Home | History | Annotate | Download | only in core
      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 
     25 SkBlitter::~SkBlitter() {}
     26 
     27 bool SkBlitter::isNullBlitter() const { return false; }
     28 
     29 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) {
     30     return true;
     31 }
     32 
     33 SkShader::Context* SkBlitter::getShaderContext() const {
     34     return nullptr;
     35 }
     36 
     37 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
     38     return nullptr;
     39 }
     40 
     41 void SkBlitter::blitH(int x, int y, int width) {
     42     SkDEBUGFAIL("unimplemented");
     43 }
     44 
     45 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     46                           const int16_t runs[]) {
     47     SkDEBUGFAIL("unimplemented");
     48 }
     49 
     50 void 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 
     64 void 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.
     74 void 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 
     86 static 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.
    123 static uint8_t generate_right_mask(int maskBitCount) {
    124     return static_cast<uint8_t>(0xFF00U >> maskBitCount);
    125 }
    126 
    127 void 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 
    210 void 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 
    224 void 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 
    234 void 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 
    246 void SkNullBlitter::blitH(int x, int y, int width) {}
    247 
    248 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
    249                               const int16_t runs[]) {}
    250 
    251 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
    252 
    253 void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
    254 
    255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
    256 
    257 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
    258     return nullptr;
    259 }
    260 
    261 bool SkNullBlitter::isNullBlitter() const { return true; }
    262 
    263 ///////////////////////////////////////////////////////////////////////////////
    264 
    265 static 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 
    281 static inline bool y_in_rect(int y, const SkIRect& rect) {
    282     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
    283 }
    284 
    285 static inline bool x_in_rect(int x, const SkIRect& rect) {
    286     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
    287 }
    288 
    289 void 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 
    311 void 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 
    346 void 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 
    368 void 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 
    377 void 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 
    408 void 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 
    418 const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
    419     return fBlitter->justAnOpaqueColor(value);
    420 }
    421 
    422 ///////////////////////////////////////////////////////////////////////////////
    423 
    424 void 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 
    434 void 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 
    473 void 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 
    488 void 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 
    503 void 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 
    541 void 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 
    554 const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
    555     return fBlitter->justAnOpaqueColor(value);
    556 }
    557 
    558 ///////////////////////////////////////////////////////////////////////////////
    559 
    560 SkBlitter* 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 
    585 class Sk3DShader : public SkShader {
    586 public:
    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 
    728 protected:
    729     void flatten(SkWriteBuffer& buffer) const override {
    730         buffer.writeFlattenable(fProxy);
    731     }
    732 
    733 private:
    734     SkShader*       fProxy;
    735 
    736     typedef SkShader INHERITED;
    737 };
    738 
    739 SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) {
    740     SkAutoTUnref<SkShader> shader(buffer.readShader());
    741     return new Sk3DShader(shader);
    742 }
    743 
    744 class Sk3DBlitter : public SkBlitter {
    745 public:
    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 
    782 private:
    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 
    792 SkShader::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 
    802 SkBlitter* 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 
    971 class SkZeroShaderContext : public SkShader::Context {
    972 public:
    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 
    982 private:
    983     typedef SkShader::Context INHERITED;
    984 };
    985 
    986 SkShaderBlitter::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 
    999 SkShaderBlitter::~SkShaderBlitter() {
   1000     fShader->unref();
   1001 }
   1002 
   1003 bool 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