Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2006 The Android Open Source Project
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkBlitter.h"
      9 #include "SkAntiRun.h"
     10 #include "SkColor.h"
     11 #include "SkColorFilter.h"
     12 #include "SkCoreBlitters.h"
     13 #include "SkFilterShader.h"
     14 #include "SkReadBuffer.h"
     15 #include "SkWriteBuffer.h"
     16 #include "SkMask.h"
     17 #include "SkMaskFilter.h"
     18 #include "SkString.h"
     19 #include "SkTLazy.h"
     20 #include "SkUtils.h"
     21 #include "SkXfermode.h"
     22 #include "SkXfermodeInterpretation.h"
     23 
     24 SkBlitter::~SkBlitter() {}
     25 
     26 bool SkBlitter::isNullBlitter() const { return false; }
     27 
     28 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) {
     29     return true;
     30 }
     31 
     32 SkShader::Context* SkBlitter::getShaderContext() const {
     33     return NULL;
     34 }
     35 
     36 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
     37     return NULL;
     38 }
     39 
     40 void SkBlitter::blitH(int x, int y, int width) {
     41     SkDEBUGFAIL("unimplemented");
     42 }
     43 
     44 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     45                           const int16_t runs[]) {
     46     SkDEBUGFAIL("unimplemented");
     47 }
     48 
     49 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
     50     if (alpha == 255) {
     51         this->blitRect(x, y, 1, height);
     52     } else {
     53         int16_t runs[2];
     54         runs[0] = 1;
     55         runs[1] = 0;
     56 
     57         while (--height >= 0) {
     58             this->blitAntiH(x, y++, &alpha, runs);
     59         }
     60     }
     61 }
     62 
     63 void SkBlitter::blitRect(int x, int y, int width, int height) {
     64     SkASSERT(width > 0);
     65     while (--height >= 0) {
     66         this->blitH(x, y++, width);
     67     }
     68 }
     69 
     70 /// Default implementation doesn't check for any easy optimizations
     71 /// such as alpha == 0 or 255; also uses blitV(), which some subclasses
     72 /// may not support.
     73 void SkBlitter::blitAntiRect(int x, int y, int width, int height,
     74                              SkAlpha leftAlpha, SkAlpha rightAlpha) {
     75     this->blitV(x++, y, height, leftAlpha);
     76     if (width > 0) {
     77         this->blitRect(x, y, width, height);
     78         x += width;
     79     }
     80     this->blitV(x, y, height, rightAlpha);
     81 }
     82 
     83 //////////////////////////////////////////////////////////////////////////////
     84 
     85 static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
     86                                 const uint8_t bits[],
     87                                 U8CPU left_mask, int rowBytes,
     88                                 U8CPU right_mask) {
     89     int inFill = 0;
     90     int pos = 0;
     91 
     92     while (--rowBytes >= 0) {
     93         unsigned b = *bits++ & left_mask;
     94         if (rowBytes == 0) {
     95             b &= right_mask;
     96         }
     97 
     98         for (unsigned test = 0x80; test != 0; test >>= 1) {
     99             if (b & test) {
    100                 if (!inFill) {
    101                     pos = x;
    102                     inFill = true;
    103                 }
    104             } else {
    105                 if (inFill) {
    106                     blitter->blitH(pos, y, x - pos);
    107                     inFill = false;
    108                 }
    109             }
    110             x += 1;
    111         }
    112         left_mask = 0xFF;
    113     }
    114 
    115     // final cleanup
    116     if (inFill) {
    117         blitter->blitH(pos, y, x - pos);
    118     }
    119 }
    120 
    121 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    122     SkASSERT(mask.fBounds.contains(clip));
    123 
    124     if (mask.fFormat == SkMask::kBW_Format) {
    125         int cx = clip.fLeft;
    126         int cy = clip.fTop;
    127         int maskLeft = mask.fBounds.fLeft;
    128         int mask_rowBytes = mask.fRowBytes;
    129         int height = clip.height();
    130 
    131         const uint8_t* bits = mask.getAddr1(cx, cy);
    132 
    133         if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
    134             while (--height >= 0) {
    135                 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
    136                 bits += mask_rowBytes;
    137                 cy += 1;
    138             }
    139         } else {
    140             int left_edge = cx - maskLeft;
    141             SkASSERT(left_edge >= 0);
    142             int rite_edge = clip.fRight - maskLeft;
    143             SkASSERT(rite_edge > left_edge);
    144 
    145             int left_mask = 0xFF >> (left_edge & 7);
    146             int rite_mask = 0xFF << (8 - (rite_edge & 7));
    147             int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
    148 
    149             // check for empty right mask, so we don't read off the end (or go slower than we need to)
    150             if (rite_mask == 0) {
    151                 SkASSERT(full_runs >= 0);
    152                 full_runs -= 1;
    153                 rite_mask = 0xFF;
    154             }
    155             if (left_mask == 0xFF) {
    156                 full_runs -= 1;
    157             }
    158 
    159             // back up manually so we can keep in sync with our byte-aligned src
    160             // have cx reflect our actual starting x-coord
    161             cx -= left_edge & 7;
    162 
    163             if (full_runs < 0) {
    164                 SkASSERT((left_mask & rite_mask) != 0);
    165                 while (--height >= 0) {
    166                     bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
    167                     bits += mask_rowBytes;
    168                     cy += 1;
    169                 }
    170             } else {
    171                 while (--height >= 0) {
    172                     bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
    173                     bits += mask_rowBytes;
    174                     cy += 1;
    175                 }
    176             }
    177         }
    178     } else {
    179         int                         width = clip.width();
    180         SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
    181         int16_t*                    runs = runStorage.get();
    182         const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
    183 
    184         sk_memset16((uint16_t*)runs, 1, width);
    185         runs[width] = 0;
    186 
    187         int height = clip.height();
    188         int y = clip.fTop;
    189         while (--height >= 0) {
    190             this->blitAntiH(clip.fLeft, y, aa, runs);
    191             aa += mask.fRowBytes;
    192             y += 1;
    193         }
    194     }
    195 }
    196 
    197 /////////////////////// these guys are not virtual, just a helpers
    198 
    199 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
    200     if (clip.quickReject(mask.fBounds)) {
    201         return;
    202     }
    203 
    204     SkRegion::Cliperator clipper(clip, mask.fBounds);
    205 
    206     while (!clipper.done()) {
    207         const SkIRect& cr = clipper.rect();
    208         this->blitMask(mask, cr);
    209         clipper.next();
    210     }
    211 }
    212 
    213 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
    214     SkRegion::Cliperator clipper(clip, rect);
    215 
    216     while (!clipper.done()) {
    217         const SkIRect& cr = clipper.rect();
    218         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
    219         clipper.next();
    220     }
    221 }
    222 
    223 void SkBlitter::blitRegion(const SkRegion& clip) {
    224     SkRegion::Iterator iter(clip);
    225 
    226     while (!iter.done()) {
    227         const SkIRect& cr = iter.rect();
    228         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
    229         iter.next();
    230     }
    231 }
    232 
    233 ///////////////////////////////////////////////////////////////////////////////
    234 
    235 void SkNullBlitter::blitH(int x, int y, int width) {}
    236 
    237 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
    238                               const int16_t runs[]) {}
    239 
    240 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
    241 
    242 void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
    243 
    244 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
    245 
    246 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
    247     return NULL;
    248 }
    249 
    250 bool SkNullBlitter::isNullBlitter() const { return true; }
    251 
    252 ///////////////////////////////////////////////////////////////////////////////
    253 
    254 static int compute_anti_width(const int16_t runs[]) {
    255     int width = 0;
    256 
    257     for (;;) {
    258         int count = runs[0];
    259 
    260         SkASSERT(count >= 0);
    261         if (count == 0) {
    262             break;
    263         }
    264         width += count;
    265         runs += count;
    266     }
    267     return width;
    268 }
    269 
    270 static inline bool y_in_rect(int y, const SkIRect& rect) {
    271     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
    272 }
    273 
    274 static inline bool x_in_rect(int x, const SkIRect& rect) {
    275     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
    276 }
    277 
    278 void SkRectClipBlitter::blitH(int left, int y, int width) {
    279     SkASSERT(width > 0);
    280 
    281     if (!y_in_rect(y, fClipRect)) {
    282         return;
    283     }
    284 
    285     int right = left + width;
    286 
    287     if (left < fClipRect.fLeft) {
    288         left = fClipRect.fLeft;
    289     }
    290     if (right > fClipRect.fRight) {
    291         right = fClipRect.fRight;
    292     }
    293 
    294     width = right - left;
    295     if (width > 0) {
    296         fBlitter->blitH(left, y, width);
    297     }
    298 }
    299 
    300 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
    301                                   const int16_t runs[]) {
    302     if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
    303         return;
    304     }
    305 
    306     int x0 = left;
    307     int x1 = left + compute_anti_width(runs);
    308 
    309     if (x1 <= fClipRect.fLeft) {
    310         return;
    311     }
    312 
    313     SkASSERT(x0 < x1);
    314     if (x0 < fClipRect.fLeft) {
    315         int dx = fClipRect.fLeft - x0;
    316         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
    317         runs += dx;
    318         aa += dx;
    319         x0 = fClipRect.fLeft;
    320     }
    321 
    322     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
    323     if (x1 > fClipRect.fRight) {
    324         x1 = fClipRect.fRight;
    325         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
    326         ((int16_t*)runs)[x1 - x0] = 0;
    327     }
    328 
    329     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
    330     SkASSERT(compute_anti_width(runs) == x1 - x0);
    331 
    332     fBlitter->blitAntiH(x0, y, aa, runs);
    333 }
    334 
    335 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
    336     SkASSERT(height > 0);
    337 
    338     if (!x_in_rect(x, fClipRect)) {
    339         return;
    340     }
    341 
    342     int y0 = y;
    343     int y1 = y + height;
    344 
    345     if (y0 < fClipRect.fTop) {
    346         y0 = fClipRect.fTop;
    347     }
    348     if (y1 > fClipRect.fBottom) {
    349         y1 = fClipRect.fBottom;
    350     }
    351 
    352     if (y0 < y1) {
    353         fBlitter->blitV(x, y0, y1 - y0, alpha);
    354     }
    355 }
    356 
    357 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
    358     SkIRect    r;
    359 
    360     r.set(left, y, left + width, y + height);
    361     if (r.intersect(fClipRect)) {
    362         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
    363     }
    364 }
    365 
    366 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
    367                                      SkAlpha leftAlpha, SkAlpha rightAlpha) {
    368     SkIRect    r;
    369 
    370     // The *true* width of the rectangle blitted is width+2:
    371     r.set(left, y, left + width + 2, y + height);
    372     if (r.intersect(fClipRect)) {
    373         if (r.fLeft != left) {
    374             SkASSERT(r.fLeft > left);
    375             leftAlpha = 255;
    376         }
    377         if (r.fRight != left + width + 2) {
    378             SkASSERT(r.fRight < left + width + 2);
    379             rightAlpha = 255;
    380         }
    381         if (255 == leftAlpha && 255 == rightAlpha) {
    382             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
    383         } else if (1 == r.width()) {
    384             if (r.fLeft == left) {
    385                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
    386             } else {
    387                 SkASSERT(r.fLeft == left + width + 1);
    388                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
    389             }
    390         } else {
    391             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
    392                                    leftAlpha, rightAlpha);
    393         }
    394     }
    395 }
    396 
    397 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    398     SkASSERT(mask.fBounds.contains(clip));
    399 
    400     SkIRect    r = clip;
    401 
    402     if (r.intersect(fClipRect)) {
    403         fBlitter->blitMask(mask, r);
    404     }
    405 }
    406 
    407 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
    408     return fBlitter->justAnOpaqueColor(value);
    409 }
    410 
    411 ///////////////////////////////////////////////////////////////////////////////
    412 
    413 void SkRgnClipBlitter::blitH(int x, int y, int width) {
    414     SkRegion::Spanerator span(*fRgn, y, x, x + width);
    415     int left, right;
    416 
    417     while (span.next(&left, &right)) {
    418         SkASSERT(left < right);
    419         fBlitter->blitH(left, y, right - left);
    420     }
    421 }
    422 
    423 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
    424                                  const int16_t runs[]) {
    425     int width = compute_anti_width(runs);
    426     SkRegion::Spanerator span(*fRgn, y, x, x + width);
    427     int left, right;
    428     SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
    429 
    430     int prevRite = x;
    431     while (span.next(&left, &right)) {
    432         SkASSERT(x <= left);
    433         SkASSERT(left < right);
    434         SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
    435 
    436         SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
    437 
    438         // now zero before left
    439         if (left > prevRite) {
    440             int index = prevRite - x;
    441             ((uint8_t*)aa)[index] = 0;   // skip runs after right
    442             ((int16_t*)runs)[index] = SkToS16(left - prevRite);
    443         }
    444 
    445         prevRite = right;
    446     }
    447 
    448     if (prevRite > x) {
    449         ((int16_t*)runs)[prevRite - x] = 0;
    450 
    451         if (x < 0) {
    452             int skip = runs[0];
    453             SkASSERT(skip >= -x);
    454             aa += skip;
    455             runs += skip;
    456             x += skip;
    457         }
    458         fBlitter->blitAntiH(x, y, aa, runs);
    459     }
    460 }
    461 
    462 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
    463     SkIRect    bounds;
    464     bounds.set(x, y, x + 1, y + height);
    465 
    466     SkRegion::Cliperator    iter(*fRgn, bounds);
    467 
    468     while (!iter.done()) {
    469         const SkIRect& r = iter.rect();
    470         SkASSERT(bounds.contains(r));
    471 
    472         fBlitter->blitV(x, r.fTop, r.height(), alpha);
    473         iter.next();
    474     }
    475 }
    476 
    477 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
    478     SkIRect    bounds;
    479     bounds.set(x, y, x + width, y + height);
    480 
    481     SkRegion::Cliperator    iter(*fRgn, bounds);
    482 
    483     while (!iter.done()) {
    484         const SkIRect& r = iter.rect();
    485         SkASSERT(bounds.contains(r));
    486 
    487         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
    488         iter.next();
    489     }
    490 }
    491 
    492 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
    493                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
    494     // The *true* width of the rectangle to blit is width + 2
    495     SkIRect    bounds;
    496     bounds.set(x, y, x + width + 2, y + height);
    497 
    498     SkRegion::Cliperator    iter(*fRgn, bounds);
    499 
    500     while (!iter.done()) {
    501         const SkIRect& r = iter.rect();
    502         SkASSERT(bounds.contains(r));
    503         SkASSERT(r.fLeft >= x);
    504         SkASSERT(r.fRight <= x + width + 2);
    505 
    506         SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
    507         SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
    508                                       rightAlpha : 255;
    509 
    510         if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
    511             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
    512         } else if (1 == r.width()) {
    513             if (r.fLeft == x) {
    514                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
    515                                 effectiveLeftAlpha);
    516             } else {
    517                 SkASSERT(r.fLeft == x + width + 1);
    518                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
    519                                 effectiveRightAlpha);
    520             }
    521         } else {
    522             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
    523                                    effectiveLeftAlpha, effectiveRightAlpha);
    524         }
    525         iter.next();
    526     }
    527 }
    528 
    529 
    530 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
    531     SkASSERT(mask.fBounds.contains(clip));
    532 
    533     SkRegion::Cliperator iter(*fRgn, clip);
    534     const SkIRect&       r = iter.rect();
    535     SkBlitter*           blitter = fBlitter;
    536 
    537     while (!iter.done()) {
    538         blitter->blitMask(mask, r);
    539         iter.next();
    540     }
    541 }
    542 
    543 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
    544     return fBlitter->justAnOpaqueColor(value);
    545 }
    546 
    547 ///////////////////////////////////////////////////////////////////////////////
    548 
    549 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
    550                                    const SkIRect* ir) {
    551     if (clip) {
    552         const SkIRect& clipR = clip->getBounds();
    553 
    554         if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
    555             blitter = &fNullBlitter;
    556         } else if (clip->isRect()) {
    557             if (ir == NULL || !clipR.contains(*ir)) {
    558                 fRectBlitter.init(blitter, clipR);
    559                 blitter = &fRectBlitter;
    560             }
    561         } else {
    562             fRgnBlitter.init(blitter, clip);
    563             blitter = &fRgnBlitter;
    564         }
    565     }
    566     return blitter;
    567 }
    568 
    569 ///////////////////////////////////////////////////////////////////////////////
    570 
    571 #include "SkColorShader.h"
    572 #include "SkColorPriv.h"
    573 
    574 class Sk3DShader : public SkShader {
    575 public:
    576     Sk3DShader(SkShader* proxy) : fProxy(proxy) {
    577         SkSafeRef(proxy);
    578     }
    579 
    580     virtual ~Sk3DShader() {
    581         SkSafeUnref(fProxy);
    582     }
    583 
    584     size_t contextSize() const override {
    585         size_t size = sizeof(Sk3DShaderContext);
    586         if (fProxy) {
    587             size += fProxy->contextSize();
    588         }
    589         return size;
    590     }
    591 
    592     Context* onCreateContext(const ContextRec& rec, void* storage) const override {
    593         SkShader::Context* proxyContext = NULL;
    594         if (fProxy) {
    595             char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
    596             proxyContext = fProxy->createContext(rec, proxyContextStorage);
    597             if (!proxyContext) {
    598                 return NULL;
    599             }
    600         }
    601         return SkNEW_PLACEMENT_ARGS(storage, Sk3DShaderContext, (*this, rec, proxyContext));
    602     }
    603 
    604     class Sk3DShaderContext : public SkShader::Context {
    605     public:
    606         // Calls proxyContext's destructor but will NOT free its memory.
    607         Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
    608                           SkShader::Context* proxyContext)
    609             : INHERITED(shader, rec)
    610             , fMask(NULL)
    611             , fProxyContext(proxyContext)
    612         {
    613             if (!fProxyContext) {
    614                 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
    615             }
    616         }
    617 
    618         virtual ~Sk3DShaderContext() {
    619             if (fProxyContext) {
    620                 fProxyContext->~Context();
    621             }
    622         }
    623 
    624         void set3DMask(const SkMask* mask) override { fMask = mask; }
    625 
    626         void shadeSpan(int x, int y, SkPMColor span[], int count) override {
    627             if (fProxyContext) {
    628                 fProxyContext->shadeSpan(x, y, span, count);
    629             }
    630 
    631             if (fMask == NULL) {
    632                 if (fProxyContext == NULL) {
    633                     sk_memset32(span, fPMColor, count);
    634                 }
    635                 return;
    636             }
    637 
    638             SkASSERT(fMask->fBounds.contains(x, y));
    639             SkASSERT(fMask->fBounds.contains(x + count - 1, y));
    640 
    641             size_t          size = fMask->computeImageSize();
    642             const uint8_t*  alpha = fMask->getAddr8(x, y);
    643             const uint8_t*  mulp = alpha + size;
    644             const uint8_t*  addp = mulp + size;
    645 
    646             if (fProxyContext) {
    647                 for (int i = 0; i < count; i++) {
    648                     if (alpha[i]) {
    649                         SkPMColor c = span[i];
    650                         if (c) {
    651                             unsigned a = SkGetPackedA32(c);
    652                             unsigned r = SkGetPackedR32(c);
    653                             unsigned g = SkGetPackedG32(c);
    654                             unsigned b = SkGetPackedB32(c);
    655 
    656                             unsigned mul = SkAlpha255To256(mulp[i]);
    657                             unsigned add = addp[i];
    658 
    659                             r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
    660                             g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
    661                             b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
    662 
    663                             span[i] = SkPackARGB32(a, r, g, b);
    664                         }
    665                     } else {
    666                         span[i] = 0;
    667                     }
    668                 }
    669             } else {    // color
    670                 unsigned a = SkGetPackedA32(fPMColor);
    671                 unsigned r = SkGetPackedR32(fPMColor);
    672                 unsigned g = SkGetPackedG32(fPMColor);
    673                 unsigned b = SkGetPackedB32(fPMColor);
    674                 for (int i = 0; i < count; i++) {
    675                     if (alpha[i]) {
    676                         unsigned mul = SkAlpha255To256(mulp[i]);
    677                         unsigned add = addp[i];
    678 
    679                         span[i] = SkPackARGB32( a,
    680                                         SkFastMin32(SkAlphaMul(r, mul) + add, a),
    681                                         SkFastMin32(SkAlphaMul(g, mul) + add, a),
    682                                         SkFastMin32(SkAlphaMul(b, mul) + add, a));
    683                     } else {
    684                         span[i] = 0;
    685                     }
    686                 }
    687             }
    688         }
    689 
    690     private:
    691         // Unowned.
    692         const SkMask*       fMask;
    693         // Memory is unowned, but we need to call the destructor.
    694         SkShader::Context*  fProxyContext;
    695         SkPMColor           fPMColor;
    696 
    697         typedef SkShader::Context INHERITED;
    698     };
    699 
    700 #ifndef SK_IGNORE_TO_STRING
    701     void toString(SkString* str) const override {
    702         str->append("Sk3DShader: (");
    703 
    704         if (fProxy) {
    705             str->append("Proxy: ");
    706             fProxy->toString(str);
    707         }
    708 
    709         this->INHERITED::toString(str);
    710 
    711         str->append(")");
    712     }
    713 #endif
    714 
    715     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
    716 
    717 protected:
    718     void flatten(SkWriteBuffer& buffer) const override {
    719         buffer.writeFlattenable(fProxy);
    720     }
    721 
    722 private:
    723     SkShader*       fProxy;
    724 
    725     typedef SkShader INHERITED;
    726 };
    727 
    728 SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) {
    729     SkAutoTUnref<SkShader> shader(buffer.readShader());
    730     return SkNEW_ARGS(Sk3DShader, (shader));
    731 }
    732 
    733 class Sk3DBlitter : public SkBlitter {
    734 public:
    735     Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
    736         : fProxy(proxy)
    737         , fShaderContext(shaderContext)
    738     {}
    739 
    740     void blitH(int x, int y, int width) override {
    741         fProxy->blitH(x, y, width);
    742     }
    743 
    744     virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
    745                            const int16_t runs[]) override {
    746         fProxy->blitAntiH(x, y, antialias, runs);
    747     }
    748 
    749     void blitV(int x, int y, int height, SkAlpha alpha) override {
    750         fProxy->blitV(x, y, height, alpha);
    751     }
    752 
    753     void blitRect(int x, int y, int width, int height) override {
    754         fProxy->blitRect(x, y, width, height);
    755     }
    756 
    757     void blitMask(const SkMask& mask, const SkIRect& clip) override {
    758         if (mask.fFormat == SkMask::k3D_Format) {
    759             fShaderContext->set3DMask(&mask);
    760 
    761             ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
    762             fProxy->blitMask(mask, clip);
    763             ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
    764 
    765             fShaderContext->set3DMask(NULL);
    766         } else {
    767             fProxy->blitMask(mask, clip);
    768         }
    769     }
    770 
    771 private:
    772     // Both pointers are unowned. They will be deleted by SkSmallAllocator.
    773     SkBlitter*          fProxy;
    774     SkShader::Context*  fShaderContext;
    775 };
    776 
    777 ///////////////////////////////////////////////////////////////////////////////
    778 
    779 #include "SkCoreBlitters.h"
    780 
    781 SkBlitter* SkBlitter::Choose(const SkBitmap& device,
    782                              const SkMatrix& matrix,
    783                              const SkPaint& origPaint,
    784                              SkTBlitterAllocator* allocator,
    785                              bool drawCoverage) {
    786     SkASSERT(allocator != NULL);
    787 
    788     // which check, in case we're being called by a client with a dummy device
    789     // (e.g. they have a bounder that always aborts the draw)
    790     if (kUnknown_SkColorType == device.colorType() ||
    791             (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
    792         return allocator->createT<SkNullBlitter>();
    793     }
    794 
    795     SkShader* shader = origPaint.getShader();
    796     SkColorFilter* cf = origPaint.getColorFilter();
    797     SkXfermode* mode = origPaint.getXfermode();
    798     Sk3DShader* shader3D = NULL;
    799 
    800     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
    801 
    802     if (origPaint.getMaskFilter() != NULL &&
    803             origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
    804         shader3D = SkNEW_ARGS(Sk3DShader, (shader));
    805         // we know we haven't initialized lazyPaint yet, so just do it
    806         paint.writable()->setShader(shader3D)->unref();
    807         shader = shader3D;
    808     }
    809 
    810     if (mode) {
    811         bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType();
    812         switch (SkInterpretXfermode(*paint, deviceIsOpaque)) {
    813             case kSrcOver_SkXfermodeInterpretation:
    814                 mode = NULL;
    815                 paint.writable()->setXfermode(NULL);
    816                 break;
    817             case kSkipDrawing_SkXfermodeInterpretation:{
    818                 return allocator->createT<SkNullBlitter>();
    819             }
    820             default:
    821                 break;
    822         }
    823     }
    824 
    825     /*
    826      *  If the xfermode is CLEAR, then we can completely ignore the installed
    827      *  color/shader/colorfilter, and just pretend we're SRC + color==0. This
    828      *  will fall into our optimizations for SRC mode.
    829      */
    830     if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) {
    831         SkPaint* p = paint.writable();
    832         shader = p->setShader(NULL);
    833         cf = p->setColorFilter(NULL);
    834         mode = p->setXfermodeMode(SkXfermode::kSrc_Mode);
    835         p->setColor(0);
    836     }
    837 
    838     if (NULL == shader) {
    839         if (mode) {
    840             // xfermodes (and filters) require shaders for our current blitters
    841             shader = SkNEW_ARGS(SkColorShader, (paint->getColor()));
    842             paint.writable()->setShader(shader)->unref();
    843             paint.writable()->setAlpha(0xFF);
    844         } else if (cf) {
    845             // if no shader && no xfermode, we just apply the colorfilter to
    846             // our color and move on.
    847             SkPaint* writablePaint = paint.writable();
    848             writablePaint->setColor(cf->filterColor(paint->getColor()));
    849             writablePaint->setColorFilter(NULL);
    850             cf = NULL;
    851         }
    852     }
    853 
    854     if (cf) {
    855         SkASSERT(shader);
    856         shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
    857         paint.writable()->setShader(shader)->unref();
    858         // blitters should ignore the presence/absence of a filter, since
    859         // if there is one, the shader will take care of it.
    860     }
    861 
    862     /*
    863      *  We create a SkShader::Context object, and store it on the blitter.
    864      */
    865     SkShader::Context* shaderContext = NULL;
    866     if (shader) {
    867         SkShader::ContextRec rec(device, *paint, matrix);
    868         size_t contextSize = shader->contextSize();
    869         if (contextSize) {
    870             // Try to create the ShaderContext
    871             void* storage = allocator->reserveT<SkShader::Context>(contextSize);
    872             shaderContext = shader->createContext(rec, storage);
    873             if (!shaderContext) {
    874                 allocator->freeLast();
    875                 return allocator->createT<SkNullBlitter>();
    876             }
    877             SkASSERT(shaderContext);
    878             SkASSERT((void*) shaderContext == storage);
    879         } else {
    880             return allocator->createT<SkNullBlitter>();
    881         }
    882     }
    883 
    884     SkBlitter*  blitter = NULL;
    885     switch (device.colorType()) {
    886         case kAlpha_8_SkColorType:
    887             if (drawCoverage) {
    888                 SkASSERT(NULL == shader);
    889                 SkASSERT(NULL == paint->getXfermode());
    890                 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
    891             } else if (shader) {
    892                 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext);
    893             } else {
    894                 blitter = allocator->createT<SkA8_Blitter>(device, *paint);
    895             }
    896             break;
    897 
    898         case kRGB_565_SkColorType:
    899             blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, allocator);
    900             break;
    901 
    902         case kN32_SkColorType:
    903             if (shader) {
    904                 blitter = allocator->createT<SkARGB32_Shader_Blitter>(
    905                         device, *paint, shaderContext);
    906             } else if (paint->getColor() == SK_ColorBLACK) {
    907                 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
    908             } else if (paint->getAlpha() == 0xFF) {
    909                 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint);
    910             } else {
    911                 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint);
    912             }
    913             break;
    914 
    915         default:
    916             SkDEBUGFAIL("unsupported device config");
    917             blitter = allocator->createT<SkNullBlitter>();
    918             break;
    919     }
    920 
    921     if (shader3D) {
    922         SkBlitter* innerBlitter = blitter;
    923         // innerBlitter was allocated by allocator, which will delete it.
    924         // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
    925         // wrapper the blitter to notify it when we see an emboss mask.
    926         blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext);
    927     }
    928     return blitter;
    929 }
    930 
    931 ///////////////////////////////////////////////////////////////////////////////
    932 
    933 class SkTransparentShaderContext : public SkShader::Context {
    934 public:
    935     SkTransparentShaderContext(const SkShader& shader, const SkShader::ContextRec& rec)
    936         // Override rec with the identity matrix, so it is guaranteed to be invertible.
    937         : INHERITED(shader, SkShader::ContextRec(*rec.fDevice, *rec.fPaint, SkMatrix::I())) {}
    938 
    939     void shadeSpan(int x, int y, SkPMColor colors[], int count) override {
    940         sk_bzero(colors, count * sizeof(SkPMColor));
    941     }
    942 
    943 private:
    944     typedef SkShader::Context INHERITED;
    945 };
    946 
    947 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint,
    948                                  SkShader::Context* shaderContext)
    949         : INHERITED(device)
    950         , fShader(paint.getShader())
    951         , fShaderContext(shaderContext) {
    952     SkASSERT(fShader);
    953     SkASSERT(fShaderContext);
    954 
    955     fShader->ref();
    956     fShaderFlags = fShaderContext->getFlags();
    957 }
    958 
    959 SkShaderBlitter::~SkShaderBlitter() {
    960     fShader->unref();
    961 }
    962 
    963 bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) {
    964     // Only destroy the old context if we have a new one. We need to ensure to have a
    965     // live context in fShaderContext because the storage is owned by an SkSmallAllocator
    966     // outside of this class.
    967     // The new context will be of the same size as the old one because we use the same
    968     // shader to create it. It is therefore safe to re-use the storage.
    969     fShaderContext->~Context();
    970     SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext);
    971     if (NULL == ctx) {
    972         // Need a valid context in fShaderContext's storage, so we can later (or our caller) call
    973         // the in-place destructor.
    974         SkNEW_PLACEMENT_ARGS(fShaderContext, SkTransparentShaderContext, (*fShader, rec));
    975         return false;
    976     }
    977     return true;
    978 }
    979