1/*
2 * Copyright 2006 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkArenaAlloc.h"
9#include "SkBlitter.h"
10#include "SkAntiRun.h"
11#include "SkColor.h"
12#include "SkColorFilter.h"
13#include "SkReadBuffer.h"
14#include "SkWriteBuffer.h"
15#include "SkMask.h"
16#include "SkMaskFilter.h"
17#include "SkString.h"
18#include "SkTLazy.h"
19#include "SkUtils.h"
20#include "SkXfermodeInterpretation.h"
21
22// define this for testing srgb blits
23//#define SK_FORCE_PM4f_FOR_L32_BLITS
24
25SkBlitter::~SkBlitter() {}
26
27bool SkBlitter::isNullBlitter() const { return false; }
28
29const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
30    return nullptr;
31}
32
33/*
34void SkBlitter::blitH(int x, int y, int width) {
35    SkDEBUGFAIL("unimplemented");
36}
37
38
39void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
40                          const int16_t runs[]) {
41    SkDEBUGFAIL("unimplemented");
42}
43 */
44
45void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
46    if (alpha == 255) {
47        this->blitRect(x, y, 1, height);
48    } else {
49        int16_t runs[2];
50        runs[0] = 1;
51        runs[1] = 0;
52
53        while (--height >= 0) {
54            this->blitAntiH(x, y++, &alpha, runs);
55        }
56    }
57}
58
59void SkBlitter::blitRect(int x, int y, int width, int height) {
60    SkASSERT(width > 0);
61    while (--height >= 0) {
62        this->blitH(x, y++, width);
63    }
64}
65
66/// Default implementation doesn't check for easy optimizations
67/// such as alpha == 255; also uses blitV(), which some subclasses
68/// may not support.
69void SkBlitter::blitAntiRect(int x, int y, int width, int height,
70                             SkAlpha leftAlpha, SkAlpha rightAlpha) {
71    if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0
72        this->blitV(x, y, height, leftAlpha);
73    }
74    x++;
75    if (width > 0) {
76        this->blitRect(x, y, width, height);
77        x += width;
78    }
79    if (rightAlpha > 0) {
80        this->blitV(x, y, height, rightAlpha);
81    }
82}
83
84//////////////////////////////////////////////////////////////////////////////
85
86static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
87                                const uint8_t bits[],
88                                uint8_t left_mask, ptrdiff_t rowBytes,
89                                uint8_t right_mask) {
90    int inFill = 0;
91    int pos = 0;
92
93    while (--rowBytes >= 0) {
94        uint8_t b = *bits++ & left_mask;
95        if (rowBytes == 0) {
96            b &= right_mask;
97        }
98
99        for (uint8_t test = 0x80U; test != 0; test >>= 1) {
100            if (b & test) {
101                if (!inFill) {
102                    pos = x;
103                    inFill = true;
104                }
105            } else {
106                if (inFill) {
107                    blitter->blitH(pos, y, x - pos);
108                    inFill = false;
109                }
110            }
111            x += 1;
112        }
113        left_mask = 0xFFU;
114    }
115
116    // final cleanup
117    if (inFill) {
118        blitter->blitH(pos, y, x - pos);
119    }
120}
121
122// maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8.
123static uint8_t generate_right_mask(int maskBitCount) {
124    return static_cast<uint8_t>(0xFF00U >> maskBitCount);
125}
126
127void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
128    SkASSERT(mask.fBounds.contains(clip));
129
130    if (mask.fFormat == SkMask::kLCD16_Format) {
131        return; // needs to be handled by subclass
132    }
133
134    if (mask.fFormat == SkMask::kBW_Format) {
135        int cx = clip.fLeft;
136        int cy = clip.fTop;
137        int maskLeft = mask.fBounds.fLeft;
138        int maskRowBytes = mask.fRowBytes;
139        int height = clip.height();
140
141        const uint8_t* bits = mask.getAddr1(cx, cy);
142
143        SkDEBUGCODE(const uint8_t* endOfImage =
144            mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes
145            + ((mask.fBounds.width() + 7) >> 3));
146
147        if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
148            while (--height >= 0) {
149                int affectedRightBit = mask.fBounds.width() - 1;
150                ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1;
151                SkASSERT(bits + rowBytes <= endOfImage);
152                U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
153                bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask);
154                bits += maskRowBytes;
155                cy += 1;
156            }
157        } else {
158            // Bits is calculated as the offset into the mask at the point {cx, cy} therefore, all
159            // addressing into the bit mask is relative to that point. Since this is an address
160            // calculated from a arbitrary bit in that byte, calculate the left most bit.
161            int bitsLeft = cx - ((cx - maskLeft) & 7);
162
163            // Everything is relative to the bitsLeft.
164            int leftEdge = cx - bitsLeft;
165            SkASSERT(leftEdge >= 0);
166            int rightEdge = clip.fRight - bitsLeft;
167            SkASSERT(rightEdge > leftEdge);
168
169            // Calculate left byte and mask
170            const uint8_t* leftByte = bits;
171            U8CPU leftMask = 0xFFU >> (leftEdge & 7);
172
173            // Calculate right byte and mask
174            int affectedRightBit = rightEdge - 1;
175            const uint8_t* rightByte = bits + (affectedRightBit >> 3);
176            U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
177
178            // leftByte and rightByte are byte locations therefore, to get a count of bytes the
179            // code must add one.
180            ptrdiff_t rowBytes = rightByte - leftByte + 1;
181
182            while (--height >= 0) {
183                SkASSERT(bits + rowBytes <= endOfImage);
184                bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask);
185                bits += maskRowBytes;
186                cy += 1;
187            }
188        }
189    } else {
190        int                         width = clip.width();
191        SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
192        int16_t*                    runs = runStorage.get();
193        const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
194
195        sk_memset16((uint16_t*)runs, 1, width);
196        runs[width] = 0;
197
198        int height = clip.height();
199        int y = clip.fTop;
200        while (--height >= 0) {
201            this->blitAntiH(clip.fLeft, y, aa, runs);
202            aa += mask.fRowBytes;
203            y += 1;
204        }
205    }
206}
207
208/////////////////////// these guys are not virtual, just a helpers
209
210void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
211    if (clip.quickReject(mask.fBounds)) {
212        return;
213    }
214
215    SkRegion::Cliperator clipper(clip, mask.fBounds);
216
217    while (!clipper.done()) {
218        const SkIRect& cr = clipper.rect();
219        this->blitMask(mask, cr);
220        clipper.next();
221    }
222}
223
224void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
225    SkRegion::Cliperator clipper(clip, rect);
226
227    while (!clipper.done()) {
228        const SkIRect& cr = clipper.rect();
229        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
230        clipper.next();
231    }
232}
233
234void SkBlitter::blitRegion(const SkRegion& clip) {
235    SkRegion::Iterator iter(clip);
236
237    while (!iter.done()) {
238        const SkIRect& cr = iter.rect();
239        this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
240        iter.next();
241    }
242}
243
244///////////////////////////////////////////////////////////////////////////////
245
246void SkNullBlitter::blitH(int x, int y, int width) {}
247
248void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
249                              const int16_t runs[]) {}
250
251void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
252
253void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
254
255void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
256
257const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
258    return nullptr;
259}
260
261bool SkNullBlitter::isNullBlitter() const { return true; }
262
263///////////////////////////////////////////////////////////////////////////////
264
265static int compute_anti_width(const int16_t runs[]) {
266    int width = 0;
267
268    for (;;) {
269        int count = runs[0];
270
271        SkASSERT(count >= 0);
272        if (count == 0) {
273            break;
274        }
275        width += count;
276        runs += count;
277    }
278    return width;
279}
280
281static inline bool y_in_rect(int y, const SkIRect& rect) {
282    return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
283}
284
285static inline bool x_in_rect(int x, const SkIRect& rect) {
286    return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
287}
288
289void SkRectClipBlitter::blitH(int left, int y, int width) {
290    SkASSERT(width > 0);
291
292    if (!y_in_rect(y, fClipRect)) {
293        return;
294    }
295
296    int right = left + width;
297
298    if (left < fClipRect.fLeft) {
299        left = fClipRect.fLeft;
300    }
301    if (right > fClipRect.fRight) {
302        right = fClipRect.fRight;
303    }
304
305    width = right - left;
306    if (width > 0) {
307        fBlitter->blitH(left, y, width);
308    }
309}
310
311void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
312                                  const int16_t runs[]) {
313    if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
314        return;
315    }
316
317    int x0 = left;
318    int x1 = left + compute_anti_width(runs);
319
320    if (x1 <= fClipRect.fLeft) {
321        return;
322    }
323
324    SkASSERT(x0 < x1);
325    if (x0 < fClipRect.fLeft) {
326        int dx = fClipRect.fLeft - x0;
327        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
328        runs += dx;
329        aa += dx;
330        x0 = fClipRect.fLeft;
331    }
332
333    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
334    if (x1 > fClipRect.fRight) {
335        x1 = fClipRect.fRight;
336        SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
337        ((int16_t*)runs)[x1 - x0] = 0;
338    }
339
340    SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
341    SkASSERT(compute_anti_width(runs) == x1 - x0);
342
343    fBlitter->blitAntiH(x0, y, aa, runs);
344}
345
346void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
347    SkASSERT(height > 0);
348
349    if (!x_in_rect(x, fClipRect)) {
350        return;
351    }
352
353    int y0 = y;
354    int y1 = y + height;
355
356    if (y0 < fClipRect.fTop) {
357        y0 = fClipRect.fTop;
358    }
359    if (y1 > fClipRect.fBottom) {
360        y1 = fClipRect.fBottom;
361    }
362
363    if (y0 < y1) {
364        fBlitter->blitV(x, y0, y1 - y0, alpha);
365    }
366}
367
368void SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
369    SkIRect    r;
370
371    r.set(left, y, left + width, y + height);
372    if (r.intersect(fClipRect)) {
373        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
374    }
375}
376
377void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
378                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
379    SkIRect    r;
380
381    // The *true* width of the rectangle blitted is width+2:
382    r.set(left, y, left + width + 2, y + height);
383    if (r.intersect(fClipRect)) {
384        if (r.fLeft != left) {
385            SkASSERT(r.fLeft > left);
386            leftAlpha = 255;
387        }
388        if (r.fRight != left + width + 2) {
389            SkASSERT(r.fRight < left + width + 2);
390            rightAlpha = 255;
391        }
392        if (255 == leftAlpha && 255 == rightAlpha) {
393            fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
394        } else if (1 == r.width()) {
395            if (r.fLeft == left) {
396                fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
397            } else {
398                SkASSERT(r.fLeft == left + width + 1);
399                fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
400            }
401        } else {
402            fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
403                                   leftAlpha, rightAlpha);
404        }
405    }
406}
407
408void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
409    SkASSERT(mask.fBounds.contains(clip));
410
411    SkIRect    r = clip;
412
413    if (r.intersect(fClipRect)) {
414        fBlitter->blitMask(mask, r);
415    }
416}
417
418const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
419    return fBlitter->justAnOpaqueColor(value);
420}
421
422///////////////////////////////////////////////////////////////////////////////
423
424void SkRgnClipBlitter::blitH(int x, int y, int width) {
425    SkRegion::Spanerator span(*fRgn, y, x, x + width);
426    int left, right;
427
428    while (span.next(&left, &right)) {
429        SkASSERT(left < right);
430        fBlitter->blitH(left, y, right - left);
431    }
432}
433
434void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
435                                 const int16_t runs[]) {
436    int width = compute_anti_width(runs);
437    SkRegion::Spanerator span(*fRgn, y, x, x + width);
438    int left, right;
439    SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
440
441    int prevRite = x;
442    while (span.next(&left, &right)) {
443        SkASSERT(x <= left);
444        SkASSERT(left < right);
445        SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
446
447        SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
448
449        // now zero before left
450        if (left > prevRite) {
451            int index = prevRite - x;
452            ((uint8_t*)aa)[index] = 0;   // skip runs after right
453            ((int16_t*)runs)[index] = SkToS16(left - prevRite);
454        }
455
456        prevRite = right;
457    }
458
459    if (prevRite > x) {
460        ((int16_t*)runs)[prevRite - x] = 0;
461
462        if (x < 0) {
463            int skip = runs[0];
464            SkASSERT(skip >= -x);
465            aa += skip;
466            runs += skip;
467            x += skip;
468        }
469        fBlitter->blitAntiH(x, y, aa, runs);
470    }
471}
472
473void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
474    SkIRect    bounds;
475    bounds.set(x, y, x + 1, y + height);
476
477    SkRegion::Cliperator    iter(*fRgn, bounds);
478
479    while (!iter.done()) {
480        const SkIRect& r = iter.rect();
481        SkASSERT(bounds.contains(r));
482
483        fBlitter->blitV(x, r.fTop, r.height(), alpha);
484        iter.next();
485    }
486}
487
488void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
489    SkIRect    bounds;
490    bounds.set(x, y, x + width, y + height);
491
492    SkRegion::Cliperator    iter(*fRgn, bounds);
493
494    while (!iter.done()) {
495        const SkIRect& r = iter.rect();
496        SkASSERT(bounds.contains(r));
497
498        fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
499        iter.next();
500    }
501}
502
503void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
504                                    SkAlpha leftAlpha, SkAlpha rightAlpha) {
505    // The *true* width of the rectangle to blit is width + 2
506    SkIRect    bounds;
507    bounds.set(x, y, x + width + 2, y + height);
508
509    SkRegion::Cliperator    iter(*fRgn, bounds);
510
511    while (!iter.done()) {
512        const SkIRect& r = iter.rect();
513        SkASSERT(bounds.contains(r));
514        SkASSERT(r.fLeft >= x);
515        SkASSERT(r.fRight <= x + width + 2);
516
517        SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
518        SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
519                                      rightAlpha : 255;
520
521        if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
522            fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
523        } else if (1 == r.width()) {
524            if (r.fLeft == x) {
525                fBlitter->blitV(r.fLeft, r.fTop, r.height(),
526                                effectiveLeftAlpha);
527            } else {
528                SkASSERT(r.fLeft == x + width + 1);
529                fBlitter->blitV(r.fLeft, r.fTop, r.height(),
530                                effectiveRightAlpha);
531            }
532        } else {
533            fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
534                                   effectiveLeftAlpha, effectiveRightAlpha);
535        }
536        iter.next();
537    }
538}
539
540
541void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
542    SkASSERT(mask.fBounds.contains(clip));
543
544    SkRegion::Cliperator iter(*fRgn, clip);
545    const SkIRect&       r = iter.rect();
546    SkBlitter*           blitter = fBlitter;
547
548    while (!iter.done()) {
549        blitter->blitMask(mask, r);
550        iter.next();
551    }
552}
553
554const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
555    return fBlitter->justAnOpaqueColor(value);
556}
557
558///////////////////////////////////////////////////////////////////////////////
559
560SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
561                                   const SkIRect* ir) {
562    if (clip) {
563        const SkIRect& clipR = clip->getBounds();
564
565        if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
566            blitter = &fNullBlitter;
567        } else if (clip->isRect()) {
568            if (ir == nullptr || !clipR.contains(*ir)) {
569                fRectBlitter.init(blitter, clipR);
570                blitter = &fRectBlitter;
571            }
572        } else {
573            fRgnBlitter.init(blitter, clip);
574            blitter = &fRgnBlitter;
575        }
576    }
577    return blitter;
578}
579
580///////////////////////////////////////////////////////////////////////////////
581
582#include "SkColorShader.h"
583#include "SkColorPriv.h"
584
585class Sk3DShader : public SkShader {
586public:
587    Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {}
588
589    Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override {
590        SkShader::Context* proxyContext = nullptr;
591        if (fProxy) {
592            proxyContext = fProxy->makeContext(rec, alloc);
593            if (!proxyContext) {
594                return nullptr;
595            }
596        }
597        return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext);
598    }
599
600    class Sk3DShaderContext : public SkShader::Context {
601    public:
602        // Calls proxyContext's destructor but will NOT free its memory.
603        Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
604                          SkShader::Context* proxyContext)
605            : INHERITED(shader, rec)
606            , fMask(nullptr)
607            , fProxyContext(proxyContext)
608        {
609            if (!fProxyContext) {
610                fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
611            }
612        }
613
614        ~Sk3DShaderContext() override {
615            if (fProxyContext) {
616                fProxyContext->~Context();
617            }
618        }
619
620        void set3DMask(const SkMask* mask) override { fMask = mask; }
621
622        void shadeSpan(int x, int y, SkPMColor span[], int count) override {
623            if (fProxyContext) {
624                fProxyContext->shadeSpan(x, y, span, count);
625            }
626
627            if (fMask == nullptr) {
628                if (fProxyContext == nullptr) {
629                    sk_memset32(span, fPMColor, count);
630                }
631                return;
632            }
633
634            SkASSERT(fMask->fBounds.contains(x, y));
635            SkASSERT(fMask->fBounds.contains(x + count - 1, y));
636
637            size_t          size = fMask->computeImageSize();
638            const uint8_t*  alpha = fMask->getAddr8(x, y);
639            const uint8_t*  mulp = alpha + size;
640            const uint8_t*  addp = mulp + size;
641
642            if (fProxyContext) {
643                for (int i = 0; i < count; i++) {
644                    if (alpha[i]) {
645                        SkPMColor c = span[i];
646                        if (c) {
647                            unsigned a = SkGetPackedA32(c);
648                            unsigned r = SkGetPackedR32(c);
649                            unsigned g = SkGetPackedG32(c);
650                            unsigned b = SkGetPackedB32(c);
651
652                            unsigned mul = SkAlpha255To256(mulp[i]);
653                            unsigned add = addp[i];
654
655                            r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
656                            g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
657                            b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
658
659                            span[i] = SkPackARGB32(a, r, g, b);
660                        }
661                    } else {
662                        span[i] = 0;
663                    }
664                }
665            } else {    // color
666                unsigned a = SkGetPackedA32(fPMColor);
667                unsigned r = SkGetPackedR32(fPMColor);
668                unsigned g = SkGetPackedG32(fPMColor);
669                unsigned b = SkGetPackedB32(fPMColor);
670                for (int i = 0; i < count; i++) {
671                    if (alpha[i]) {
672                        unsigned mul = SkAlpha255To256(mulp[i]);
673                        unsigned add = addp[i];
674
675                        span[i] = SkPackARGB32( a,
676                                        SkFastMin32(SkAlphaMul(r, mul) + add, a),
677                                        SkFastMin32(SkAlphaMul(g, mul) + add, a),
678                                        SkFastMin32(SkAlphaMul(b, mul) + add, a));
679                    } else {
680                        span[i] = 0;
681                    }
682                }
683            }
684        }
685
686    private:
687        // Unowned.
688        const SkMask*       fMask;
689        // Memory is unowned, but we need to call the destructor.
690        SkShader::Context*  fProxyContext;
691        SkPMColor           fPMColor;
692
693        typedef SkShader::Context INHERITED;
694    };
695
696#ifndef SK_IGNORE_TO_STRING
697    void toString(SkString* str) const override {
698        str->append("Sk3DShader: (");
699
700        if (fProxy) {
701            str->append("Proxy: ");
702            fProxy->toString(str);
703        }
704
705        this->INHERITED::toString(str);
706
707        str->append(")");
708    }
709#endif
710
711    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
712
713protected:
714    void flatten(SkWriteBuffer& buffer) const override {
715        buffer.writeFlattenable(fProxy.get());
716    }
717
718private:
719    sk_sp<SkShader> fProxy;
720
721    typedef SkShader INHERITED;
722};
723
724sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) {
725    return sk_make_sp<Sk3DShader>(buffer.readShader());
726}
727
728class Sk3DBlitter : public SkBlitter {
729public:
730    Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
731        : fProxy(proxy)
732        , fShaderContext(shaderContext)
733    {}
734
735    void blitH(int x, int y, int width) override {
736        fProxy->blitH(x, y, width);
737    }
738
739    void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override {
740        fProxy->blitAntiH(x, y, antialias, runs);
741    }
742
743    void blitV(int x, int y, int height, SkAlpha alpha) override {
744        fProxy->blitV(x, y, height, alpha);
745    }
746
747    void blitRect(int x, int y, int width, int height) override {
748        fProxy->blitRect(x, y, width, height);
749    }
750
751    void blitMask(const SkMask& mask, const SkIRect& clip) override {
752        if (mask.fFormat == SkMask::k3D_Format) {
753            fShaderContext->set3DMask(&mask);
754
755            ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
756            fProxy->blitMask(mask, clip);
757            ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
758
759            fShaderContext->set3DMask(nullptr);
760        } else {
761            fProxy->blitMask(mask, clip);
762        }
763    }
764
765private:
766    // Both pointers are unowned. They will be deleted by SkSmallAllocator.
767    SkBlitter*          fProxy;
768    SkShader::Context*  fShaderContext;
769};
770
771///////////////////////////////////////////////////////////////////////////////
772
773#include "SkCoreBlitters.h"
774
775SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) {
776#ifdef SK_FORCE_PM4f_FOR_L32_BLITS
777    return SkShader::ContextRec::kPM4f_DstType;
778#else
779    return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType)
780            ? SkShader::ContextRec::kPM4f_DstType
781            : SkShader::ContextRec::kPMColor_DstType;
782#endif
783}
784
785SkBlitter* SkBlitter::Choose(const SkPixmap& device,
786                             const SkMatrix& matrix,
787                             const SkPaint& origPaint,
788                             SkArenaAlloc* alloc,
789                             bool drawCoverage) {
790    SkASSERT(alloc != nullptr);
791
792    // which check, in case we're being called by a client with a dummy device
793    // (e.g. they have a bounder that always aborts the draw)
794    if (kUnknown_SkColorType == device.colorType() ||
795            (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
796        return alloc->make<SkNullBlitter>();
797    }
798
799    SkShader* shader = origPaint.getShader();
800    SkColorFilter* cf = origPaint.getColorFilter();
801    SkBlendMode mode = origPaint.getBlendMode();
802    sk_sp<Sk3DShader> shader3D;
803
804    SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
805
806    if (origPaint.getMaskFilter() != nullptr &&
807            origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
808        shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader));
809        // we know we haven't initialized lazyPaint yet, so just do it
810        paint.writable()->setShader(shader3D);
811        shader = shader3D.get();
812    }
813
814    if (mode != SkBlendMode::kSrcOver) {
815        bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType();
816        switch (SkInterpretXfermode(*paint, deviceIsOpaque)) {
817            case kSrcOver_SkXfermodeInterpretation:
818                mode = SkBlendMode::kSrcOver;
819                paint.writable()->setBlendMode(mode);
820                break;
821            case kSkipDrawing_SkXfermodeInterpretation:{
822                return alloc->make<SkNullBlitter>();
823            }
824            default:
825                break;
826        }
827    }
828
829    /*
830     *  If the xfermode is CLEAR, then we can completely ignore the installed
831     *  color/shader/colorfilter, and just pretend we're SRC + color==0. This
832     *  will fall into our optimizations for SRC mode.
833     */
834    if (mode == SkBlendMode::kClear) {
835        SkPaint* p = paint.writable();
836        p->setShader(nullptr);
837        shader = nullptr;
838        p->setColorFilter(nullptr);
839        cf = nullptr;
840        p->setBlendMode(mode = SkBlendMode::kSrc);
841        p->setColor(0);
842    }
843
844    if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) {
845        SkASSERT(nullptr == shader);
846        SkASSERT(paint->isSrcOver());
847        return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
848    }
849
850    if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) {
851        return blitter;
852    }
853
854    if (nullptr == shader) {
855        if (mode != SkBlendMode::kSrcOver) {
856            // xfermodes (and filters) require shaders for our current blitters
857            paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor()));
858            paint.writable()->setAlpha(0xFF);
859            shader = paint->getShader();
860        } else if (cf) {
861            // if no shader && no xfermode, we just apply the colorfilter to
862            // our color and move on.
863            SkPaint* writablePaint = paint.writable();
864            writablePaint->setColor(cf->filterColor(paint->getColor()));
865            writablePaint->setColorFilter(nullptr);
866            cf = nullptr;
867        }
868    }
869
870    if (cf) {
871        SkASSERT(shader);
872        paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf)));
873        shader = paint->getShader();
874        // blitters should ignore the presence/absence of a filter, since
875        // if there is one, the shader will take care of it.
876    }
877
878    /*
879     *  We create a SkShader::Context object, and store it on the blitter.
880     */
881    SkShader::Context* shaderContext = nullptr;
882    if (shader) {
883        const SkShader::ContextRec rec(*paint, matrix, nullptr,
884                                       PreferredShaderDest(device.info()),
885                                       device.colorSpace());
886        // Try to create the ShaderContext
887        shaderContext = shader->makeContext(rec, alloc);
888        if (!shaderContext) {
889            return alloc->make<SkNullBlitter>();
890        }
891        SkASSERT(shaderContext);
892    }
893
894    SkBlitter*  blitter = nullptr;
895    switch (device.colorType()) {
896        case kAlpha_8_SkColorType:
897            SkASSERT(!drawCoverage);  // Handled above.
898            if (shader) {
899                blitter = alloc->make<SkA8_Shader_Blitter>(device, *paint, shaderContext);
900            } else {
901                blitter = alloc->make<SkA8_Blitter>(device, *paint);
902            }
903            break;
904
905        case kRGB_565_SkColorType:
906            blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloc);
907            break;
908
909        case kN32_SkColorType:
910#ifdef SK_FORCE_PM4f_FOR_L32_BLITS
911            if (true)
912#else
913            if (device.info().gammaCloseToSRGB())
914#endif
915            {
916                blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, alloc);
917            } else {
918                if (shader) {
919                        blitter = alloc->make<SkARGB32_Shader_Blitter>(
920                                device, *paint, shaderContext);
921                } else if (paint->getColor() == SK_ColorBLACK) {
922                    blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint);
923                } else if (paint->getAlpha() == 0xFF) {
924                    blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint);
925                } else {
926                    blitter = alloc->make<SkARGB32_Blitter>(device, *paint);
927                }
928            }
929            break;
930
931        case kRGBA_F16_SkColorType:
932            blitter = SkBlitter_F16_Create(device, *paint, shaderContext, alloc);
933            break;
934
935        default:
936            break;
937    }
938
939    if (!blitter) {
940        blitter = alloc->make<SkNullBlitter>();
941    }
942
943    if (shader3D) {
944        SkBlitter* innerBlitter = blitter;
945        // FIXME - comment about allocator
946        // innerBlitter was allocated by allocator, which will delete it.
947        // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
948        // wrapper the blitter to notify it when we see an emboss mask.
949        blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext);
950    }
951    return blitter;
952}
953
954///////////////////////////////////////////////////////////////////////////////
955
956class SkZeroShaderContext : public SkShader::Context {
957public:
958    SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec)
959        // Override rec with the identity matrix, so it is guaranteed to be invertible.
960        : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr,
961                                                 rec.fPreferredDstType, rec.fDstColorSpace)) {}
962
963    void shadeSpan(int x, int y, SkPMColor colors[], int count) override {
964        sk_bzero(colors, count * sizeof(SkPMColor));
965    }
966
967private:
968    typedef SkShader::Context INHERITED;
969};
970
971SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint,
972                                 SkShader::Context* shaderContext)
973        : INHERITED(device)
974        , fShader(paint.getShader())
975        , fShaderContext(shaderContext) {
976    SkASSERT(fShader);
977    SkASSERT(fShaderContext);
978
979    fShader->ref();
980    fShaderFlags = fShaderContext->getFlags();
981    fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag);
982}
983
984SkShaderBlitter::~SkShaderBlitter() {
985    fShader->unref();
986}
987
988///////////////////////////////////////////////////////////////////////////////////////////////////
989
990#ifdef SK_DEBUG
991
992void SkRectClipCheckBlitter::blitH(int x, int y, int width) {
993    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1)));
994    fBlitter->blitH(x, y, width);
995}
996
997void SkRectClipCheckBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {
998    const int16_t* iter = runs;
999    for (; *iter; iter += *iter)
1000        ;
1001    int width = iter - runs;
1002    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1)));
1003    fBlitter->blitAntiH(x, y, aa, runs);
1004}
1005
1006void SkRectClipCheckBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
1007    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, height)));
1008    fBlitter->blitV(x, y, height, alpha);
1009}
1010
1011void SkRectClipCheckBlitter::blitRect(int x, int y, int width, int height) {
1012    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, height)));
1013    fBlitter->blitRect(x, y, width, height);
1014}
1015
1016void SkRectClipCheckBlitter::blitAntiRect(int x, int y, int width, int height,
1017                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
1018    bool skipLeft = !leftAlpha;
1019    bool skipRight = !rightAlpha;
1020    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x + skipLeft, y,
1021            width + 2 - skipRight - skipLeft, height)));
1022    fBlitter->blitAntiRect(x, y, width, height, leftAlpha, rightAlpha);
1023}
1024
1025void SkRectClipCheckBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1026    SkASSERT(mask.fBounds.contains(clip));
1027    SkASSERT(fClipRect.contains(clip));
1028    fBlitter->blitMask(mask, clip);
1029}
1030
1031const SkPixmap* SkRectClipCheckBlitter::justAnOpaqueColor(uint32_t* value) {
1032    return fBlitter->justAnOpaqueColor(value);
1033}
1034
1035void SkRectClipCheckBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
1036    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 2, 1)));
1037    fBlitter->blitAntiH2(x, y, a0, a1);
1038}
1039
1040void SkRectClipCheckBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
1041    SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, 2)));
1042    fBlitter->blitAntiV2(x, y, a0, a1);
1043}
1044
1045#endif
1046