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