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