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 "SkBlitter.h"
9#include "SkAntiRun.h"
10#include "SkColor.h"
11#include "SkColorFilter.h"
12#include "SkReadBuffer.h"
13#include "SkWriteBuffer.h"
14#include "SkMask.h"
15#include "SkMaskFilter.h"
16#include "SkString.h"
17#include "SkTLazy.h"
18#include "SkUtils.h"
19#include "SkXfermode.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
29bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) {
30    return true;
31}
32
33SkShader::Context* SkBlitter::getShaderContext() const {
34    return nullptr;
35}
36
37const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
38    return nullptr;
39}
40
41void SkBlitter::blitH(int x, int y, int width) {
42    SkDEBUGFAIL("unimplemented");
43}
44
45void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
46                          const int16_t runs[]) {
47    SkDEBUGFAIL("unimplemented");
48}
49
50void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
51    if (alpha == 255) {
52        this->blitRect(x, y, 1, height);
53    } else {
54        int16_t runs[2];
55        runs[0] = 1;
56        runs[1] = 0;
57
58        while (--height >= 0) {
59            this->blitAntiH(x, y++, &alpha, runs);
60        }
61    }
62}
63
64void SkBlitter::blitRect(int x, int y, int width, int height) {
65    SkASSERT(width > 0);
66    while (--height >= 0) {
67        this->blitH(x, y++, width);
68    }
69}
70
71/// Default implementation doesn't check for any easy optimizations
72/// such as alpha == 0 or 255; also uses blitV(), which some subclasses
73/// may not support.
74void SkBlitter::blitAntiRect(int x, int y, int width, int height,
75                             SkAlpha leftAlpha, SkAlpha rightAlpha) {
76    this->blitV(x++, y, height, leftAlpha);
77    if (width > 0) {
78        this->blitRect(x, y, width, height);
79        x += width;
80    }
81    this->blitV(x, y, height, rightAlpha);
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} therfore, 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(SkShader* proxy) : fProxy(proxy) {
588        SkSafeRef(proxy);
589    }
590
591    virtual ~Sk3DShader() {
592        SkSafeUnref(fProxy);
593    }
594
595    size_t contextSize(const ContextRec& rec) const override {
596        size_t size = sizeof(Sk3DShaderContext);
597        if (fProxy) {
598            size += fProxy->contextSize(rec);
599        }
600        return size;
601    }
602
603    Context* onCreateContext(const ContextRec& rec, void* storage) const override {
604        SkShader::Context* proxyContext = nullptr;
605        if (fProxy) {
606            char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
607            proxyContext = fProxy->createContext(rec, proxyContextStorage);
608            if (!proxyContext) {
609                return nullptr;
610            }
611        }
612        return new (storage) Sk3DShaderContext(*this, rec, proxyContext);
613    }
614
615    class Sk3DShaderContext : public SkShader::Context {
616    public:
617        // Calls proxyContext's destructor but will NOT free its memory.
618        Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
619                          SkShader::Context* proxyContext)
620            : INHERITED(shader, rec)
621            , fMask(nullptr)
622            , fProxyContext(proxyContext)
623        {
624            if (!fProxyContext) {
625                fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
626            }
627        }
628
629        virtual ~Sk3DShaderContext() {
630            if (fProxyContext) {
631                fProxyContext->~Context();
632            }
633        }
634
635        void set3DMask(const SkMask* mask) override { fMask = mask; }
636
637        void shadeSpan(int x, int y, SkPMColor span[], int count) override {
638            if (fProxyContext) {
639                fProxyContext->shadeSpan(x, y, span, count);
640            }
641
642            if (fMask == nullptr) {
643                if (fProxyContext == nullptr) {
644                    sk_memset32(span, fPMColor, count);
645                }
646                return;
647            }
648
649            SkASSERT(fMask->fBounds.contains(x, y));
650            SkASSERT(fMask->fBounds.contains(x + count - 1, y));
651
652            size_t          size = fMask->computeImageSize();
653            const uint8_t*  alpha = fMask->getAddr8(x, y);
654            const uint8_t*  mulp = alpha + size;
655            const uint8_t*  addp = mulp + size;
656
657            if (fProxyContext) {
658                for (int i = 0; i < count; i++) {
659                    if (alpha[i]) {
660                        SkPMColor c = span[i];
661                        if (c) {
662                            unsigned a = SkGetPackedA32(c);
663                            unsigned r = SkGetPackedR32(c);
664                            unsigned g = SkGetPackedG32(c);
665                            unsigned b = SkGetPackedB32(c);
666
667                            unsigned mul = SkAlpha255To256(mulp[i]);
668                            unsigned add = addp[i];
669
670                            r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
671                            g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
672                            b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
673
674                            span[i] = SkPackARGB32(a, r, g, b);
675                        }
676                    } else {
677                        span[i] = 0;
678                    }
679                }
680            } else {    // color
681                unsigned a = SkGetPackedA32(fPMColor);
682                unsigned r = SkGetPackedR32(fPMColor);
683                unsigned g = SkGetPackedG32(fPMColor);
684                unsigned b = SkGetPackedB32(fPMColor);
685                for (int i = 0; i < count; i++) {
686                    if (alpha[i]) {
687                        unsigned mul = SkAlpha255To256(mulp[i]);
688                        unsigned add = addp[i];
689
690                        span[i] = SkPackARGB32( a,
691                                        SkFastMin32(SkAlphaMul(r, mul) + add, a),
692                                        SkFastMin32(SkAlphaMul(g, mul) + add, a),
693                                        SkFastMin32(SkAlphaMul(b, mul) + add, a));
694                    } else {
695                        span[i] = 0;
696                    }
697                }
698            }
699        }
700
701    private:
702        // Unowned.
703        const SkMask*       fMask;
704        // Memory is unowned, but we need to call the destructor.
705        SkShader::Context*  fProxyContext;
706        SkPMColor           fPMColor;
707
708        typedef SkShader::Context INHERITED;
709    };
710
711#ifndef SK_IGNORE_TO_STRING
712    void toString(SkString* str) const override {
713        str->append("Sk3DShader: (");
714
715        if (fProxy) {
716            str->append("Proxy: ");
717            fProxy->toString(str);
718        }
719
720        this->INHERITED::toString(str);
721
722        str->append(")");
723    }
724#endif
725
726    SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
727
728protected:
729    void flatten(SkWriteBuffer& buffer) const override {
730        buffer.writeFlattenable(fProxy);
731    }
732
733private:
734    SkShader*       fProxy;
735
736    typedef SkShader INHERITED;
737};
738
739SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) {
740    SkAutoTUnref<SkShader> shader(buffer.readShader());
741    return new Sk3DShader(shader);
742}
743
744class Sk3DBlitter : public SkBlitter {
745public:
746    Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
747        : fProxy(proxy)
748        , fShaderContext(shaderContext)
749    {}
750
751    void blitH(int x, int y, int width) override {
752        fProxy->blitH(x, y, width);
753    }
754
755    virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
756                           const int16_t runs[]) override {
757        fProxy->blitAntiH(x, y, antialias, runs);
758    }
759
760    void blitV(int x, int y, int height, SkAlpha alpha) override {
761        fProxy->blitV(x, y, height, alpha);
762    }
763
764    void blitRect(int x, int y, int width, int height) override {
765        fProxy->blitRect(x, y, width, height);
766    }
767
768    void blitMask(const SkMask& mask, const SkIRect& clip) override {
769        if (mask.fFormat == SkMask::k3D_Format) {
770            fShaderContext->set3DMask(&mask);
771
772            ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
773            fProxy->blitMask(mask, clip);
774            ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
775
776            fShaderContext->set3DMask(nullptr);
777        } else {
778            fProxy->blitMask(mask, clip);
779        }
780    }
781
782private:
783    // Both pointers are unowned. They will be deleted by SkSmallAllocator.
784    SkBlitter*          fProxy;
785    SkShader::Context*  fShaderContext;
786};
787
788///////////////////////////////////////////////////////////////////////////////
789
790#include "SkCoreBlitters.h"
791
792SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) {
793#ifdef SK_FORCE_PM4f_FOR_L32_BLITS
794    return SkShader::ContextRec::kPM4f_DstType;
795#else
796    return (dstInfo.isSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType)
797            ? SkShader::ContextRec::kPM4f_DstType
798            : SkShader::ContextRec::kPMColor_DstType;
799#endif
800}
801
802SkBlitter* SkBlitter::Choose(const SkPixmap& device,
803                             const SkMatrix& matrix,
804                             const SkPaint& origPaint,
805                             SkTBlitterAllocator* allocator,
806                             bool drawCoverage) {
807    SkASSERT(allocator != nullptr);
808
809    // which check, in case we're being called by a client with a dummy device
810    // (e.g. they have a bounder that always aborts the draw)
811    if (kUnknown_SkColorType == device.colorType() ||
812            (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
813        return allocator->createT<SkNullBlitter>();
814    }
815
816    SkShader* shader = origPaint.getShader();
817    SkColorFilter* cf = origPaint.getColorFilter();
818    SkXfermode* mode = origPaint.getXfermode();
819    Sk3DShader* shader3D = nullptr;
820
821    SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
822
823    if (origPaint.getMaskFilter() != nullptr &&
824            origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
825        shader3D = new Sk3DShader(shader);
826        // we know we haven't initialized lazyPaint yet, so just do it
827        paint.writable()->setShader(shader3D)->unref();
828        shader = shader3D;
829    }
830
831    if (mode) {
832        bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType();
833        switch (SkInterpretXfermode(*paint, deviceIsOpaque)) {
834            case kSrcOver_SkXfermodeInterpretation:
835                mode = nullptr;
836                paint.writable()->setXfermode(nullptr);
837                break;
838            case kSkipDrawing_SkXfermodeInterpretation:{
839                return allocator->createT<SkNullBlitter>();
840            }
841            default:
842                break;
843        }
844    }
845
846    /*
847     *  If the xfermode is CLEAR, then we can completely ignore the installed
848     *  color/shader/colorfilter, and just pretend we're SRC + color==0. This
849     *  will fall into our optimizations for SRC mode.
850     */
851    if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) {
852        SkPaint* p = paint.writable();
853        shader = p->setShader(nullptr);
854        cf = p->setColorFilter(nullptr);
855        mode = p->setXfermodeMode(SkXfermode::kSrc_Mode);
856        p->setColor(0);
857    }
858
859    if (nullptr == shader) {
860        if (mode) {
861            // xfermodes (and filters) require shaders for our current blitters
862            shader = new SkColorShader(paint->getColor());
863            paint.writable()->setShader(shader)->unref();
864            paint.writable()->setAlpha(0xFF);
865        } else if (cf) {
866            // if no shader && no xfermode, we just apply the colorfilter to
867            // our color and move on.
868            SkPaint* writablePaint = paint.writable();
869            writablePaint->setColor(cf->filterColor(paint->getColor()));
870            writablePaint->setColorFilter(nullptr);
871            cf = nullptr;
872        }
873    }
874
875    if (cf) {
876        SkASSERT(shader);
877        shader = shader->newWithColorFilter(cf);
878        paint.writable()->setShader(shader)->unref();
879        // blitters should ignore the presence/absence of a filter, since
880        // if there is one, the shader will take care of it.
881    }
882
883    /*
884     *  We create a SkShader::Context object, and store it on the blitter.
885     */
886    SkShader::Context* shaderContext = nullptr;
887    if (shader) {
888        const SkShader::ContextRec rec(*paint, matrix, nullptr,
889                                       PreferredShaderDest(device.info()));
890        size_t contextSize = shader->contextSize(rec);
891        if (contextSize) {
892            // Try to create the ShaderContext
893            void* storage = allocator->reserveT<SkShader::Context>(contextSize);
894            shaderContext = shader->createContext(rec, storage);
895            if (!shaderContext) {
896                allocator->freeLast();
897                return allocator->createT<SkNullBlitter>();
898            }
899            SkASSERT(shaderContext);
900            SkASSERT((void*) shaderContext == storage);
901        } else {
902            return allocator->createT<SkNullBlitter>();
903        }
904    }
905
906    SkBlitter*  blitter = nullptr;
907    switch (device.colorType()) {
908        case kAlpha_8_SkColorType:
909            if (drawCoverage) {
910                SkASSERT(nullptr == shader);
911                SkASSERT(nullptr == paint->getXfermode());
912                blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
913            } else if (shader) {
914                blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext);
915            } else {
916                blitter = allocator->createT<SkA8_Blitter>(device, *paint);
917            }
918            break;
919
920        case kRGB_565_SkColorType:
921            blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, allocator);
922            break;
923
924        case kN32_SkColorType:
925#ifdef SK_FORCE_PM4f_FOR_L32_BLITS
926            if (true)
927#else
928            if (device.info().isSRGB())
929#endif
930            {
931                blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, allocator);
932            } else {
933                if (shader) {
934                        blitter = allocator->createT<SkARGB32_Shader_Blitter>(
935                                device, *paint, shaderContext);
936                } else if (paint->getColor() == SK_ColorBLACK) {
937                    blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
938                } else if (paint->getAlpha() == 0xFF) {
939                    blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint);
940                } else {
941                    blitter = allocator->createT<SkARGB32_Blitter>(device, *paint);
942                }
943            }
944            break;
945
946        case kRGBA_F16_SkColorType:
947        // kU16_SkColorType:
948            blitter = SkBlitter_ARGB64_Create(device, *paint, shaderContext, allocator);
949            break;
950
951        default:
952            break;
953    }
954
955    if (!blitter) {
956        blitter = allocator->createT<SkNullBlitter>();
957    }
958
959    if (shader3D) {
960        SkBlitter* innerBlitter = blitter;
961        // innerBlitter was allocated by allocator, which will delete it.
962        // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
963        // wrapper the blitter to notify it when we see an emboss mask.
964        blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext);
965    }
966    return blitter;
967}
968
969///////////////////////////////////////////////////////////////////////////////
970
971class SkZeroShaderContext : public SkShader::Context {
972public:
973    SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec)
974        // Override rec with the identity matrix, so it is guaranteed to be invertible.
975        : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr,
976                                                 rec.fPreferredDstType)) {}
977
978    void shadeSpan(int x, int y, SkPMColor colors[], int count) override {
979        sk_bzero(colors, count * sizeof(SkPMColor));
980    }
981
982private:
983    typedef SkShader::Context INHERITED;
984};
985
986SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint,
987                                 SkShader::Context* shaderContext)
988        : INHERITED(device)
989        , fShader(paint.getShader())
990        , fShaderContext(shaderContext) {
991    SkASSERT(fShader);
992    SkASSERT(fShaderContext);
993
994    fShader->ref();
995    fShaderFlags = fShaderContext->getFlags();
996    fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag);
997}
998
999SkShaderBlitter::~SkShaderBlitter() {
1000    fShader->unref();
1001}
1002
1003bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) {
1004    // Only destroy the old context if we have a new one. We need to ensure to have a
1005    // live context in fShaderContext because the storage is owned by an SkSmallAllocator
1006    // outside of this class.
1007    // The new context will be of the same size as the old one because we use the same
1008    // shader to create it. It is therefore safe to re-use the storage.
1009    fShaderContext->~Context();
1010    SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext);
1011    if (nullptr == ctx) {
1012        // Need a valid context in fShaderContext's storage, so we can later (or our caller) call
1013        // the in-place destructor.
1014        new (fShaderContext) SkZeroShaderContext(*fShader, rec);
1015        return false;
1016    }
1017    return true;
1018}
1019