gfx/skia/trunk/src/core/SkBlitter.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     2 /*
     3  * Copyright 2006 The Android Open Source Project
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkBlitter.h"
    11 #include "SkAntiRun.h"
    12 #include "SkColor.h"
    13 #include "SkColorFilter.h"
    14 #include "SkCoreBlitters.h"
    15 #include "SkFilterShader.h"
    16 #include "SkReadBuffer.h"
    17 #include "SkWriteBuffer.h"
    18 #include "SkMask.h"
    19 #include "SkMaskFilter.h"
    20 #include "SkString.h"
    21 #include "SkTLazy.h"
    22 #include "SkUtils.h"
    23 #include "SkXfermode.h"
    25 SkBlitter::~SkBlitter() {}
    27 bool SkBlitter::isNullBlitter() const { return false; }
    29 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
    30     return NULL;
    31 }
    33 void SkBlitter::blitH(int x, int y, int width) {
    34     SkDEBUGFAIL("unimplemented");
    35 }
    37 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
    38                           const int16_t runs[]) {
    39     SkDEBUGFAIL("unimplemented");
    40 }
    42 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
    43     if (alpha == 255) {
    44         this->blitRect(x, y, 1, height);
    45     } else {
    46         int16_t runs[2];
    47         runs[0] = 1;
    48         runs[1] = 0;
    50         while (--height >= 0) {
    51             this->blitAntiH(x, y++, &alpha, runs);
    52         }
    53     }
    54 }
    56 void SkBlitter::blitRect(int x, int y, int width, int height) {
    57     SkASSERT(width > 0);
    58     while (--height >= 0) {
    59         this->blitH(x, y++, width);
    60     }
    61 }
    63 /// Default implementation doesn't check for any easy optimizations
    64 /// such as alpha == 0 or 255; also uses blitV(), which some subclasses
    65 /// may not support.
    66 void SkBlitter::blitAntiRect(int x, int y, int width, int height,
    67                              SkAlpha leftAlpha, SkAlpha rightAlpha) {
    68     this->blitV(x++, y, height, leftAlpha);
    69     if (width > 0) {
    70         this->blitRect(x, y, width, height);
    71         x += width;
    72     }
    73     this->blitV(x, y, height, rightAlpha);
    74 }
    76 //////////////////////////////////////////////////////////////////////////////
    78 static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
    79                                 const uint8_t bits[],
    80                                 U8CPU left_mask, int rowBytes,
    81                                 U8CPU right_mask) {
    82     int inFill = 0;
    83     int pos = 0;
    85     while (--rowBytes >= 0) {
    86         unsigned b = *bits++ & left_mask;
    87         if (rowBytes == 0) {
    88             b &= right_mask;
    89         }
    91         for (unsigned test = 0x80; test != 0; test >>= 1) {
    92             if (b & test) {
    93                 if (!inFill) {
    94                     pos = x;
    95                     inFill = true;
    96                 }
    97             } else {
    98                 if (inFill) {
    99                     blitter->blitH(pos, y, x - pos);
   100                     inFill = false;
   101                 }
   102             }
   103             x += 1;
   104         }
   105         left_mask = 0xFF;
   106     }
   108     // final cleanup
   109     if (inFill) {
   110         blitter->blitH(pos, y, x - pos);
   111     }
   112 }
   114 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
   115     SkASSERT(mask.fBounds.contains(clip));
   117     if (mask.fFormat == SkMask::kBW_Format) {
   118         int cx = clip.fLeft;
   119         int cy = clip.fTop;
   120         int maskLeft = mask.fBounds.fLeft;
   121         int mask_rowBytes = mask.fRowBytes;
   122         int height = clip.height();
   124         const uint8_t* bits = mask.getAddr1(cx, cy);
   126         if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
   127             while (--height >= 0) {
   128                 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
   129                 bits += mask_rowBytes;
   130                 cy += 1;
   131             }
   132         } else {
   133             int left_edge = cx - maskLeft;
   134             SkASSERT(left_edge >= 0);
   135             int rite_edge = clip.fRight - maskLeft;
   136             SkASSERT(rite_edge > left_edge);
   138             int left_mask = 0xFF >> (left_edge & 7);
   139             int rite_mask = 0xFF << (8 - (rite_edge & 7));
   140             int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
   142             // check for empty right mask, so we don't read off the end (or go slower than we need to)
   143             if (rite_mask == 0) {
   144                 SkASSERT(full_runs >= 0);
   145                 full_runs -= 1;
   146                 rite_mask = 0xFF;
   147             }
   148             if (left_mask == 0xFF) {
   149                 full_runs -= 1;
   150             }
   152             // back up manually so we can keep in sync with our byte-aligned src
   153             // have cx reflect our actual starting x-coord
   154             cx -= left_edge & 7;
   156             if (full_runs < 0) {
   157                 SkASSERT((left_mask & rite_mask) != 0);
   158                 while (--height >= 0) {
   159                     bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
   160                     bits += mask_rowBytes;
   161                     cy += 1;
   162                 }
   163             } else {
   164                 while (--height >= 0) {
   165                     bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
   166                     bits += mask_rowBytes;
   167                     cy += 1;
   168                 }
   169             }
   170         }
   171     } else {
   172         int                         width = clip.width();
   173         SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
   174         int16_t*                    runs = runStorage.get();
   175         const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
   177         sk_memset16((uint16_t*)runs, 1, width);
   178         runs[width] = 0;
   180         int height = clip.height();
   181         int y = clip.fTop;
   182         while (--height >= 0) {
   183             this->blitAntiH(clip.fLeft, y, aa, runs);
   184             aa += mask.fRowBytes;
   185             y += 1;
   186         }
   187     }
   188 }
   190 /////////////////////// these guys are not virtual, just a helpers
   192 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
   193     if (clip.quickReject(mask.fBounds)) {
   194         return;
   195     }
   197     SkRegion::Cliperator clipper(clip, mask.fBounds);
   199     while (!clipper.done()) {
   200         const SkIRect& cr = clipper.rect();
   201         this->blitMask(mask, cr);
   202         clipper.next();
   203     }
   204 }
   206 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
   207     SkRegion::Cliperator clipper(clip, rect);
   209     while (!clipper.done()) {
   210         const SkIRect& cr = clipper.rect();
   211         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
   212         clipper.next();
   213     }
   214 }
   216 void SkBlitter::blitRegion(const SkRegion& clip) {
   217     SkRegion::Iterator iter(clip);
   219     while (!iter.done()) {
   220         const SkIRect& cr = iter.rect();
   221         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
   222         iter.next();
   223     }
   224 }
   226 ///////////////////////////////////////////////////////////////////////////////
   228 void SkNullBlitter::blitH(int x, int y, int width) {}
   230 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
   231                               const int16_t runs[]) {}
   233 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
   235 void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
   237 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
   239 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
   240     return NULL;
   241 }
   243 bool SkNullBlitter::isNullBlitter() const { return true; }
   245 ///////////////////////////////////////////////////////////////////////////////
   247 static int compute_anti_width(const int16_t runs[]) {
   248     int width = 0;
   250     for (;;) {
   251         int count = runs[0];
   253         SkASSERT(count >= 0);
   254         if (count == 0) {
   255             break;
   256         }
   257         width += count;
   258         runs += count;
   259     }
   260     return width;
   261 }
   263 static inline bool y_in_rect(int y, const SkIRect& rect) {
   264     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
   265 }
   267 static inline bool x_in_rect(int x, const SkIRect& rect) {
   268     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
   269 }
   271 void SkRectClipBlitter::blitH(int left, int y, int width) {
   272     SkASSERT(width > 0);
   274     if (!y_in_rect(y, fClipRect)) {
   275         return;
   276     }
   278     int right = left + width;
   280     if (left < fClipRect.fLeft) {
   281         left = fClipRect.fLeft;
   282     }
   283     if (right > fClipRect.fRight) {
   284         right = fClipRect.fRight;
   285     }
   287     width = right - left;
   288     if (width > 0) {
   289         fBlitter->blitH(left, y, width);
   290     }
   291 }
   293 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
   294                                   const int16_t runs[]) {
   295     if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
   296         return;
   297     }
   299     int x0 = left;
   300     int x1 = left + compute_anti_width(runs);
   302     if (x1 <= fClipRect.fLeft) {
   303         return;
   304     }
   306     SkASSERT(x0 < x1);
   307     if (x0 < fClipRect.fLeft) {
   308         int dx = fClipRect.fLeft - x0;
   309         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
   310         runs += dx;
   311         aa += dx;
   312         x0 = fClipRect.fLeft;
   313     }
   315     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
   316     if (x1 > fClipRect.fRight) {
   317         x1 = fClipRect.fRight;
   318         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
   319         ((int16_t*)runs)[x1 - x0] = 0;
   320     }
   322     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
   323     SkASSERT(compute_anti_width(runs) == x1 - x0);
   325     fBlitter->blitAntiH(x0, y, aa, runs);
   326 }
   328 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
   329     SkASSERT(height > 0);
   331     if (!x_in_rect(x, fClipRect)) {
   332         return;
   333     }
   335     int y0 = y;
   336     int y1 = y + height;
   338     if (y0 < fClipRect.fTop) {
   339         y0 = fClipRect.fTop;
   340     }
   341     if (y1 > fClipRect.fBottom) {
   342         y1 = fClipRect.fBottom;
   343     }
   345     if (y0 < y1) {
   346         fBlitter->blitV(x, y0, y1 - y0, alpha);
   347     }
   348 }
   350 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
   351     SkIRect    r;
   353     r.set(left, y, left + width, y + height);
   354     if (r.intersect(fClipRect)) {
   355         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
   356     }
   357 }
   359 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
   360                                      SkAlpha leftAlpha, SkAlpha rightAlpha) {
   361     SkIRect    r;
   363     // The *true* width of the rectangle blitted is width+2:
   364     r.set(left, y, left + width + 2, y + height);
   365     if (r.intersect(fClipRect)) {
   366         if (r.fLeft != left) {
   367             SkASSERT(r.fLeft > left);
   368             leftAlpha = 255;
   369         }
   370         if (r.fRight != left + width + 2) {
   371             SkASSERT(r.fRight < left + width + 2);
   372             rightAlpha = 255;
   373         }
   374         if (255 == leftAlpha && 255 == rightAlpha) {
   375             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
   376         } else if (1 == r.width()) {
   377             if (r.fLeft == left) {
   378                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
   379             } else {
   380                 SkASSERT(r.fLeft == left + width + 1);
   381                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
   382             }
   383         } else {
   384             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
   385                                    leftAlpha, rightAlpha);
   386         }
   387     }
   388 }
   390 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
   391     SkASSERT(mask.fBounds.contains(clip));
   393     SkIRect    r = clip;
   395     if (r.intersect(fClipRect)) {
   396         fBlitter->blitMask(mask, r);
   397     }
   398 }
   400 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
   401     return fBlitter->justAnOpaqueColor(value);
   402 }
   404 ///////////////////////////////////////////////////////////////////////////////
   406 void SkRgnClipBlitter::blitH(int x, int y, int width) {
   407     SkRegion::Spanerator span(*fRgn, y, x, x + width);
   408     int left, right;
   410     while (span.next(&left, &right)) {
   411         SkASSERT(left < right);
   412         fBlitter->blitH(left, y, right - left);
   413     }
   414 }
   416 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
   417                                  const int16_t runs[]) {
   418     int width = compute_anti_width(runs);
   419     SkRegion::Spanerator span(*fRgn, y, x, x + width);
   420     int left, right;
   421     SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
   423     int prevRite = x;
   424     while (span.next(&left, &right)) {
   425         SkASSERT(x <= left);
   426         SkASSERT(left < right);
   427         SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
   429         SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
   431         // now zero before left
   432         if (left > prevRite) {
   433             int index = prevRite - x;
   434             ((uint8_t*)aa)[index] = 0;   // skip runs after right
   435             ((int16_t*)runs)[index] = SkToS16(left - prevRite);
   436         }
   438         prevRite = right;
   439     }
   441     if (prevRite > x) {
   442         ((int16_t*)runs)[prevRite - x] = 0;
   444         if (x < 0) {
   445             int skip = runs[0];
   446             SkASSERT(skip >= -x);
   447             aa += skip;
   448             runs += skip;
   449             x += skip;
   450         }
   451         fBlitter->blitAntiH(x, y, aa, runs);
   452     }
   453 }
   455 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
   456     SkIRect    bounds;
   457     bounds.set(x, y, x + 1, y + height);
   459     SkRegion::Cliperator    iter(*fRgn, bounds);
   461     while (!iter.done()) {
   462         const SkIRect& r = iter.rect();
   463         SkASSERT(bounds.contains(r));
   465         fBlitter->blitV(x, r.fTop, r.height(), alpha);
   466         iter.next();
   467     }
   468 }
   470 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
   471     SkIRect    bounds;
   472     bounds.set(x, y, x + width, y + height);
   474     SkRegion::Cliperator    iter(*fRgn, bounds);
   476     while (!iter.done()) {
   477         const SkIRect& r = iter.rect();
   478         SkASSERT(bounds.contains(r));
   480         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
   481         iter.next();
   482     }
   483 }
   485 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
   486                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
   487     // The *true* width of the rectangle to blit is width + 2
   488     SkIRect    bounds;
   489     bounds.set(x, y, x + width + 2, y + height);
   491     SkRegion::Cliperator    iter(*fRgn, bounds);
   493     while (!iter.done()) {
   494         const SkIRect& r = iter.rect();
   495         SkASSERT(bounds.contains(r));
   496         SkASSERT(r.fLeft >= x);
   497         SkASSERT(r.fRight <= x + width + 2);
   499         SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
   500         SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
   501                                       rightAlpha : 255;
   503         if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
   504             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
   505         } else if (1 == r.width()) {
   506             if (r.fLeft == x) {
   507                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
   508                                 effectiveLeftAlpha);
   509             } else {
   510                 SkASSERT(r.fLeft == x + width + 1);
   511                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
   512                                 effectiveRightAlpha);
   513             }
   514         } else {
   515             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
   516                                    effectiveLeftAlpha, effectiveRightAlpha);
   517         }
   518         iter.next();
   519     }
   520 }
   523 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
   524     SkASSERT(mask.fBounds.contains(clip));
   526     SkRegion::Cliperator iter(*fRgn, clip);
   527     const SkIRect&       r = iter.rect();
   528     SkBlitter*           blitter = fBlitter;
   530     while (!iter.done()) {
   531         blitter->blitMask(mask, r);
   532         iter.next();
   533     }
   534 }
   536 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
   537     return fBlitter->justAnOpaqueColor(value);
   538 }
   540 ///////////////////////////////////////////////////////////////////////////////
   542 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
   543                                    const SkIRect* ir) {
   544     if (clip) {
   545         const SkIRect& clipR = clip->getBounds();
   547         if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
   548             blitter = &fNullBlitter;
   549         } else if (clip->isRect()) {
   550             if (ir == NULL || !clipR.contains(*ir)) {
   551                 fRectBlitter.init(blitter, clipR);
   552                 blitter = &fRectBlitter;
   553             }
   554         } else {
   555             fRgnBlitter.init(blitter, clip);
   556             blitter = &fRgnBlitter;
   557         }
   558     }
   559     return blitter;
   560 }
   562 ///////////////////////////////////////////////////////////////////////////////
   564 #include "SkColorShader.h"
   565 #include "SkColorPriv.h"
   567 class Sk3DShader : public SkShader {
   568 public:
   569     Sk3DShader(SkShader* proxy) : fProxy(proxy) {
   570         SkSafeRef(proxy);
   571         fMask = NULL;
   572     }
   574     virtual ~Sk3DShader() {
   575         SkSafeUnref(fProxy);
   576     }
   578     void setMask(const SkMask* mask) { fMask = mask; }
   580     virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
   581                             const SkMatrix& matrix) SK_OVERRIDE {
   582         if (!this->INHERITED::setContext(device, paint, matrix)) {
   583             return false;
   584         }
   585         if (fProxy) {
   586             if (!fProxy->setContext(device, paint, matrix)) {
   587                 // must keep our set/end context calls balanced
   588                 this->INHERITED::endContext();
   589                 return false;
   590             }
   591         } else {
   592             fPMColor = SkPreMultiplyColor(paint.getColor());
   593         }
   594         return true;
   595     }
   597     virtual void endContext() SK_OVERRIDE {
   598         if (fProxy) {
   599             fProxy->endContext();
   600         }
   601         this->INHERITED::endContext();
   602     }
   604     virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE {
   605         if (fProxy) {
   606             fProxy->shadeSpan(x, y, span, count);
   607         }
   609         if (fMask == NULL) {
   610             if (fProxy == NULL) {
   611                 sk_memset32(span, fPMColor, count);
   612             }
   613             return;
   614         }
   616         SkASSERT(fMask->fBounds.contains(x, y));
   617         SkASSERT(fMask->fBounds.contains(x + count - 1, y));
   619         size_t          size = fMask->computeImageSize();
   620         const uint8_t*  alpha = fMask->getAddr8(x, y);
   621         const uint8_t*  mulp = alpha + size;
   622         const uint8_t*  addp = mulp + size;
   624         if (fProxy) {
   625             for (int i = 0; i < count; i++) {
   626                 if (alpha[i]) {
   627                     SkPMColor c = span[i];
   628                     if (c) {
   629                         unsigned a = SkGetPackedA32(c);
   630                         unsigned r = SkGetPackedR32(c);
   631                         unsigned g = SkGetPackedG32(c);
   632                         unsigned b = SkGetPackedB32(c);
   634                         unsigned mul = SkAlpha255To256(mulp[i]);
   635                         unsigned add = addp[i];
   637                         r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
   638                         g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
   639                         b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
   641                         span[i] = SkPackARGB32(a, r, g, b);
   642                     }
   643                 } else {
   644                     span[i] = 0;
   645                 }
   646             }
   647         } else {    // color
   648             unsigned a = SkGetPackedA32(fPMColor);
   649             unsigned r = SkGetPackedR32(fPMColor);
   650             unsigned g = SkGetPackedG32(fPMColor);
   651             unsigned b = SkGetPackedB32(fPMColor);
   652             for (int i = 0; i < count; i++) {
   653                 if (alpha[i]) {
   654                     unsigned mul = SkAlpha255To256(mulp[i]);
   655                     unsigned add = addp[i];
   657                     span[i] = SkPackARGB32( a,
   658                                     SkFastMin32(SkAlphaMul(r, mul) + add, a),
   659                                     SkFastMin32(SkAlphaMul(g, mul) + add, a),
   660                                     SkFastMin32(SkAlphaMul(b, mul) + add, a));
   661                 } else {
   662                     span[i] = 0;
   663                 }
   664             }
   665         }
   666     }
   668 #ifndef SK_IGNORE_TO_STRING
   669     virtual void toString(SkString* str) const SK_OVERRIDE {
   670         str->append("Sk3DShader: (");
   672         if (NULL != fProxy) {
   673             str->append("Proxy: ");
   674             fProxy->toString(str);
   675         }
   677         this->INHERITED::toString(str);
   679         str->append(")");
   680     }
   681 #endif
   683     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
   685 protected:
   686     Sk3DShader(SkReadBuffer& buffer) : INHERITED(buffer) {
   687         fProxy = buffer.readShader();
   688         fPMColor = buffer.readColor();
   689         fMask = NULL;
   690     }
   692     virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE {
   693         this->INHERITED::flatten(buffer);
   694         buffer.writeFlattenable(fProxy);
   695         buffer.writeColor(fPMColor);
   696     }
   698 private:
   699     SkShader*       fProxy;
   700     SkPMColor       fPMColor;
   701     const SkMask*   fMask;
   703     typedef SkShader INHERITED;
   704 };
   706 class Sk3DBlitter : public SkBlitter {
   707 public:
   708     Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader)
   709         : fProxy(proxy)
   710         , f3DShader(SkRef(shader))
   711     {}
   713     virtual void blitH(int x, int y, int width) {
   714         fProxy->blitH(x, y, width);
   715     }
   717     virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
   718                            const int16_t runs[]) {
   719         fProxy->blitAntiH(x, y, antialias, runs);
   720     }
   722     virtual void blitV(int x, int y, int height, SkAlpha alpha) {
   723         fProxy->blitV(x, y, height, alpha);
   724     }
   726     virtual void blitRect(int x, int y, int width, int height) {
   727         fProxy->blitRect(x, y, width, height);
   728     }
   730     virtual void blitMask(const SkMask& mask, const SkIRect& clip) {
   731         if (mask.fFormat == SkMask::k3D_Format) {
   732             f3DShader->setMask(&mask);
   734             ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
   735             fProxy->blitMask(mask, clip);
   736             ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
   738             f3DShader->setMask(NULL);
   739         } else {
   740             fProxy->blitMask(mask, clip);
   741         }
   742     }
   744 private:
   745     // fProxy is unowned. It will be deleted by SkSmallAllocator.
   746     SkBlitter*               fProxy;
   747     SkAutoTUnref<Sk3DShader> f3DShader;
   748 };
   750 ///////////////////////////////////////////////////////////////////////////////
   752 #include "SkCoreBlitters.h"
   754 static bool just_solid_color(const SkPaint& paint) {
   755     if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) {
   756         SkShader* shader = paint.getShader();
   757         if (NULL == shader ||
   758             (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
   759             return true;
   760         }
   761     }
   762     return false;
   763 }
   765 /** By analyzing the paint (with an xfermode), we may decide we can take
   766     special action. This enum lists our possible actions
   767  */
   768 enum XferInterp {
   769     kNormal_XferInterp,         // no special interpretation, draw normally
   770     kSrcOver_XferInterp,        // draw as if in srcover mode
   771     kSkipDrawing_XferInterp     // draw nothing
   772 };
   774 static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer,
   775                                      SkColorType deviceCT) {
   776     SkXfermode::Mode  mode;
   778     if (SkXfermode::AsMode(xfer, &mode)) {
   779         switch (mode) {
   780             case SkXfermode::kSrc_Mode:
   781                 if (just_solid_color(paint)) {
   782                     return kSrcOver_XferInterp;
   783                 }
   784                 break;
   785             case SkXfermode::kDst_Mode:
   786                 return kSkipDrawing_XferInterp;
   787             case SkXfermode::kSrcOver_Mode:
   788                 return kSrcOver_XferInterp;
   789             case SkXfermode::kDstOver_Mode:
   790                 if (kRGB_565_SkColorType == deviceCT) {
   791                     return kSkipDrawing_XferInterp;
   792                 }
   793                 break;
   794             case SkXfermode::kSrcIn_Mode:
   795                 if (kRGB_565_SkColorType == deviceCT &&
   796                     just_solid_color(paint)) {
   797                     return kSrcOver_XferInterp;
   798                 }
   799                 break;
   800             case SkXfermode::kDstIn_Mode:
   801                 if (just_solid_color(paint)) {
   802                     return kSkipDrawing_XferInterp;
   803                 }
   804                 break;
   805             default:
   806                 break;
   807         }
   808     }
   809     return kNormal_XferInterp;
   810 }
   812 SkBlitter* SkBlitter::Choose(const SkBitmap& device,
   813                              const SkMatrix& matrix,
   814                              const SkPaint& origPaint,
   815                              SkTBlitterAllocator* allocator,
   816                              bool drawCoverage) {
   817     SkASSERT(allocator != NULL);
   819     SkBlitter*  blitter = NULL;
   821     // which check, in case we're being called by a client with a dummy device
   822     // (e.g. they have a bounder that always aborts the draw)
   823     if (kUnknown_SkColorType == device.colorType() ||
   824             (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
   825         blitter = allocator->createT<SkNullBlitter>();
   826         return blitter;
   827     }
   829     SkShader* shader = origPaint.getShader();
   830     SkColorFilter* cf = origPaint.getColorFilter();
   831     SkXfermode* mode = origPaint.getXfermode();
   832     Sk3DShader* shader3D = NULL;
   834     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
   836     if (origPaint.getMaskFilter() != NULL &&
   837             origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
   838         shader3D = SkNEW_ARGS(Sk3DShader, (shader));
   839         // we know we haven't initialized lazyPaint yet, so just do it
   840         paint.writable()->setShader(shader3D)->unref();
   841         shader = shader3D;
   842     }
   844     if (NULL != mode) {
   845         switch (interpret_xfermode(*paint, mode, device.colorType())) {
   846             case kSrcOver_XferInterp:
   847                 mode = NULL;
   848                 paint.writable()->setXfermode(NULL);
   849                 break;
   850             case kSkipDrawing_XferInterp:{
   851                 blitter = allocator->createT<SkNullBlitter>();
   852                 return blitter;
   853             }
   854             default:
   855                 break;
   856         }
   857     }
   859     /*
   860      *  If the xfermode is CLEAR, then we can completely ignore the installed
   861      *  color/shader/colorfilter, and just pretend we're SRC + color==0. This
   862      *  will fall into our optimizations for SRC mode.
   863      */
   864     if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) {
   865         SkPaint* p = paint.writable();
   866         shader = p->setShader(NULL);
   867         cf = p->setColorFilter(NULL);
   868         mode = p->setXfermodeMode(SkXfermode::kSrc_Mode);
   869         p->setColor(0);
   870     }
   872     if (NULL == shader) {
   873         if (mode) {
   874             // xfermodes (and filters) require shaders for our current blitters
   875             shader = SkNEW(SkColorShader);
   876             paint.writable()->setShader(shader)->unref();
   877         } else if (cf) {
   878             // if no shader && no xfermode, we just apply the colorfilter to
   879             // our color and move on.
   880             SkPaint* writablePaint = paint.writable();
   881             writablePaint->setColor(cf->filterColor(paint->getColor()));
   882             writablePaint->setColorFilter(NULL);
   883             cf = NULL;
   884         }
   885     }
   887     if (cf) {
   888         SkASSERT(shader);
   889         shader = SkNEW_ARGS(SkFilterShader, (shader, cf));
   890         paint.writable()->setShader(shader)->unref();
   891         // blitters should ignore the presence/absence of a filter, since
   892         // if there is one, the shader will take care of it.
   893     }
   895     /*
   896      *  We need to have balanced calls to the shader:
   897      *      setContext
   898      *      endContext
   899      *  We make the first call here, in case it fails we can abort the draw.
   900      *  The endContext() call is made by the blitter (assuming setContext did
   901      *  not fail) in its destructor.
   902      */
   903     if (shader && !shader->setContext(device, *paint, matrix)) {
   904         blitter = allocator->createT<SkNullBlitter>();
   905         return blitter;
   906     }
   909     switch (device.colorType()) {
   910         case kAlpha_8_SkColorType:
   911             if (drawCoverage) {
   912                 SkASSERT(NULL == shader);
   913                 SkASSERT(NULL == paint->getXfermode());
   914                 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
   915             } else if (shader) {
   916                 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint);
   917             } else {
   918                 blitter = allocator->createT<SkA8_Blitter>(device, *paint);
   919             }
   920             break;
   922         case kRGB_565_SkColorType:
   923             blitter = SkBlitter_ChooseD565(device, *paint, allocator);
   924             break;
   926         case kPMColor_SkColorType:
   927             if (shader) {
   928                 blitter = allocator->createT<SkARGB32_Shader_Blitter>(device, *paint);
   929             } else if (paint->getColor() == SK_ColorBLACK) {
   930                 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
   931             } else if (paint->getAlpha() == 0xFF) {
   932                 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint);
   933             } else {
   934                 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint);
   935             }
   936             break;
   938         default:
   939             SkDEBUGFAIL("unsupported device config");
   940             blitter = allocator->createT<SkNullBlitter>();
   941             break;
   942     }
   944     if (shader3D) {
   945         SkBlitter* innerBlitter = blitter;
   946         // innerBlitter was allocated by allocator, which will delete it.
   947         blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shader3D);
   948     }
   949     return blitter;
   950 }
   952 ///////////////////////////////////////////////////////////////////////////////
   954 const uint16_t gMask_0F0F = 0xF0F;
   955 const uint32_t gMask_00FF00FF = 0xFF00FF;
   957 ///////////////////////////////////////////////////////////////////////////////
   959 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
   960         : INHERITED(device) {
   961     fShader = paint.getShader();
   962     SkASSERT(fShader);
   963     SkASSERT(fShader->setContextHasBeenCalled());
   965     fShader->ref();
   966     fShaderFlags = fShader->getFlags();
   967 }
   969 SkShaderBlitter::~SkShaderBlitter() {
   970     SkASSERT(fShader->setContextHasBeenCalled());
   971     fShader->endContext();
   972     fShader->unref();
   973 }

mercurial