Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2011 Google Inc.
      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 "SkAAClip.h"
      9 #include "SkAtomics.h"
     10 #include "SkBlitter.h"
     11 #include "SkColorData.h"
     12 #include "SkRectPriv.h"
     13 #include "SkPath.h"
     14 #include "SkScan.h"
     15 #include "SkUtils.h"
     16 
     17 class AutoAAClipValidate {
     18 public:
     19     AutoAAClipValidate(const SkAAClip& clip) : fClip(clip) {
     20         fClip.validate();
     21     }
     22     ~AutoAAClipValidate() {
     23         fClip.validate();
     24     }
     25 private:
     26     const SkAAClip& fClip;
     27 };
     28 
     29 #ifdef SK_DEBUG
     30     #define AUTO_AACLIP_VALIDATE(clip)  AutoAAClipValidate acv(clip)
     31 #else
     32     #define AUTO_AACLIP_VALIDATE(clip)
     33 #endif
     34 
     35 ///////////////////////////////////////////////////////////////////////////////
     36 
     37 #define kMaxInt32   0x7FFFFFFF
     38 
     39 #ifdef SK_DEBUG
     40 static inline bool x_in_rect(int x, const SkIRect& rect) {
     41     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
     42 }
     43 #endif
     44 
     45 static inline bool y_in_rect(int y, const SkIRect& rect) {
     46     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
     47 }
     48 
     49 /*
     50  *  Data runs are packed [count, alpha]
     51  */
     52 
     53 struct SkAAClip::YOffset {
     54     int32_t  fY;
     55     uint32_t fOffset;
     56 };
     57 
     58 struct SkAAClip::RunHead {
     59     int32_t fRefCnt;
     60     int32_t fRowCount;
     61     size_t  fDataSize;
     62 
     63     YOffset* yoffsets() {
     64         return (YOffset*)((char*)this + sizeof(RunHead));
     65     }
     66     const YOffset* yoffsets() const {
     67         return (const YOffset*)((const char*)this + sizeof(RunHead));
     68     }
     69     uint8_t* data() {
     70         return (uint8_t*)(this->yoffsets() + fRowCount);
     71     }
     72     const uint8_t* data() const {
     73         return (const uint8_t*)(this->yoffsets() + fRowCount);
     74     }
     75 
     76     static RunHead* Alloc(int rowCount, size_t dataSize) {
     77         size_t size = sizeof(RunHead) + rowCount * sizeof(YOffset) + dataSize;
     78         RunHead* head = (RunHead*)sk_malloc_throw(size);
     79         head->fRefCnt = 1;
     80         head->fRowCount = rowCount;
     81         head->fDataSize = dataSize;
     82         return head;
     83     }
     84 
     85     static int ComputeRowSizeForWidth(int width) {
     86         // 2 bytes per segment, where each segment can store up to 255 for count
     87         int segments = 0;
     88         while (width > 0) {
     89             segments += 1;
     90             int n = SkMin32(width, 255);
     91             width -= n;
     92         }
     93         return segments * 2;    // each segment is row[0] + row[1] (n + alpha)
     94     }
     95 
     96     static RunHead* AllocRect(const SkIRect& bounds) {
     97         SkASSERT(!bounds.isEmpty());
     98         int width = bounds.width();
     99         size_t rowSize = ComputeRowSizeForWidth(width);
    100         RunHead* head = RunHead::Alloc(1, rowSize);
    101         YOffset* yoff = head->yoffsets();
    102         yoff->fY = bounds.height() - 1;
    103         yoff->fOffset = 0;
    104         uint8_t* row = head->data();
    105         while (width > 0) {
    106             int n = SkMin32(width, 255);
    107             row[0] = n;
    108             row[1] = 0xFF;
    109             width -= n;
    110             row += 2;
    111         }
    112         return head;
    113     }
    114 };
    115 
    116 class SkAAClip::Iter {
    117 public:
    118     Iter(const SkAAClip&);
    119 
    120     bool done() const { return fDone; }
    121     int top() const { return fTop; }
    122     int bottom() const { return fBottom; }
    123     const uint8_t* data() const { return fData; }
    124     void next();
    125 
    126 private:
    127     const YOffset* fCurrYOff;
    128     const YOffset* fStopYOff;
    129     const uint8_t* fData;
    130 
    131     int fTop, fBottom;
    132     bool fDone;
    133 };
    134 
    135 SkAAClip::Iter::Iter(const SkAAClip& clip) {
    136     if (clip.isEmpty()) {
    137         fDone = true;
    138         fTop = fBottom = clip.fBounds.fBottom;
    139         fData = nullptr;
    140         fCurrYOff = nullptr;
    141         fStopYOff = nullptr;
    142         return;
    143     }
    144 
    145     const RunHead* head = clip.fRunHead;
    146     fCurrYOff = head->yoffsets();
    147     fStopYOff = fCurrYOff + head->fRowCount;
    148     fData     = head->data() + fCurrYOff->fOffset;
    149 
    150     // setup first value
    151     fTop = clip.fBounds.fTop;
    152     fBottom = clip.fBounds.fTop + fCurrYOff->fY + 1;
    153     fDone = false;
    154 }
    155 
    156 void SkAAClip::Iter::next() {
    157     if (!fDone) {
    158         const YOffset* prev = fCurrYOff;
    159         const YOffset* curr = prev + 1;
    160         SkASSERT(curr <= fStopYOff);
    161 
    162         fTop = fBottom;
    163         if (curr >= fStopYOff) {
    164             fDone = true;
    165             fBottom = kMaxInt32;
    166             fData = nullptr;
    167         } else {
    168             fBottom += curr->fY - prev->fY;
    169             fData += curr->fOffset - prev->fOffset;
    170             fCurrYOff = curr;
    171         }
    172     }
    173 }
    174 
    175 #ifdef SK_DEBUG
    176 // assert we're exactly width-wide, and then return the number of bytes used
    177 static size_t compute_row_length(const uint8_t row[], int width) {
    178     const uint8_t* origRow = row;
    179     while (width > 0) {
    180         int n = row[0];
    181         SkASSERT(n > 0);
    182         SkASSERT(n <= width);
    183         row += 2;
    184         width -= n;
    185     }
    186     SkASSERT(0 == width);
    187     return row - origRow;
    188 }
    189 
    190 void SkAAClip::validate() const {
    191     if (nullptr == fRunHead) {
    192         SkASSERT(fBounds.isEmpty());
    193         return;
    194     }
    195     SkASSERT(!fBounds.isEmpty());
    196 
    197     const RunHead* head = fRunHead;
    198     SkASSERT(head->fRefCnt > 0);
    199     SkASSERT(head->fRowCount > 0);
    200 
    201     const YOffset* yoff = head->yoffsets();
    202     const YOffset* ystop = yoff + head->fRowCount;
    203     const int lastY = fBounds.height() - 1;
    204 
    205     // Y and offset must be monotonic
    206     int prevY = -1;
    207     int32_t prevOffset = -1;
    208     while (yoff < ystop) {
    209         SkASSERT(prevY < yoff->fY);
    210         SkASSERT(yoff->fY <= lastY);
    211         prevY = yoff->fY;
    212         SkASSERT(prevOffset < (int32_t)yoff->fOffset);
    213         prevOffset = yoff->fOffset;
    214         const uint8_t* row = head->data() + yoff->fOffset;
    215         size_t rowLength = compute_row_length(row, fBounds.width());
    216         SkASSERT(yoff->fOffset + rowLength <= head->fDataSize);
    217         yoff += 1;
    218     }
    219     // check the last entry;
    220     --yoff;
    221     SkASSERT(yoff->fY == lastY);
    222 }
    223 
    224 static void dump_one_row(const uint8_t* SK_RESTRICT row,
    225                          int width, int leading_num) {
    226     if (leading_num) {
    227         SkDebugf( "%03d ", leading_num );
    228     }
    229     while (width > 0) {
    230         int n = row[0];
    231         int val = row[1];
    232         char out = '.';
    233         if (val == 0xff) {
    234             out = '*';
    235         } else if (val > 0) {
    236             out = '+';
    237         }
    238         for (int i = 0 ; i < n ; i++) {
    239             SkDebugf( "%c", out );
    240         }
    241         row += 2;
    242         width -= n;
    243     }
    244     SkDebugf( "\n" );
    245 }
    246 
    247 void SkAAClip::debug(bool compress_y) const {
    248     Iter iter(*this);
    249     const int width = fBounds.width();
    250 
    251     int y = fBounds.fTop;
    252     while (!iter.done()) {
    253         if (compress_y) {
    254             dump_one_row(iter.data(), width, iter.bottom() - iter.top() + 1);
    255         } else {
    256             do {
    257                 dump_one_row(iter.data(), width, 0);
    258             } while (++y < iter.bottom());
    259         }
    260         iter.next();
    261     }
    262 }
    263 #endif
    264 
    265 ///////////////////////////////////////////////////////////////////////////////
    266 
    267 // Count the number of zeros on the left and right edges of the passed in
    268 // RLE row. If 'row' is all zeros return 'width' in both variables.
    269 static void count_left_right_zeros(const uint8_t* row, int width,
    270                                    int* leftZ, int* riteZ) {
    271     int zeros = 0;
    272     do {
    273         if (row[1]) {
    274             break;
    275         }
    276         int n = row[0];
    277         SkASSERT(n > 0);
    278         SkASSERT(n <= width);
    279         zeros += n;
    280         row += 2;
    281         width -= n;
    282     } while (width > 0);
    283     *leftZ = zeros;
    284 
    285     if (0 == width) {
    286         // this line is completely empty return 'width' in both variables
    287         *riteZ = *leftZ;
    288         return;
    289     }
    290 
    291     zeros = 0;
    292     while (width > 0) {
    293         int n = row[0];
    294         SkASSERT(n > 0);
    295         if (0 == row[1]) {
    296             zeros += n;
    297         } else {
    298             zeros = 0;
    299         }
    300         row += 2;
    301         width -= n;
    302     }
    303     *riteZ = zeros;
    304 }
    305 
    306 #ifdef SK_DEBUG
    307 static void test_count_left_right_zeros() {
    308     static bool gOnce;
    309     if (gOnce) {
    310         return;
    311     }
    312     gOnce = true;
    313 
    314     const uint8_t data0[] = {  0, 0,     10, 0xFF };
    315     const uint8_t data1[] = {  0, 0,     5, 0xFF, 2, 0, 3, 0xFF };
    316     const uint8_t data2[] = {  7, 0,     5, 0, 2, 0, 3, 0xFF };
    317     const uint8_t data3[] = {  0, 5,     5, 0xFF, 2, 0, 3, 0 };
    318     const uint8_t data4[] = {  2, 3,     2, 0, 5, 0xFF, 3, 0 };
    319     const uint8_t data5[] = { 10, 10,    10, 0 };
    320     const uint8_t data6[] = {  2, 2,     2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    321 
    322     const uint8_t* array[] = {
    323         data0, data1, data2, data3, data4, data5, data6
    324     };
    325 
    326     for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) {
    327         const uint8_t* data = array[i];
    328         const int expectedL = *data++;
    329         const int expectedR = *data++;
    330         int L = 12345, R = 12345;
    331         count_left_right_zeros(data, 10, &L, &R);
    332         SkASSERT(expectedL == L);
    333         SkASSERT(expectedR == R);
    334     }
    335 }
    336 #endif
    337 
    338 // modify row in place, trimming off (zeros) from the left and right sides.
    339 // return the number of bytes that were completely eliminated from the left
    340 static int trim_row_left_right(uint8_t* row, int width, int leftZ, int riteZ) {
    341     int trim = 0;
    342     while (leftZ > 0) {
    343         SkASSERT(0 == row[1]);
    344         int n = row[0];
    345         SkASSERT(n > 0);
    346         SkASSERT(n <= width);
    347         width -= n;
    348         row += 2;
    349         if (n > leftZ) {
    350             row[-2] = n - leftZ;
    351             break;
    352         }
    353         trim += 2;
    354         leftZ -= n;
    355         SkASSERT(leftZ >= 0);
    356     }
    357 
    358     if (riteZ) {
    359         // walk row to the end, and then we'll back up to trim riteZ
    360         while (width > 0) {
    361             int n = row[0];
    362             SkASSERT(n <= width);
    363             width -= n;
    364             row += 2;
    365         }
    366         // now skip whole runs of zeros
    367         do {
    368             row -= 2;
    369             SkASSERT(0 == row[1]);
    370             int n = row[0];
    371             SkASSERT(n > 0);
    372             if (n > riteZ) {
    373                 row[0] = n - riteZ;
    374                 break;
    375             }
    376             riteZ -= n;
    377             SkASSERT(riteZ >= 0);
    378         } while (riteZ > 0);
    379     }
    380 
    381     return trim;
    382 }
    383 
    384 #ifdef SK_DEBUG
    385 // assert that this row is exactly this width
    386 static void assert_row_width(const uint8_t* row, int width) {
    387     while (width > 0) {
    388         int n = row[0];
    389         SkASSERT(n > 0);
    390         SkASSERT(n <= width);
    391         width -= n;
    392         row += 2;
    393     }
    394     SkASSERT(0 == width);
    395 }
    396 
    397 static void test_trim_row_left_right() {
    398     static bool gOnce;
    399     if (gOnce) {
    400         return;
    401     }
    402     gOnce = true;
    403 
    404     uint8_t data0[] = {  0, 0, 0,   10,    10, 0xFF };
    405     uint8_t data1[] = {  2, 0, 0,   10,    5, 0, 2, 0, 3, 0xFF };
    406     uint8_t data2[] = {  5, 0, 2,   10,    5, 0, 2, 0, 3, 0xFF };
    407     uint8_t data3[] = {  6, 0, 2,   10,    5, 0, 2, 0, 3, 0xFF };
    408     uint8_t data4[] = {  0, 0, 0,   10,    2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    409     uint8_t data5[] = {  1, 0, 0,   10,    2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    410     uint8_t data6[] = {  0, 1, 0,   10,    2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    411     uint8_t data7[] = {  1, 1, 0,   10,    2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    412     uint8_t data8[] = {  2, 2, 2,   10,    2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 };
    413     uint8_t data9[] = {  5, 2, 4,   10,    2, 0, 2, 0, 2, 0, 2, 0xFF, 2, 0 };
    414     uint8_t data10[] ={  74, 0, 4, 150,    9, 0, 65, 0, 76, 0xFF };
    415 
    416     uint8_t* array[] = {
    417         data0, data1, data2, data3, data4,
    418         data5, data6, data7, data8, data9,
    419         data10
    420     };
    421 
    422     for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) {
    423         uint8_t* data = array[i];
    424         const int trimL = *data++;
    425         const int trimR = *data++;
    426         const int expectedSkip = *data++;
    427         const int origWidth = *data++;
    428         assert_row_width(data, origWidth);
    429         int skip = trim_row_left_right(data, origWidth, trimL, trimR);
    430         SkASSERT(expectedSkip == skip);
    431         int expectedWidth = origWidth - trimL - trimR;
    432         assert_row_width(data + skip, expectedWidth);
    433     }
    434 }
    435 #endif
    436 
    437 bool SkAAClip::trimLeftRight() {
    438     SkDEBUGCODE(test_trim_row_left_right();)
    439 
    440     if (this->isEmpty()) {
    441         return false;
    442     }
    443 
    444     AUTO_AACLIP_VALIDATE(*this);
    445 
    446     const int width = fBounds.width();
    447     RunHead* head = fRunHead;
    448     YOffset* yoff = head->yoffsets();
    449     YOffset* stop = yoff + head->fRowCount;
    450     uint8_t* base = head->data();
    451 
    452     // After this loop, 'leftZeros' & 'rightZeros' will contain the minimum
    453     // number of zeros on the left and right of the clip. This information
    454     // can be used to shrink the bounding box.
    455     int leftZeros = width;
    456     int riteZeros = width;
    457     while (yoff < stop) {
    458         int L, R;
    459         count_left_right_zeros(base + yoff->fOffset, width, &L, &R);
    460         SkASSERT(L + R < width || (L == width && R == width));
    461         if (L < leftZeros) {
    462             leftZeros = L;
    463         }
    464         if (R < riteZeros) {
    465             riteZeros = R;
    466         }
    467         if (0 == (leftZeros | riteZeros)) {
    468             // no trimming to do
    469             return true;
    470         }
    471         yoff += 1;
    472     }
    473 
    474     SkASSERT(leftZeros || riteZeros);
    475     if (width == leftZeros) {
    476         SkASSERT(width == riteZeros);
    477         return this->setEmpty();
    478     }
    479 
    480     this->validate();
    481 
    482     fBounds.fLeft += leftZeros;
    483     fBounds.fRight -= riteZeros;
    484     SkASSERT(!fBounds.isEmpty());
    485 
    486     // For now we don't realloc the storage (for time), we just shrink in place
    487     // This means we don't have to do any memmoves either, since we can just
    488     // play tricks with the yoff->fOffset for each row
    489     yoff = head->yoffsets();
    490     while (yoff < stop) {
    491         uint8_t* row = base + yoff->fOffset;
    492         SkDEBUGCODE((void)compute_row_length(row, width);)
    493         yoff->fOffset += trim_row_left_right(row, width, leftZeros, riteZeros);
    494         SkDEBUGCODE((void)compute_row_length(base + yoff->fOffset, width - leftZeros - riteZeros);)
    495         yoff += 1;
    496     }
    497     return true;
    498 }
    499 
    500 static bool row_is_all_zeros(const uint8_t* row, int width) {
    501     SkASSERT(width > 0);
    502     do {
    503         if (row[1]) {
    504             return false;
    505         }
    506         int n = row[0];
    507         SkASSERT(n <= width);
    508         width -= n;
    509         row += 2;
    510     } while (width > 0);
    511     SkASSERT(0 == width);
    512     return true;
    513 }
    514 
    515 bool SkAAClip::trimTopBottom() {
    516     if (this->isEmpty()) {
    517         return false;
    518     }
    519 
    520     this->validate();
    521 
    522     const int width = fBounds.width();
    523     RunHead* head = fRunHead;
    524     YOffset* yoff = head->yoffsets();
    525     YOffset* stop = yoff + head->fRowCount;
    526     const uint8_t* base = head->data();
    527 
    528     //  Look to trim away empty rows from the top.
    529     //
    530     int skip = 0;
    531     while (yoff < stop) {
    532         const uint8_t* data = base + yoff->fOffset;
    533         if (!row_is_all_zeros(data, width)) {
    534             break;
    535         }
    536         skip += 1;
    537         yoff += 1;
    538     }
    539     SkASSERT(skip <= head->fRowCount);
    540     if (skip == head->fRowCount) {
    541         return this->setEmpty();
    542     }
    543     if (skip > 0) {
    544         // adjust fRowCount and fBounds.fTop, and slide all the data up
    545         // as we remove [skip] number of YOffset entries
    546         yoff = head->yoffsets();
    547         int dy = yoff[skip - 1].fY + 1;
    548         for (int i = skip; i < head->fRowCount; ++i) {
    549             SkASSERT(yoff[i].fY >= dy);
    550             yoff[i].fY -= dy;
    551         }
    552         YOffset* dst = head->yoffsets();
    553         size_t size = head->fRowCount * sizeof(YOffset) + head->fDataSize;
    554         memmove(dst, dst + skip, size - skip * sizeof(YOffset));
    555 
    556         fBounds.fTop += dy;
    557         SkASSERT(!fBounds.isEmpty());
    558         head->fRowCount -= skip;
    559         SkASSERT(head->fRowCount > 0);
    560 
    561         this->validate();
    562         // need to reset this after the memmove
    563         base = head->data();
    564     }
    565 
    566     //  Look to trim away empty rows from the bottom.
    567     //  We know that we have at least one non-zero row, so we can just walk
    568     //  backwards without checking for running past the start.
    569     //
    570     stop = yoff = head->yoffsets() + head->fRowCount;
    571     do {
    572         yoff -= 1;
    573     } while (row_is_all_zeros(base + yoff->fOffset, width));
    574     skip = SkToInt(stop - yoff - 1);
    575     SkASSERT(skip >= 0 && skip < head->fRowCount);
    576     if (skip > 0) {
    577         // removing from the bottom is easier than from the top, as we don't
    578         // have to adjust any of the Y values, we just have to trim the array
    579         memmove(stop - skip, stop, head->fDataSize);
    580 
    581         fBounds.fBottom = fBounds.fTop + yoff->fY + 1;
    582         SkASSERT(!fBounds.isEmpty());
    583         head->fRowCount -= skip;
    584         SkASSERT(head->fRowCount > 0);
    585     }
    586     this->validate();
    587 
    588     return true;
    589 }
    590 
    591 // can't validate before we're done, since trimming is part of the process of
    592 // making us valid after the Builder. Since we build from top to bottom, its
    593 // possible our fBounds.fBottom is bigger than our last scanline of data, so
    594 // we trim fBounds.fBottom back up.
    595 //
    596 // TODO: check for duplicates in X and Y to further compress our data
    597 //
    598 bool SkAAClip::trimBounds() {
    599     if (this->isEmpty()) {
    600         return false;
    601     }
    602 
    603     const RunHead* head = fRunHead;
    604     const YOffset* yoff = head->yoffsets();
    605 
    606     SkASSERT(head->fRowCount > 0);
    607     const YOffset& lastY = yoff[head->fRowCount - 1];
    608     SkASSERT(lastY.fY + 1 <= fBounds.height());
    609     fBounds.fBottom = fBounds.fTop + lastY.fY + 1;
    610     SkASSERT(lastY.fY + 1 == fBounds.height());
    611     SkASSERT(!fBounds.isEmpty());
    612 
    613     return this->trimTopBottom() && this->trimLeftRight();
    614 }
    615 
    616 ///////////////////////////////////////////////////////////////////////////////
    617 
    618 void SkAAClip::freeRuns() {
    619     if (fRunHead) {
    620         SkASSERT(fRunHead->fRefCnt >= 1);
    621         if (1 == sk_atomic_dec(&fRunHead->fRefCnt)) {
    622             sk_free(fRunHead);
    623         }
    624     }
    625 }
    626 
    627 SkAAClip::SkAAClip() {
    628     fBounds.setEmpty();
    629     fRunHead = nullptr;
    630 }
    631 
    632 SkAAClip::SkAAClip(const SkAAClip& src) {
    633     SkDEBUGCODE(fBounds.setEmpty();)    // need this for validate
    634     fRunHead = nullptr;
    635     *this = src;
    636 }
    637 
    638 SkAAClip::~SkAAClip() {
    639     this->freeRuns();
    640 }
    641 
    642 SkAAClip& SkAAClip::operator=(const SkAAClip& src) {
    643     AUTO_AACLIP_VALIDATE(*this);
    644     src.validate();
    645 
    646     if (this != &src) {
    647         this->freeRuns();
    648         fBounds = src.fBounds;
    649         fRunHead = src.fRunHead;
    650         if (fRunHead) {
    651             sk_atomic_inc(&fRunHead->fRefCnt);
    652         }
    653     }
    654     return *this;
    655 }
    656 
    657 bool operator==(const SkAAClip& a, const SkAAClip& b) {
    658     a.validate();
    659     b.validate();
    660 
    661     if (&a == &b) {
    662         return true;
    663     }
    664     if (a.fBounds != b.fBounds) {
    665         return false;
    666     }
    667 
    668     const SkAAClip::RunHead* ah = a.fRunHead;
    669     const SkAAClip::RunHead* bh = b.fRunHead;
    670 
    671     // this catches empties and rects being equal
    672     if (ah == bh) {
    673         return true;
    674     }
    675 
    676     // now we insist that both are complex (but different ptrs)
    677     if (!a.fRunHead || !b.fRunHead) {
    678         return false;
    679     }
    680 
    681     return  ah->fRowCount == bh->fRowCount &&
    682             ah->fDataSize == bh->fDataSize &&
    683             !memcmp(ah->data(), bh->data(), ah->fDataSize);
    684 }
    685 
    686 void SkAAClip::swap(SkAAClip& other) {
    687     AUTO_AACLIP_VALIDATE(*this);
    688     other.validate();
    689 
    690     SkTSwap(fBounds, other.fBounds);
    691     SkTSwap(fRunHead, other.fRunHead);
    692 }
    693 
    694 bool SkAAClip::set(const SkAAClip& src) {
    695     *this = src;
    696     return !this->isEmpty();
    697 }
    698 
    699 bool SkAAClip::setEmpty() {
    700     this->freeRuns();
    701     fBounds.setEmpty();
    702     fRunHead = nullptr;
    703     return false;
    704 }
    705 
    706 bool SkAAClip::setRect(const SkIRect& bounds) {
    707     if (bounds.isEmpty()) {
    708         return this->setEmpty();
    709     }
    710 
    711     AUTO_AACLIP_VALIDATE(*this);
    712 
    713 #if 0
    714     SkRect r;
    715     r.set(bounds);
    716     SkPath path;
    717     path.addRect(r);
    718     return this->setPath(path);
    719 #else
    720     this->freeRuns();
    721     fBounds = bounds;
    722     fRunHead = RunHead::AllocRect(bounds);
    723     SkASSERT(!this->isEmpty());
    724     return true;
    725 #endif
    726 }
    727 
    728 bool SkAAClip::isRect() const {
    729     if (this->isEmpty()) {
    730         return false;
    731     }
    732 
    733     const RunHead* head = fRunHead;
    734     if (head->fRowCount != 1) {
    735         return false;
    736     }
    737     const YOffset* yoff = head->yoffsets();
    738     if (yoff->fY != fBounds.fBottom - 1) {
    739         return false;
    740     }
    741 
    742     const uint8_t* row = head->data() + yoff->fOffset;
    743     int width = fBounds.width();
    744     do {
    745         if (row[1] != 0xFF) {
    746             return false;
    747         }
    748         int n = row[0];
    749         SkASSERT(n <= width);
    750         width -= n;
    751         row += 2;
    752     } while (width > 0);
    753     return true;
    754 }
    755 
    756 bool SkAAClip::setRect(const SkRect& r, bool doAA) {
    757     if (r.isEmpty()) {
    758         return this->setEmpty();
    759     }
    760 
    761     AUTO_AACLIP_VALIDATE(*this);
    762 
    763     // TODO: special case this
    764 
    765     SkPath path;
    766     path.addRect(r);
    767     return this->setPath(path, nullptr, doAA);
    768 }
    769 
    770 static void append_run(SkTDArray<uint8_t>& array, uint8_t value, int count) {
    771     SkASSERT(count >= 0);
    772     while (count > 0) {
    773         int n = count;
    774         if (n > 255) {
    775             n = 255;
    776         }
    777         uint8_t* data = array.append(2);
    778         data[0] = n;
    779         data[1] = value;
    780         count -= n;
    781     }
    782 }
    783 
    784 bool SkAAClip::setRegion(const SkRegion& rgn) {
    785     if (rgn.isEmpty()) {
    786         return this->setEmpty();
    787     }
    788     if (rgn.isRect()) {
    789         return this->setRect(rgn.getBounds());
    790     }
    791 
    792 #if 0
    793     SkAAClip clip;
    794     SkRegion::Iterator iter(rgn);
    795     for (; !iter.done(); iter.next()) {
    796         clip.op(iter.rect(), SkRegion::kUnion_Op);
    797     }
    798     this->swap(clip);
    799     return !this->isEmpty();
    800 #else
    801     const SkIRect& bounds = rgn.getBounds();
    802     const int offsetX = bounds.fLeft;
    803     const int offsetY = bounds.fTop;
    804 
    805     SkTDArray<YOffset> yArray;
    806     SkTDArray<uint8_t> xArray;
    807 
    808     yArray.setReserve(SkMin32(bounds.height(), 1024));
    809     xArray.setReserve(SkMin32(bounds.width(), 512) * 128);
    810 
    811     SkRegion::Iterator iter(rgn);
    812     int prevRight = 0;
    813     int prevBot = 0;
    814     YOffset* currY = nullptr;
    815 
    816     for (; !iter.done(); iter.next()) {
    817         const SkIRect& r = iter.rect();
    818         SkASSERT(bounds.contains(r));
    819 
    820         int bot = r.fBottom - offsetY;
    821         SkASSERT(bot >= prevBot);
    822         if (bot > prevBot) {
    823             if (currY) {
    824                 // flush current row
    825                 append_run(xArray, 0, bounds.width() - prevRight);
    826             }
    827             // did we introduce an empty-gap from the prev row?
    828             int top = r.fTop - offsetY;
    829             if (top > prevBot) {
    830                 currY = yArray.append();
    831                 currY->fY = top - 1;
    832                 currY->fOffset = xArray.count();
    833                 append_run(xArray, 0, bounds.width());
    834             }
    835             // create a new record for this Y value
    836             currY = yArray.append();
    837             currY->fY = bot - 1;
    838             currY->fOffset = xArray.count();
    839             prevRight = 0;
    840             prevBot = bot;
    841         }
    842 
    843         int x = r.fLeft - offsetX;
    844         append_run(xArray, 0, x - prevRight);
    845 
    846         int w = r.fRight - r.fLeft;
    847         append_run(xArray, 0xFF, w);
    848         prevRight = x + w;
    849         SkASSERT(prevRight <= bounds.width());
    850     }
    851     // flush last row
    852     append_run(xArray, 0, bounds.width() - prevRight);
    853 
    854     // now pack everything into a RunHead
    855     RunHead* head = RunHead::Alloc(yArray.count(), xArray.bytes());
    856     memcpy(head->yoffsets(), yArray.begin(), yArray.bytes());
    857     memcpy(head->data(), xArray.begin(), xArray.bytes());
    858 
    859     this->setEmpty();
    860     fBounds = bounds;
    861     fRunHead = head;
    862     this->validate();
    863     return true;
    864 #endif
    865 }
    866 
    867 ///////////////////////////////////////////////////////////////////////////////
    868 
    869 const uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const {
    870     SkASSERT(fRunHead);
    871 
    872     if (!y_in_rect(y, fBounds)) {
    873         return nullptr;
    874     }
    875     y -= fBounds.y();  // our yoffs values are relative to the top
    876 
    877     const YOffset* yoff = fRunHead->yoffsets();
    878     while (yoff->fY < y) {
    879         yoff += 1;
    880         SkASSERT(yoff - fRunHead->yoffsets() < fRunHead->fRowCount);
    881     }
    882 
    883     if (lastYForRow) {
    884         *lastYForRow = fBounds.y() + yoff->fY;
    885     }
    886     return fRunHead->data() + yoff->fOffset;
    887 }
    888 
    889 const uint8_t* SkAAClip::findX(const uint8_t data[], int x, int* initialCount) const {
    890     SkASSERT(x_in_rect(x, fBounds));
    891     x -= fBounds.x();
    892 
    893     // first skip up to X
    894     for (;;) {
    895         int n = data[0];
    896         if (x < n) {
    897             if (initialCount) {
    898                 *initialCount = n - x;
    899             }
    900             break;
    901         }
    902         data += 2;
    903         x -= n;
    904     }
    905     return data;
    906 }
    907 
    908 bool SkAAClip::quickContains(int left, int top, int right, int bottom) const {
    909     if (this->isEmpty()) {
    910         return false;
    911     }
    912     if (!fBounds.contains(left, top, right, bottom)) {
    913         return false;
    914     }
    915 #if 0
    916     if (this->isRect()) {
    917         return true;
    918     }
    919 #endif
    920 
    921     int lastY SK_INIT_TO_AVOID_WARNING;
    922     const uint8_t* row = this->findRow(top, &lastY);
    923     if (lastY < bottom) {
    924         return false;
    925     }
    926     // now just need to check in X
    927     int count;
    928     row = this->findX(row, left, &count);
    929 #if 0
    930     return count >= (right - left) && 0xFF == row[1];
    931 #else
    932     int rectWidth = right - left;
    933     while (0xFF == row[1]) {
    934         if (count >= rectWidth) {
    935             return true;
    936         }
    937         rectWidth -= count;
    938         row += 2;
    939         count = row[0];
    940     }
    941     return false;
    942 #endif
    943 }
    944 
    945 ///////////////////////////////////////////////////////////////////////////////
    946 
    947 class SkAAClip::Builder {
    948     SkIRect fBounds;
    949     struct Row {
    950         int fY;
    951         int fWidth;
    952         SkTDArray<uint8_t>* fData;
    953     };
    954     SkTDArray<Row>  fRows;
    955     Row* fCurrRow;
    956     int fPrevY;
    957     int fWidth;
    958     int fMinY;
    959 
    960 public:
    961     Builder(const SkIRect& bounds) : fBounds(bounds) {
    962         fPrevY = -1;
    963         fWidth = bounds.width();
    964         fCurrRow = nullptr;
    965         fMinY = bounds.fTop;
    966     }
    967 
    968     ~Builder() {
    969         Row* row = fRows.begin();
    970         Row* stop = fRows.end();
    971         while (row < stop) {
    972             delete row->fData;
    973             row += 1;
    974         }
    975     }
    976 
    977     const SkIRect& getBounds() const { return fBounds; }
    978 
    979     void addRun(int x, int y, U8CPU alpha, int count) {
    980         SkASSERT(count > 0);
    981         SkASSERT(fBounds.contains(x, y));
    982         SkASSERT(fBounds.contains(x + count - 1, y));
    983 
    984         x -= fBounds.left();
    985         y -= fBounds.top();
    986 
    987         Row* row = fCurrRow;
    988         if (y != fPrevY) {
    989             SkASSERT(y > fPrevY);
    990             fPrevY = y;
    991             row = this->flushRow(true);
    992             row->fY = y;
    993             row->fWidth = 0;
    994             SkASSERT(row->fData);
    995             SkASSERT(0 == row->fData->count());
    996             fCurrRow = row;
    997         }
    998 
    999         SkASSERT(row->fWidth <= x);
   1000         SkASSERT(row->fWidth < fBounds.width());
   1001 
   1002         SkTDArray<uint8_t>& data = *row->fData;
   1003 
   1004         int gap = x - row->fWidth;
   1005         if (gap) {
   1006             AppendRun(data, 0, gap);
   1007             row->fWidth += gap;
   1008             SkASSERT(row->fWidth < fBounds.width());
   1009         }
   1010 
   1011         AppendRun(data, alpha, count);
   1012         row->fWidth += count;
   1013         SkASSERT(row->fWidth <= fBounds.width());
   1014     }
   1015 
   1016     void addColumn(int x, int y, U8CPU alpha, int height) {
   1017         SkASSERT(fBounds.contains(x, y + height - 1));
   1018 
   1019         this->addRun(x, y, alpha, 1);
   1020         this->flushRowH(fCurrRow);
   1021         y -= fBounds.fTop;
   1022         SkASSERT(y == fCurrRow->fY);
   1023         fCurrRow->fY = y + height - 1;
   1024     }
   1025 
   1026     void addRectRun(int x, int y, int width, int height) {
   1027         SkASSERT(fBounds.contains(x + width - 1, y + height - 1));
   1028         this->addRun(x, y, 0xFF, width);
   1029 
   1030         // we assum the rect must be all we'll see for these scanlines
   1031         // so we ensure our row goes all the way to our right
   1032         this->flushRowH(fCurrRow);
   1033 
   1034         y -= fBounds.fTop;
   1035         SkASSERT(y == fCurrRow->fY);
   1036         fCurrRow->fY = y + height - 1;
   1037     }
   1038 
   1039     void addAntiRectRun(int x, int y, int width, int height,
   1040                         SkAlpha leftAlpha, SkAlpha rightAlpha) {
   1041         // According to SkBlitter.cpp, no matter whether leftAlpha is 0 or positive,
   1042         // we should always consider [x, x+1] as the left-most column and [x+1, x+1+width]
   1043         // as the rect with full alpha.
   1044         SkASSERT(fBounds.contains(x + width + (rightAlpha > 0 ? 1 : 0),
   1045                  y + height - 1));
   1046         SkASSERT(width >= 0);
   1047 
   1048         // Conceptually we're always adding 3 runs, but we should
   1049         // merge or omit them if possible.
   1050         if (leftAlpha == 0xFF) {
   1051             width++;
   1052         } else if (leftAlpha > 0) {
   1053           this->addRun(x++, y, leftAlpha, 1);
   1054         } else {
   1055           // leftAlpha is 0, ignore the left column
   1056           x++;
   1057         }
   1058         if (rightAlpha == 0xFF) {
   1059             width++;
   1060         }
   1061         if (width > 0) {
   1062             this->addRun(x, y, 0xFF, width);
   1063         }
   1064         if (rightAlpha > 0 && rightAlpha < 255) {
   1065             this->addRun(x + width, y, rightAlpha, 1);
   1066         }
   1067 
   1068         // we assume the rect must be all we'll see for these scanlines
   1069         // so we ensure our row goes all the way to our right
   1070         this->flushRowH(fCurrRow);
   1071 
   1072         y -= fBounds.fTop;
   1073         SkASSERT(y == fCurrRow->fY);
   1074         fCurrRow->fY = y + height - 1;
   1075     }
   1076 
   1077     bool finish(SkAAClip* target) {
   1078         this->flushRow(false);
   1079 
   1080         const Row* row = fRows.begin();
   1081         const Row* stop = fRows.end();
   1082 
   1083         size_t dataSize = 0;
   1084         while (row < stop) {
   1085             dataSize += row->fData->count();
   1086             row += 1;
   1087         }
   1088 
   1089         if (0 == dataSize) {
   1090             return target->setEmpty();
   1091         }
   1092 
   1093         SkASSERT(fMinY >= fBounds.fTop);
   1094         SkASSERT(fMinY < fBounds.fBottom);
   1095         int adjustY = fMinY - fBounds.fTop;
   1096         fBounds.fTop = fMinY;
   1097 
   1098         RunHead* head = RunHead::Alloc(fRows.count(), dataSize);
   1099         YOffset* yoffset = head->yoffsets();
   1100         uint8_t* data = head->data();
   1101         uint8_t* baseData = data;
   1102 
   1103         row = fRows.begin();
   1104         SkDEBUGCODE(int prevY = row->fY - 1;)
   1105         while (row < stop) {
   1106             SkASSERT(prevY < row->fY);  // must be monotonic
   1107             SkDEBUGCODE(prevY = row->fY);
   1108 
   1109             yoffset->fY = row->fY - adjustY;
   1110             yoffset->fOffset = SkToU32(data - baseData);
   1111             yoffset += 1;
   1112 
   1113             size_t n = row->fData->count();
   1114             memcpy(data, row->fData->begin(), n);
   1115 #ifdef SK_DEBUG
   1116             size_t bytesNeeded = compute_row_length(data, fBounds.width());
   1117             SkASSERT(bytesNeeded == n);
   1118 #endif
   1119             data += n;
   1120 
   1121             row += 1;
   1122         }
   1123 
   1124         target->freeRuns();
   1125         target->fBounds = fBounds;
   1126         target->fRunHead = head;
   1127         return target->trimBounds();
   1128     }
   1129 
   1130     void dump() {
   1131         this->validate();
   1132         int y;
   1133         for (y = 0; y < fRows.count(); ++y) {
   1134             const Row& row = fRows[y];
   1135             SkDebugf("Y:%3d W:%3d", row.fY, row.fWidth);
   1136             const SkTDArray<uint8_t>& data = *row.fData;
   1137             int count = data.count();
   1138             SkASSERT(!(count & 1));
   1139             const uint8_t* ptr = data.begin();
   1140             for (int x = 0; x < count; x += 2) {
   1141                 SkDebugf(" [%3d:%02X]", ptr[0], ptr[1]);
   1142                 ptr += 2;
   1143             }
   1144             SkDebugf("\n");
   1145         }
   1146     }
   1147 
   1148     void validate() {
   1149 #ifdef SK_DEBUG
   1150         if (false) { // avoid bit rot, suppress warning
   1151             test_count_left_right_zeros();
   1152         }
   1153         int prevY = -1;
   1154         for (int i = 0; i < fRows.count(); ++i) {
   1155             const Row& row = fRows[i];
   1156             SkASSERT(prevY < row.fY);
   1157             SkASSERT(fWidth == row.fWidth);
   1158             int count = row.fData->count();
   1159             const uint8_t* ptr = row.fData->begin();
   1160             SkASSERT(!(count & 1));
   1161             int w = 0;
   1162             for (int x = 0; x < count; x += 2) {
   1163                 int n = ptr[0];
   1164                 SkASSERT(n > 0);
   1165                 w += n;
   1166                 SkASSERT(w <= fWidth);
   1167                 ptr += 2;
   1168             }
   1169             SkASSERT(w == fWidth);
   1170             prevY = row.fY;
   1171         }
   1172 #endif
   1173     }
   1174 
   1175     // only called by BuilderBlitter
   1176     void setMinY(int y) {
   1177         fMinY = y;
   1178     }
   1179 
   1180 private:
   1181     void flushRowH(Row* row) {
   1182         // flush current row if needed
   1183         if (row->fWidth < fWidth) {
   1184             AppendRun(*row->fData, 0, fWidth - row->fWidth);
   1185             row->fWidth = fWidth;
   1186         }
   1187     }
   1188 
   1189     Row* flushRow(bool readyForAnother) {
   1190         Row* next = nullptr;
   1191         int count = fRows.count();
   1192         if (count > 0) {
   1193             this->flushRowH(&fRows[count - 1]);
   1194         }
   1195         if (count > 1) {
   1196             // are our last two runs the same?
   1197             Row* prev = &fRows[count - 2];
   1198             Row* curr = &fRows[count - 1];
   1199             SkASSERT(prev->fWidth == fWidth);
   1200             SkASSERT(curr->fWidth == fWidth);
   1201             if (*prev->fData == *curr->fData) {
   1202                 prev->fY = curr->fY;
   1203                 if (readyForAnother) {
   1204                     curr->fData->rewind();
   1205                     next = curr;
   1206                 } else {
   1207                     delete curr->fData;
   1208                     fRows.removeShuffle(count - 1);
   1209                 }
   1210             } else {
   1211                 if (readyForAnother) {
   1212                     next = fRows.append();
   1213                     next->fData = new SkTDArray<uint8_t>;
   1214                 }
   1215             }
   1216         } else {
   1217             if (readyForAnother) {
   1218                 next = fRows.append();
   1219                 next->fData = new SkTDArray<uint8_t>;
   1220             }
   1221         }
   1222         return next;
   1223     }
   1224 
   1225     static void AppendRun(SkTDArray<uint8_t>& data, U8CPU alpha, int count) {
   1226         do {
   1227             int n = count;
   1228             if (n > 255) {
   1229                 n = 255;
   1230             }
   1231             uint8_t* ptr = data.append(2);
   1232             ptr[0] = n;
   1233             ptr[1] = alpha;
   1234             count -= n;
   1235         } while (count > 0);
   1236     }
   1237 };
   1238 
   1239 class SkAAClip::BuilderBlitter : public SkBlitter {
   1240     int fLastY;
   1241 
   1242     /*
   1243         If we see a gap of 1 or more empty scanlines while building in Y-order,
   1244         we inject an explicit empty scanline (alpha==0)
   1245 
   1246         See AAClipTest.cpp : test_path_with_hole()
   1247      */
   1248     void checkForYGap(int y) {
   1249         SkASSERT(y >= fLastY);
   1250         if (fLastY > -SK_MaxS32) {
   1251             int gap = y - fLastY;
   1252             if (gap > 1) {
   1253                 fBuilder->addRun(fLeft, y - 1, 0, fRight - fLeft);
   1254             }
   1255         }
   1256         fLastY = y;
   1257     }
   1258 
   1259 public:
   1260 
   1261     BuilderBlitter(Builder* builder) {
   1262         fBuilder = builder;
   1263         fLeft = builder->getBounds().fLeft;
   1264         fRight = builder->getBounds().fRight;
   1265         fMinY = SK_MaxS32;
   1266         fLastY = -SK_MaxS32;    // sentinel
   1267     }
   1268 
   1269     void finish() {
   1270         if (fMinY < SK_MaxS32) {
   1271             fBuilder->setMinY(fMinY);
   1272         }
   1273     }
   1274 
   1275     /**
   1276        Must evaluate clips in scan-line order, so don't want to allow blitV(),
   1277        but an AAClip can be clipped down to a single pixel wide, so we
   1278        must support it (given AntiRect semantics: minimum width is 2).
   1279        Instead we'll rely on the runtime asserts to guarantee Y monotonicity;
   1280        any failure cases that misses may have minor artifacts.
   1281     */
   1282     void blitV(int x, int y, int height, SkAlpha alpha) override {
   1283         if (height == 1) {
   1284             // We're still in scan-line order if height is 1
   1285             // This is useful for Analytic AA
   1286             const SkAlpha alphas[2] = {alpha, 0};
   1287             const int16_t runs[2] = {1, 0};
   1288             this->blitAntiH(x, y, alphas, runs);
   1289         } else {
   1290             this->recordMinY(y);
   1291             fBuilder->addColumn(x, y, alpha, height);
   1292             fLastY = y + height - 1;
   1293         }
   1294     }
   1295 
   1296     void blitRect(int x, int y, int width, int height) override {
   1297         this->recordMinY(y);
   1298         this->checkForYGap(y);
   1299         fBuilder->addRectRun(x, y, width, height);
   1300         fLastY = y + height - 1;
   1301     }
   1302 
   1303     virtual void blitAntiRect(int x, int y, int width, int height,
   1304                      SkAlpha leftAlpha, SkAlpha rightAlpha) override {
   1305         this->recordMinY(y);
   1306         this->checkForYGap(y);
   1307         fBuilder->addAntiRectRun(x, y, width, height, leftAlpha, rightAlpha);
   1308         fLastY = y + height - 1;
   1309     }
   1310 
   1311     void blitMask(const SkMask&, const SkIRect& clip) override
   1312         { unexpected(); }
   1313 
   1314     const SkPixmap* justAnOpaqueColor(uint32_t*) override {
   1315         return nullptr;
   1316     }
   1317 
   1318     void blitH(int x, int y, int width) override {
   1319         this->recordMinY(y);
   1320         this->checkForYGap(y);
   1321         fBuilder->addRun(x, y, 0xFF, width);
   1322     }
   1323 
   1324     virtual void blitAntiH(int x, int y, const SkAlpha alpha[],
   1325                            const int16_t runs[]) override {
   1326         this->recordMinY(y);
   1327         this->checkForYGap(y);
   1328         for (;;) {
   1329             int count = *runs;
   1330             if (count <= 0) {
   1331                 return;
   1332             }
   1333 
   1334             // The supersampler's buffer can be the width of the device, so
   1335             // we may have to trim the run to our bounds. Previously, we assert that
   1336             // the extra spans are always alpha==0.
   1337             // However, the analytic AA is too sensitive to precision errors
   1338             // so it may have extra spans with very tiny alpha because after several
   1339             // arithmatic operations, the edge may bleed the path boundary a little bit.
   1340             // Therefore, instead of always asserting alpha==0, we assert alpha < 0x10.
   1341             int localX = x;
   1342             int localCount = count;
   1343             if (x < fLeft) {
   1344                 SkASSERT(0x10 > *alpha);
   1345                 int gap = fLeft - x;
   1346                 SkASSERT(gap <= count);
   1347                 localX += gap;
   1348                 localCount -= gap;
   1349             }
   1350             int right = x + count;
   1351             if (right > fRight) {
   1352                 SkASSERT(0x10 > *alpha);
   1353                 localCount -= right - fRight;
   1354                 SkASSERT(localCount >= 0);
   1355             }
   1356 
   1357             if (localCount) {
   1358                 fBuilder->addRun(localX, y, *alpha, localCount);
   1359             }
   1360             // Next run
   1361             runs += count;
   1362             alpha += count;
   1363             x += count;
   1364         }
   1365     }
   1366 
   1367 private:
   1368     Builder* fBuilder;
   1369     int      fLeft; // cache of builder's bounds' left edge
   1370     int      fRight;
   1371     int      fMinY;
   1372 
   1373     /*
   1374      *  We track this, in case the scan converter skipped some number of
   1375      *  scanlines at the (relative to the bounds it was given). This allows
   1376      *  the builder, during its finish, to trip its bounds down to the "real"
   1377      *  top.
   1378      */
   1379     void recordMinY(int y) {
   1380         if (y < fMinY) {
   1381             fMinY = y;
   1382         }
   1383     }
   1384 
   1385     void unexpected() {
   1386         SK_ABORT("---- did not expect to get called here");
   1387     }
   1388 };
   1389 
   1390 bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) {
   1391     AUTO_AACLIP_VALIDATE(*this);
   1392 
   1393     if (clip && clip->isEmpty()) {
   1394         return this->setEmpty();
   1395     }
   1396 
   1397     SkIRect ibounds;
   1398     path.getBounds().roundOut(&ibounds);
   1399 
   1400     SkRegion tmpClip;
   1401     if (nullptr == clip) {
   1402         tmpClip.setRect(ibounds);
   1403         clip = &tmpClip;
   1404     }
   1405 
   1406     // Since we assert that the BuilderBlitter will never blit outside the intersection
   1407     // of clip and ibounds, we create this snugClip to be that intersection and send it
   1408     // to the scan-converter.
   1409     SkRegion snugClip(*clip);
   1410 
   1411     if (path.isInverseFillType()) {
   1412         ibounds = clip->getBounds();
   1413     } else {
   1414         if (ibounds.isEmpty() || !ibounds.intersect(clip->getBounds())) {
   1415             return this->setEmpty();
   1416         }
   1417         snugClip.op(ibounds, SkRegion::kIntersect_Op);
   1418     }
   1419 
   1420     Builder        builder(ibounds);
   1421     BuilderBlitter blitter(&builder);
   1422 
   1423     if (doAA) {
   1424         SkScan::AntiFillPath(path, snugClip, &blitter, true);
   1425     } else {
   1426         SkScan::FillPath(path, snugClip, &blitter);
   1427     }
   1428 
   1429     blitter.finish();
   1430     return builder.finish(this);
   1431 }
   1432 
   1433 ///////////////////////////////////////////////////////////////////////////////
   1434 
   1435 typedef void (*RowProc)(SkAAClip::Builder&, int bottom,
   1436                         const uint8_t* rowA, const SkIRect& rectA,
   1437                         const uint8_t* rowB, const SkIRect& rectB);
   1438 
   1439 typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB);
   1440 
   1441 static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) {
   1442     // Multiply
   1443     return SkMulDiv255Round(alphaA, alphaB);
   1444 }
   1445 
   1446 static U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) {
   1447     // SrcOver
   1448     return alphaA + alphaB - SkMulDiv255Round(alphaA, alphaB);
   1449 }
   1450 
   1451 static U8CPU diffAlphaProc(U8CPU alphaA, U8CPU alphaB) {
   1452     // SrcOut
   1453     return SkMulDiv255Round(alphaA, 0xFF - alphaB);
   1454 }
   1455 
   1456 static U8CPU xorAlphaProc(U8CPU alphaA, U8CPU alphaB) {
   1457     // XOR
   1458     return alphaA + alphaB - 2 * SkMulDiv255Round(alphaA, alphaB);
   1459 }
   1460 
   1461 static AlphaProc find_alpha_proc(SkRegion::Op op) {
   1462     switch (op) {
   1463         case SkRegion::kIntersect_Op:
   1464             return sectAlphaProc;
   1465         case SkRegion::kDifference_Op:
   1466             return diffAlphaProc;
   1467         case SkRegion::kUnion_Op:
   1468             return unionAlphaProc;
   1469         case SkRegion::kXOR_Op:
   1470             return xorAlphaProc;
   1471         default:
   1472             SkDEBUGFAIL("unexpected region op");
   1473             return sectAlphaProc;
   1474     }
   1475 }
   1476 
   1477 class RowIter {
   1478 public:
   1479     RowIter(const uint8_t* row, const SkIRect& bounds) {
   1480         fRow = row;
   1481         fLeft = bounds.fLeft;
   1482         fBoundsRight = bounds.fRight;
   1483         if (row) {
   1484             fRight = bounds.fLeft + row[0];
   1485             SkASSERT(fRight <= fBoundsRight);
   1486             fAlpha = row[1];
   1487             fDone = false;
   1488         } else {
   1489             fDone = true;
   1490             fRight = kMaxInt32;
   1491             fAlpha = 0;
   1492         }
   1493     }
   1494 
   1495     bool done() const { return fDone; }
   1496     int left() const { return fLeft; }
   1497     int right() const { return fRight; }
   1498     U8CPU alpha() const { return fAlpha; }
   1499     void next() {
   1500         if (!fDone) {
   1501             fLeft = fRight;
   1502             if (fRight == fBoundsRight) {
   1503                 fDone = true;
   1504                 fRight = kMaxInt32;
   1505                 fAlpha = 0;
   1506             } else {
   1507                 fRow += 2;
   1508                 fRight += fRow[0];
   1509                 fAlpha = fRow[1];
   1510                 SkASSERT(fRight <= fBoundsRight);
   1511             }
   1512         }
   1513     }
   1514 
   1515 private:
   1516     const uint8_t*  fRow;
   1517     int             fLeft;
   1518     int             fRight;
   1519     int             fBoundsRight;
   1520     bool            fDone;
   1521     uint8_t         fAlpha;
   1522 };
   1523 
   1524 static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) {
   1525     if (rite == riteA) {
   1526         iter.next();
   1527         leftA = iter.left();
   1528         riteA = iter.right();
   1529     }
   1530 }
   1531 
   1532 #if 0 // UNUSED
   1533 static bool intersect(int& min, int& max, int boundsMin, int boundsMax) {
   1534     SkASSERT(min < max);
   1535     SkASSERT(boundsMin < boundsMax);
   1536     if (min >= boundsMax || max <= boundsMin) {
   1537         return false;
   1538     }
   1539     if (min < boundsMin) {
   1540         min = boundsMin;
   1541     }
   1542     if (max > boundsMax) {
   1543         max = boundsMax;
   1544     }
   1545     return true;
   1546 }
   1547 #endif
   1548 
   1549 static void operatorX(SkAAClip::Builder& builder, int lastY,
   1550                       RowIter& iterA, RowIter& iterB,
   1551                       AlphaProc proc, const SkIRect& bounds) {
   1552     int leftA = iterA.left();
   1553     int riteA = iterA.right();
   1554     int leftB = iterB.left();
   1555     int riteB = iterB.right();
   1556 
   1557     int prevRite = bounds.fLeft;
   1558 
   1559     do {
   1560         U8CPU alphaA = 0;
   1561         U8CPU alphaB = 0;
   1562         int left, rite;
   1563 
   1564         if (leftA < leftB) {
   1565             left = leftA;
   1566             alphaA = iterA.alpha();
   1567             if (riteA <= leftB) {
   1568                 rite = riteA;
   1569             } else {
   1570                 rite = leftA = leftB;
   1571             }
   1572         } else if (leftB < leftA) {
   1573             left = leftB;
   1574             alphaB = iterB.alpha();
   1575             if (riteB <= leftA) {
   1576                 rite = riteB;
   1577             } else {
   1578                 rite = leftB = leftA;
   1579             }
   1580         } else {
   1581             left = leftA;   // or leftB, since leftA == leftB
   1582             rite = leftA = leftB = SkMin32(riteA, riteB);
   1583             alphaA = iterA.alpha();
   1584             alphaB = iterB.alpha();
   1585         }
   1586 
   1587         if (left >= bounds.fRight) {
   1588             break;
   1589         }
   1590         if (rite > bounds.fRight) {
   1591             rite = bounds.fRight;
   1592         }
   1593 
   1594         if (left >= bounds.fLeft) {
   1595             SkASSERT(rite > left);
   1596             builder.addRun(left, lastY, proc(alphaA, alphaB), rite - left);
   1597             prevRite = rite;
   1598         }
   1599 
   1600         adjust_row(iterA, leftA, riteA, rite);
   1601         adjust_row(iterB, leftB, riteB, rite);
   1602     } while (!iterA.done() || !iterB.done());
   1603 
   1604     if (prevRite < bounds.fRight) {
   1605         builder.addRun(prevRite, lastY, 0, bounds.fRight - prevRite);
   1606     }
   1607 }
   1608 
   1609 static void adjust_iter(SkAAClip::Iter& iter, int& topA, int& botA, int bot) {
   1610     if (bot == botA) {
   1611         iter.next();
   1612         topA = botA;
   1613         SkASSERT(botA == iter.top());
   1614         botA = iter.bottom();
   1615     }
   1616 }
   1617 
   1618 static void operateY(SkAAClip::Builder& builder, const SkAAClip& A,
   1619                      const SkAAClip& B, SkRegion::Op op) {
   1620     AlphaProc proc = find_alpha_proc(op);
   1621     const SkIRect& bounds = builder.getBounds();
   1622 
   1623     SkAAClip::Iter iterA(A);
   1624     SkAAClip::Iter iterB(B);
   1625 
   1626     SkASSERT(!iterA.done());
   1627     int topA = iterA.top();
   1628     int botA = iterA.bottom();
   1629     SkASSERT(!iterB.done());
   1630     int topB = iterB.top();
   1631     int botB = iterB.bottom();
   1632 
   1633     do {
   1634         const uint8_t* rowA = nullptr;
   1635         const uint8_t* rowB = nullptr;
   1636         int top, bot;
   1637 
   1638         if (topA < topB) {
   1639             top = topA;
   1640             rowA = iterA.data();
   1641             if (botA <= topB) {
   1642                 bot = botA;
   1643             } else {
   1644                 bot = topA = topB;
   1645             }
   1646 
   1647         } else if (topB < topA) {
   1648             top = topB;
   1649             rowB = iterB.data();
   1650             if (botB <= topA) {
   1651                 bot = botB;
   1652             } else {
   1653                 bot = topB = topA;
   1654             }
   1655         } else {
   1656             top = topA;   // or topB, since topA == topB
   1657             bot = topA = topB = SkMin32(botA, botB);
   1658             rowA = iterA.data();
   1659             rowB = iterB.data();
   1660         }
   1661 
   1662         if (top >= bounds.fBottom) {
   1663             break;
   1664         }
   1665 
   1666         if (bot > bounds.fBottom) {
   1667             bot = bounds.fBottom;
   1668         }
   1669         SkASSERT(top < bot);
   1670 
   1671         if (!rowA && !rowB) {
   1672             builder.addRun(bounds.fLeft, bot - 1, 0, bounds.width());
   1673         } else if (top >= bounds.fTop) {
   1674             SkASSERT(bot <= bounds.fBottom);
   1675             RowIter rowIterA(rowA, rowA ? A.getBounds() : bounds);
   1676             RowIter rowIterB(rowB, rowB ? B.getBounds() : bounds);
   1677             operatorX(builder, bot - 1, rowIterA, rowIterB, proc, bounds);
   1678         }
   1679 
   1680         adjust_iter(iterA, topA, botA, bot);
   1681         adjust_iter(iterB, topB, botB, bot);
   1682     } while (!iterA.done() || !iterB.done());
   1683 }
   1684 
   1685 bool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig,
   1686                   SkRegion::Op op) {
   1687     AUTO_AACLIP_VALIDATE(*this);
   1688 
   1689     if (SkRegion::kReplace_Op == op) {
   1690         return this->set(clipBOrig);
   1691     }
   1692 
   1693     const SkAAClip* clipA = &clipAOrig;
   1694     const SkAAClip* clipB = &clipBOrig;
   1695 
   1696     if (SkRegion::kReverseDifference_Op == op) {
   1697         SkTSwap(clipA, clipB);
   1698         op = SkRegion::kDifference_Op;
   1699     }
   1700 
   1701     bool a_empty = clipA->isEmpty();
   1702     bool b_empty = clipB->isEmpty();
   1703 
   1704     SkIRect bounds;
   1705     switch (op) {
   1706         case SkRegion::kDifference_Op:
   1707             if (a_empty) {
   1708                 return this->setEmpty();
   1709             }
   1710             if (b_empty || !SkIRect::Intersects(clipA->fBounds, clipB->fBounds)) {
   1711                 return this->set(*clipA);
   1712             }
   1713             bounds = clipA->fBounds;
   1714             break;
   1715 
   1716         case SkRegion::kIntersect_Op:
   1717             if ((a_empty | b_empty) || !bounds.intersect(clipA->fBounds,
   1718                                                          clipB->fBounds)) {
   1719                 return this->setEmpty();
   1720             }
   1721             break;
   1722 
   1723         case SkRegion::kUnion_Op:
   1724         case SkRegion::kXOR_Op:
   1725             if (a_empty) {
   1726                 return this->set(*clipB);
   1727             }
   1728             if (b_empty) {
   1729                 return this->set(*clipA);
   1730             }
   1731             bounds = clipA->fBounds;
   1732             bounds.join(clipB->fBounds);
   1733             break;
   1734 
   1735         default:
   1736             SkDEBUGFAIL("unknown region op");
   1737             return !this->isEmpty();
   1738     }
   1739 
   1740     SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds));
   1741     SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds));
   1742 
   1743     Builder builder(bounds);
   1744     operateY(builder, *clipA, *clipB, op);
   1745 
   1746     return builder.finish(this);
   1747 }
   1748 
   1749 /*
   1750  *  It can be expensive to build a local aaclip before applying the op, so
   1751  *  we first see if we can restrict the bounds of new rect to our current
   1752  *  bounds, or note that the new rect subsumes our current clip.
   1753  */
   1754 
   1755 bool SkAAClip::op(const SkIRect& rOrig, SkRegion::Op op) {
   1756     SkIRect        rStorage;
   1757     const SkIRect* r = &rOrig;
   1758 
   1759     switch (op) {
   1760         case SkRegion::kIntersect_Op:
   1761             if (!rStorage.intersect(rOrig, fBounds)) {
   1762                 // no overlap, so we're empty
   1763                 return this->setEmpty();
   1764             }
   1765             if (rStorage == fBounds) {
   1766                 // we were wholly inside the rect, no change
   1767                 return !this->isEmpty();
   1768             }
   1769             if (this->quickContains(rStorage)) {
   1770                 // the intersection is wholly inside us, we're a rect
   1771                 return this->setRect(rStorage);
   1772             }
   1773             r = &rStorage;   // use the intersected bounds
   1774             break;
   1775         case SkRegion::kDifference_Op:
   1776             break;
   1777         case SkRegion::kUnion_Op:
   1778             if (rOrig.contains(fBounds)) {
   1779                 return this->setRect(rOrig);
   1780             }
   1781             break;
   1782         default:
   1783             break;
   1784     }
   1785 
   1786     SkAAClip clip;
   1787     clip.setRect(*r);
   1788     return this->op(*this, clip, op);
   1789 }
   1790 
   1791 bool SkAAClip::op(const SkRect& rOrig, SkRegion::Op op, bool doAA) {
   1792     SkRect        rStorage, boundsStorage;
   1793     const SkRect* r = &rOrig;
   1794 
   1795     boundsStorage.set(fBounds);
   1796     switch (op) {
   1797         case SkRegion::kIntersect_Op:
   1798         case SkRegion::kDifference_Op:
   1799             if (!rStorage.intersect(rOrig, boundsStorage)) {
   1800                 if (SkRegion::kIntersect_Op == op) {
   1801                     return this->setEmpty();
   1802                 } else {    // kDifference
   1803                     return !this->isEmpty();
   1804                 }
   1805             }
   1806             r = &rStorage;   // use the intersected bounds
   1807             break;
   1808         case SkRegion::kUnion_Op:
   1809             if (rOrig.contains(boundsStorage)) {
   1810                 return this->setRect(rOrig);
   1811             }
   1812             break;
   1813         default:
   1814             break;
   1815     }
   1816 
   1817     SkAAClip clip;
   1818     clip.setRect(*r, doAA);
   1819     return this->op(*this, clip, op);
   1820 }
   1821 
   1822 bool SkAAClip::op(const SkAAClip& clip, SkRegion::Op op) {
   1823     return this->op(*this, clip, op);
   1824 }
   1825 
   1826 ///////////////////////////////////////////////////////////////////////////////
   1827 
   1828 bool SkAAClip::translate(int dx, int dy, SkAAClip* dst) const {
   1829     if (nullptr == dst) {
   1830         return !this->isEmpty();
   1831     }
   1832 
   1833     if (this->isEmpty()) {
   1834         return dst->setEmpty();
   1835     }
   1836 
   1837     if (this != dst) {
   1838         sk_atomic_inc(&fRunHead->fRefCnt);
   1839         dst->freeRuns();
   1840         dst->fRunHead = fRunHead;
   1841         dst->fBounds = fBounds;
   1842     }
   1843     dst->fBounds.offset(dx, dy);
   1844     return true;
   1845 }
   1846 
   1847 static void expand_row_to_mask(uint8_t* SK_RESTRICT mask,
   1848                                const uint8_t* SK_RESTRICT row,
   1849                                int width) {
   1850     while (width > 0) {
   1851         int n = row[0];
   1852         SkASSERT(width >= n);
   1853         memset(mask, row[1], n);
   1854         mask += n;
   1855         row += 2;
   1856         width -= n;
   1857     }
   1858     SkASSERT(0 == width);
   1859 }
   1860 
   1861 void SkAAClip::copyToMask(SkMask* mask) const {
   1862     mask->fFormat = SkMask::kA8_Format;
   1863     if (this->isEmpty()) {
   1864         mask->fBounds.setEmpty();
   1865         mask->fImage = nullptr;
   1866         mask->fRowBytes = 0;
   1867         return;
   1868     }
   1869 
   1870     mask->fBounds = fBounds;
   1871     mask->fRowBytes = fBounds.width();
   1872     size_t size = mask->computeImageSize();
   1873     mask->fImage = SkMask::AllocImage(size);
   1874 
   1875     Iter iter(*this);
   1876     uint8_t* dst = mask->fImage;
   1877     const int width = fBounds.width();
   1878 
   1879     int y = fBounds.fTop;
   1880     while (!iter.done()) {
   1881         do {
   1882             expand_row_to_mask(dst, iter.data(), width);
   1883             dst += mask->fRowBytes;
   1884         } while (++y < iter.bottom());
   1885         iter.next();
   1886     }
   1887 }
   1888 
   1889 ///////////////////////////////////////////////////////////////////////////////
   1890 ///////////////////////////////////////////////////////////////////////////////
   1891 
   1892 static void expandToRuns(const uint8_t* SK_RESTRICT data, int initialCount, int width,
   1893                          int16_t* SK_RESTRICT runs, SkAlpha* SK_RESTRICT aa) {
   1894     // we don't read our initial n from data, since the caller may have had to
   1895     // clip it, hence the initialCount parameter.
   1896     int n = initialCount;
   1897     for (;;) {
   1898         if (n > width) {
   1899             n = width;
   1900         }
   1901         SkASSERT(n > 0);
   1902         runs[0] = n;
   1903         runs += n;
   1904 
   1905         aa[0] = data[1];
   1906         aa += n;
   1907 
   1908         data += 2;
   1909         width -= n;
   1910         if (0 == width) {
   1911             break;
   1912         }
   1913         // load the next count
   1914         n = data[0];
   1915     }
   1916     runs[0] = 0;    // sentinel
   1917 }
   1918 
   1919 SkAAClipBlitter::~SkAAClipBlitter() {
   1920     sk_free(fScanlineScratch);
   1921 }
   1922 
   1923 void SkAAClipBlitter::ensureRunsAndAA() {
   1924     if (nullptr == fScanlineScratch) {
   1925         // add 1 so we can store the terminating run count of 0
   1926         int count = fAAClipBounds.width() + 1;
   1927         // we use this either for fRuns + fAA, or a scaline of a mask
   1928         // which may be as deep as 32bits
   1929         fScanlineScratch = sk_malloc_throw(count * sizeof(SkPMColor));
   1930         fRuns = (int16_t*)fScanlineScratch;
   1931         fAA = (SkAlpha*)(fRuns + count);
   1932     }
   1933 }
   1934 
   1935 void SkAAClipBlitter::blitH(int x, int y, int width) {
   1936     SkASSERT(width > 0);
   1937     SkASSERT(fAAClipBounds.contains(x, y));
   1938     SkASSERT(fAAClipBounds.contains(x + width  - 1, y));
   1939 
   1940     const uint8_t* row = fAAClip->findRow(y);
   1941     int initialCount;
   1942     row = fAAClip->findX(row, x, &initialCount);
   1943 
   1944     if (initialCount >= width) {
   1945         SkAlpha alpha = row[1];
   1946         if (0 == alpha) {
   1947             return;
   1948         }
   1949         if (0xFF == alpha) {
   1950             fBlitter->blitH(x, y, width);
   1951             return;
   1952         }
   1953     }
   1954 
   1955     this->ensureRunsAndAA();
   1956     expandToRuns(row, initialCount, width, fRuns, fAA);
   1957 
   1958     fBlitter->blitAntiH(x, y, fAA, fRuns);
   1959 }
   1960 
   1961 static void merge(const uint8_t* SK_RESTRICT row, int rowN,
   1962                   const SkAlpha* SK_RESTRICT srcAA,
   1963                   const int16_t* SK_RESTRICT srcRuns,
   1964                   SkAlpha* SK_RESTRICT dstAA,
   1965                   int16_t* SK_RESTRICT dstRuns,
   1966                   int width) {
   1967     SkDEBUGCODE(int accumulated = 0;)
   1968     int srcN = srcRuns[0];
   1969     // do we need this check?
   1970     if (0 == srcN) {
   1971         return;
   1972     }
   1973 
   1974     for (;;) {
   1975         SkASSERT(rowN > 0);
   1976         SkASSERT(srcN > 0);
   1977 
   1978         unsigned newAlpha = SkMulDiv255Round(srcAA[0], row[1]);
   1979         int minN = SkMin32(srcN, rowN);
   1980         dstRuns[0] = minN;
   1981         dstRuns += minN;
   1982         dstAA[0] = newAlpha;
   1983         dstAA += minN;
   1984 
   1985         if (0 == (srcN -= minN)) {
   1986             srcN = srcRuns[0];  // refresh
   1987             srcRuns += srcN;
   1988             srcAA += srcN;
   1989             srcN = srcRuns[0];  // reload
   1990             if (0 == srcN) {
   1991                 break;
   1992             }
   1993         }
   1994         if (0 == (rowN -= minN)) {
   1995             row += 2;
   1996             rowN = row[0];  // reload
   1997         }
   1998 
   1999         SkDEBUGCODE(accumulated += minN;)
   2000         SkASSERT(accumulated <= width);
   2001     }
   2002     dstRuns[0] = 0;
   2003 }
   2004 
   2005 void SkAAClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
   2006                                 const int16_t runs[]) {
   2007 
   2008     const uint8_t* row = fAAClip->findRow(y);
   2009     int initialCount;
   2010     row = fAAClip->findX(row, x, &initialCount);
   2011 
   2012     this->ensureRunsAndAA();
   2013 
   2014     merge(row, initialCount, aa, runs, fAA, fRuns, fAAClipBounds.width());
   2015     fBlitter->blitAntiH(x, y, fAA, fRuns);
   2016 }
   2017 
   2018 void SkAAClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
   2019     if (fAAClip->quickContains(x, y, x + 1, y + height)) {
   2020         fBlitter->blitV(x, y, height, alpha);
   2021         return;
   2022     }
   2023 
   2024     for (;;) {
   2025         int lastY SK_INIT_TO_AVOID_WARNING;
   2026         const uint8_t* row = fAAClip->findRow(y, &lastY);
   2027         int dy = lastY - y + 1;
   2028         if (dy > height) {
   2029             dy = height;
   2030         }
   2031         height -= dy;
   2032 
   2033         row = fAAClip->findX(row, x);
   2034         SkAlpha newAlpha = SkMulDiv255Round(alpha, row[1]);
   2035         if (newAlpha) {
   2036             fBlitter->blitV(x, y, dy, newAlpha);
   2037         }
   2038         SkASSERT(height >= 0);
   2039         if (height <= 0) {
   2040             break;
   2041         }
   2042         y = lastY + 1;
   2043     }
   2044 }
   2045 
   2046 void SkAAClipBlitter::blitRect(int x, int y, int width, int height) {
   2047     if (fAAClip->quickContains(x, y, x + width, y + height)) {
   2048         fBlitter->blitRect(x, y, width, height);
   2049         return;
   2050     }
   2051 
   2052     while (--height >= 0) {
   2053         this->blitH(x, y, width);
   2054         y += 1;
   2055     }
   2056 }
   2057 
   2058 typedef void (*MergeAAProc)(const void* src, int width, const uint8_t* row,
   2059                             int initialRowCount, void* dst);
   2060 
   2061 static void small_memcpy(void* dst, const void* src, size_t n) {
   2062     memcpy(dst, src, n);
   2063 }
   2064 
   2065 static void small_bzero(void* dst, size_t n) {
   2066     sk_bzero(dst, n);
   2067 }
   2068 
   2069 static inline uint8_t mergeOne(uint8_t value, unsigned alpha) {
   2070     return SkMulDiv255Round(value, alpha);
   2071 }
   2072 
   2073 static inline uint16_t mergeOne(uint16_t value, unsigned alpha) {
   2074     unsigned r = SkGetPackedR16(value);
   2075     unsigned g = SkGetPackedG16(value);
   2076     unsigned b = SkGetPackedB16(value);
   2077     return SkPackRGB16(SkMulDiv255Round(r, alpha),
   2078                        SkMulDiv255Round(g, alpha),
   2079                        SkMulDiv255Round(b, alpha));
   2080 }
   2081 
   2082 template <typename T>
   2083 void mergeT(const void* inSrc, int srcN, const uint8_t* SK_RESTRICT row, int rowN, void* inDst) {
   2084     const T* SK_RESTRICT src = static_cast<const T*>(inSrc);
   2085     T* SK_RESTRICT       dst = static_cast<T*>(inDst);
   2086     for (;;) {
   2087         SkASSERT(rowN > 0);
   2088         SkASSERT(srcN > 0);
   2089 
   2090         int n = SkMin32(rowN, srcN);
   2091         unsigned rowA = row[1];
   2092         if (0xFF == rowA) {
   2093             small_memcpy(dst, src, n * sizeof(T));
   2094         } else if (0 == rowA) {
   2095             small_bzero(dst, n * sizeof(T));
   2096         } else {
   2097             for (int i = 0; i < n; ++i) {
   2098                 dst[i] = mergeOne(src[i], rowA);
   2099             }
   2100         }
   2101 
   2102         if (0 == (srcN -= n)) {
   2103             break;
   2104         }
   2105 
   2106         src += n;
   2107         dst += n;
   2108 
   2109         SkASSERT(rowN == n);
   2110         row += 2;
   2111         rowN = row[0];
   2112     }
   2113 }
   2114 
   2115 static MergeAAProc find_merge_aa_proc(SkMask::Format format) {
   2116     switch (format) {
   2117         case SkMask::kBW_Format:
   2118             SkDEBUGFAIL("unsupported");
   2119             return nullptr;
   2120         case SkMask::kA8_Format:
   2121         case SkMask::k3D_Format:
   2122             return mergeT<uint8_t> ;
   2123         case SkMask::kLCD16_Format:
   2124             return mergeT<uint16_t>;
   2125         default:
   2126             SkDEBUGFAIL("unsupported");
   2127             return nullptr;
   2128     }
   2129 }
   2130 
   2131 static U8CPU bit2byte(int bitInAByte) {
   2132     SkASSERT(bitInAByte <= 0xFF);
   2133     // negation turns any non-zero into 0xFFFFFF??, so we just shift down
   2134     // some value >= 8 to get a full FF value
   2135     return -bitInAByte >> 8;
   2136 }
   2137 
   2138 static void upscaleBW2A8(SkMask* dstMask, const SkMask& srcMask) {
   2139     SkASSERT(SkMask::kBW_Format == srcMask.fFormat);
   2140     SkASSERT(SkMask::kA8_Format == dstMask->fFormat);
   2141 
   2142     const int width = srcMask.fBounds.width();
   2143     const int height = srcMask.fBounds.height();
   2144 
   2145     const uint8_t* SK_RESTRICT src = (const uint8_t*)srcMask.fImage;
   2146     const size_t srcRB = srcMask.fRowBytes;
   2147     uint8_t* SK_RESTRICT dst = (uint8_t*)dstMask->fImage;
   2148     const size_t dstRB = dstMask->fRowBytes;
   2149 
   2150     const int wholeBytes = width >> 3;
   2151     const int leftOverBits = width & 7;
   2152 
   2153     for (int y = 0; y < height; ++y) {
   2154         uint8_t* SK_RESTRICT d = dst;
   2155         for (int i = 0; i < wholeBytes; ++i) {
   2156             int srcByte = src[i];
   2157             d[0] = bit2byte(srcByte & (1 << 7));
   2158             d[1] = bit2byte(srcByte & (1 << 6));
   2159             d[2] = bit2byte(srcByte & (1 << 5));
   2160             d[3] = bit2byte(srcByte & (1 << 4));
   2161             d[4] = bit2byte(srcByte & (1 << 3));
   2162             d[5] = bit2byte(srcByte & (1 << 2));
   2163             d[6] = bit2byte(srcByte & (1 << 1));
   2164             d[7] = bit2byte(srcByte & (1 << 0));
   2165             d += 8;
   2166         }
   2167         if (leftOverBits) {
   2168             int srcByte = src[wholeBytes];
   2169             for (int x = 0; x < leftOverBits; ++x) {
   2170                 *d++ = bit2byte(srcByte & 0x80);
   2171                 srcByte <<= 1;
   2172             }
   2173         }
   2174         src += srcRB;
   2175         dst += dstRB;
   2176     }
   2177 }
   2178 
   2179 void SkAAClipBlitter::blitMask(const SkMask& origMask, const SkIRect& clip) {
   2180     SkASSERT(fAAClip->getBounds().contains(clip));
   2181 
   2182     if (fAAClip->quickContains(clip)) {
   2183         fBlitter->blitMask(origMask, clip);
   2184         return;
   2185     }
   2186 
   2187     const SkMask* mask = &origMask;
   2188 
   2189     // if we're BW, we need to upscale to A8 (ugh)
   2190     SkMask  grayMask;
   2191     if (SkMask::kBW_Format == origMask.fFormat) {
   2192         grayMask.fFormat = SkMask::kA8_Format;
   2193         grayMask.fBounds = origMask.fBounds;
   2194         grayMask.fRowBytes = origMask.fBounds.width();
   2195         size_t size = grayMask.computeImageSize();
   2196         grayMask.fImage = (uint8_t*)fGrayMaskScratch.reset(size,
   2197                                                SkAutoMalloc::kReuse_OnShrink);
   2198 
   2199         upscaleBW2A8(&grayMask, origMask);
   2200         mask = &grayMask;
   2201     }
   2202 
   2203     this->ensureRunsAndAA();
   2204 
   2205     // HACK -- we are devolving 3D into A8, need to copy the rest of the 3D
   2206     // data into a temp block to support it better (ugh)
   2207 
   2208     const void* src = mask->getAddr(clip.fLeft, clip.fTop);
   2209     const size_t srcRB = mask->fRowBytes;
   2210     const int width = clip.width();
   2211     MergeAAProc mergeProc = find_merge_aa_proc(mask->fFormat);
   2212 
   2213     SkMask rowMask;
   2214     rowMask.fFormat = SkMask::k3D_Format == mask->fFormat ? SkMask::kA8_Format : mask->fFormat;
   2215     rowMask.fBounds.fLeft = clip.fLeft;
   2216     rowMask.fBounds.fRight = clip.fRight;
   2217     rowMask.fRowBytes = mask->fRowBytes; // doesn't matter, since our height==1
   2218     rowMask.fImage = (uint8_t*)fScanlineScratch;
   2219 
   2220     int y = clip.fTop;
   2221     const int stopY = y + clip.height();
   2222 
   2223     do {
   2224         int localStopY SK_INIT_TO_AVOID_WARNING;
   2225         const uint8_t* row = fAAClip->findRow(y, &localStopY);
   2226         // findRow returns last Y, not stop, so we add 1
   2227         localStopY = SkMin32(localStopY + 1, stopY);
   2228 
   2229         int initialCount;
   2230         row = fAAClip->findX(row, clip.fLeft, &initialCount);
   2231         do {
   2232             mergeProc(src, width, row, initialCount, rowMask.fImage);
   2233             rowMask.fBounds.fTop = y;
   2234             rowMask.fBounds.fBottom = y + 1;
   2235             fBlitter->blitMask(rowMask, rowMask.fBounds);
   2236             src = (const void*)((const char*)src + srcRB);
   2237         } while (++y < localStopY);
   2238     } while (y < stopY);
   2239 }
   2240 
   2241 const SkPixmap* SkAAClipBlitter::justAnOpaqueColor(uint32_t* value) {
   2242     return nullptr;
   2243 }
   2244