Home | History | Annotate | Download | only in effects
      1 
      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  */
      8 
      9 
     10 #include "SkGradientShader.h"
     11 #include "SkClampRange.h"
     12 #include "SkColorPriv.h"
     13 #include "SkMallocPixelRef.h"
     14 #include "SkUnitMapper.h"
     15 #include "SkUtils.h"
     16 #include "SkTemplates.h"
     17 #include "SkBitmapCache.h"
     18 
     19 #ifndef SK_DISABLE_DITHER_32BIT_GRADIENT
     20     #define USE_DITHER_32BIT_GRADIENT
     21 #endif
     22 
     23 static void sk_memset32_dither(uint32_t dst[], uint32_t v0, uint32_t v1,
     24                                int count) {
     25     if (count > 0) {
     26         if (v0 == v1) {
     27             sk_memset32(dst, v0, count);
     28         } else {
     29             int pairs = count >> 1;
     30             for (int i = 0; i < pairs; i++) {
     31                 *dst++ = v0;
     32                 *dst++ = v1;
     33             }
     34             if (count & 1) {
     35                 *dst = v0;
     36             }
     37         }
     38     }
     39 }
     40 
     41 ///////////////////////////////////////////////////////////////////////////////
     42 // Can't use a two-argument function with side effects like this in a
     43 // constructor's initializer's argument list because the order of
     44 // evaluations in that context is undefined (and backwards on linux/gcc).
     45 static SkPoint unflatten_point(SkReader32& buffer) {
     46     SkPoint retval;
     47     retval.fX = buffer.readScalar();
     48     retval.fY = buffer.readScalar();
     49     return retval;
     50 }
     51 
     52 //  Clamp
     53 
     54 static SkFixed clamp_tileproc(SkFixed x) {
     55     return SkClampMax(x, 0xFFFF);
     56 }
     57 
     58 // Repeat
     59 
     60 static SkFixed repeat_tileproc(SkFixed x) {
     61     return x & 0xFFFF;
     62 }
     63 
     64 static inline int repeat_bits(int x, const int bits) {
     65     return x & ((1 << bits) - 1);
     66 }
     67 
     68 static inline int repeat_8bits(int x) {
     69     return x & 0xFF;
     70 }
     71 
     72 // Mirror
     73 
     74 // Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly.
     75 // See http://code.google.com/p/skia/issues/detail?id=472
     76 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
     77 #pragma optimize("", off)
     78 #endif
     79 
     80 static inline SkFixed mirror_tileproc(SkFixed x) {
     81     int s = x << 15 >> 31;
     82     return (x ^ s) & 0xFFFF;
     83 }
     84 
     85 static inline int mirror_bits(int x, const int bits) {
     86 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
     87     if (x & (1 << bits))
     88         x = ~x;
     89     return x & ((1 << bits) - 1);
     90 #else
     91     int s = x << (31 - bits) >> 31;
     92     return (x ^ s) & ((1 << bits) - 1);
     93 #endif
     94 }
     95 
     96 static inline int mirror_8bits(int x) {
     97 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
     98     if (x & 256) {
     99         x = ~x;
    100     }
    101     return x & 255;
    102 #else
    103     int s = x << 23 >> 31;
    104     return (x ^ s) & 0xFF;
    105 #endif
    106 }
    107 
    108 #if defined(_MSC_VER) && (_MSC_VER >= 1600)
    109 #pragma optimize("", on)
    110 #endif
    111 
    112 ///////////////////////////////////////////////////////////////////////////////
    113 
    114 typedef SkFixed (*TileProc)(SkFixed);
    115 
    116 static const TileProc gTileProcs[] = {
    117     clamp_tileproc,
    118     repeat_tileproc,
    119     mirror_tileproc
    120 };
    121 
    122 ///////////////////////////////////////////////////////////////////////////////
    123 ///////////////////////////////////////////////////////////////////////////////
    124 
    125 class Gradient_Shader : public SkShader {
    126 public:
    127     Gradient_Shader(const SkColor colors[], const SkScalar pos[],
    128                 int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper);
    129     virtual ~Gradient_Shader();
    130 
    131     // overrides
    132     virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&) SK_OVERRIDE;
    133     virtual uint32_t getFlags() SK_OVERRIDE { return fFlags; }
    134     virtual bool isOpaque() const SK_OVERRIDE;
    135 
    136     enum {
    137         /// Seems like enough for visual accuracy. TODO: if pos[] deserves
    138         /// it, use a larger cache.
    139         kCache16Bits    = 8,
    140         kGradient16Length = (1 << kCache16Bits),
    141         /// Each cache gets 1 extra entry at the end so we don't have to
    142         /// test for end-of-cache in lerps. This is also the value used
    143         /// to stride *writes* into the dither cache; it must not be zero.
    144         /// Total space for a cache is 2x kCache16Count entries: one
    145         /// regular cache, one for dithering.
    146         kCache16Count   = kGradient16Length + 1,
    147         kCache16Shift   = 16 - kCache16Bits,
    148         kSqrt16Shift    = 8 - kCache16Bits,
    149 
    150         /// Seems like enough for visual accuracy. TODO: if pos[] deserves
    151         /// it, use a larger cache.
    152         kCache32Bits    = 8,
    153         kGradient32Length = (1 << kCache32Bits),
    154         /// Each cache gets 1 extra entry at the end so we don't have to
    155         /// test for end-of-cache in lerps. This is also the value used
    156         /// to stride *writes* into the dither cache; it must not be zero.
    157         /// Total space for a cache is 2x kCache32Count entries: one
    158         /// regular cache, one for dithering.
    159         kCache32Count   = kGradient32Length + 1,
    160         kCache32Shift   = 16 - kCache32Bits,
    161         kSqrt32Shift    = 8 - kCache32Bits,
    162 
    163         /// This value is used to *read* the dither cache; it may be 0
    164         /// if dithering is disabled.
    165 #ifdef USE_DITHER_32BIT_GRADIENT
    166         kDitherStride32 = kCache32Count,
    167 #else
    168         kDitherStride32 = 0,
    169 #endif
    170         kDitherStride16 = kCache16Count,
    171         kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1
    172     };
    173 
    174 
    175 protected:
    176     Gradient_Shader(SkFlattenableReadBuffer& );
    177     SkUnitMapper* fMapper;
    178     SkMatrix    fPtsToUnit;     // set by subclass
    179     SkMatrix    fDstToIndex;
    180     SkMatrix::MapXYProc fDstToIndexProc;
    181     TileMode    fTileMode;
    182     TileProc    fTileProc;
    183     int         fColorCount;
    184     uint8_t     fDstToIndexClass;
    185     uint8_t     fFlags;
    186 
    187     struct Rec {
    188         SkFixed     fPos;   // 0...1
    189         uint32_t    fScale; // (1 << 24) / range
    190     };
    191     Rec*        fRecs;
    192 
    193     virtual void flatten(SkFlattenableWriteBuffer& );
    194     const uint16_t*     getCache16() const;
    195     const SkPMColor*    getCache32() const;
    196 
    197     void commonAsABitmap(SkBitmap*) const;
    198     void commonAsAGradient(GradientInfo*) const;
    199 
    200 private:
    201     enum {
    202         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
    203 
    204         kStorageSize = kColorStorageCount * (sizeof(SkColor) + sizeof(Rec))
    205     };
    206     SkColor     fStorage[(kStorageSize + 3) >> 2];
    207     SkColor*    fOrigColors; // original colors, before modulation by paint in setContext
    208     bool        fColorsAreOpaque;
    209 
    210     mutable uint16_t*   fCache16;   // working ptr. If this is NULL, we need to recompute the cache values
    211     mutable SkPMColor*  fCache32;   // working ptr. If this is NULL, we need to recompute the cache values
    212 
    213     mutable uint16_t*   fCache16Storage;    // storage for fCache16, allocated on demand
    214     mutable SkMallocPixelRef* fCache32PixelRef;
    215     mutable unsigned    fCacheAlpha;        // the alpha value we used when we computed the cache. larger than 8bits so we can store uninitialized value
    216 
    217     static void Build16bitCache(uint16_t[], SkColor c0, SkColor c1, int count);
    218     static void Build32bitCache(SkPMColor[], SkColor c0, SkColor c1, int count,
    219                                 U8CPU alpha);
    220     void setCacheAlpha(U8CPU alpha) const;
    221     void initCommon();
    222 
    223     typedef SkShader INHERITED;
    224 };
    225 
    226 static inline unsigned scalarToU16(SkScalar x) {
    227     SkASSERT(x >= 0 && x <= SK_Scalar1);
    228 
    229 #ifdef SK_SCALAR_IS_FLOAT
    230     return (unsigned)(x * 0xFFFF);
    231 #else
    232     return x - (x >> 16);   // probably should be x - (x > 0x7FFF) but that is slower
    233 #endif
    234 }
    235 
    236 Gradient_Shader::Gradient_Shader(const SkColor colors[], const SkScalar pos[],
    237              int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) {
    238     SkASSERT(colorCount > 1);
    239 
    240     fCacheAlpha = 256;  // init to a value that paint.getAlpha() can't return
    241 
    242     fMapper = mapper;
    243     SkSafeRef(mapper);
    244 
    245     SkASSERT((unsigned)mode < SkShader::kTileModeCount);
    246     SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs));
    247     fTileMode = mode;
    248     fTileProc = gTileProcs[mode];
    249 
    250     fCache16 = fCache16Storage = NULL;
    251     fCache32 = NULL;
    252     fCache32PixelRef = NULL;
    253 
    254     /*  Note: we let the caller skip the first and/or last position.
    255         i.e. pos[0] = 0.3, pos[1] = 0.7
    256         In these cases, we insert dummy entries to ensure that the final data
    257         will be bracketed by [0, 1].
    258         i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1
    259 
    260         Thus colorCount (the caller's value, and fColorCount (our value) may
    261         differ by up to 2. In the above example:
    262             colorCount = 2
    263             fColorCount = 4
    264      */
    265     fColorCount = colorCount;
    266     // check if we need to add in dummy start and/or end position/colors
    267     bool dummyFirst = false;
    268     bool dummyLast = false;
    269     if (pos) {
    270         dummyFirst = pos[0] != 0;
    271         dummyLast = pos[colorCount - 1] != SK_Scalar1;
    272         fColorCount += dummyFirst + dummyLast;
    273     }
    274 
    275     if (fColorCount > kColorStorageCount) {
    276         size_t size = sizeof(SkColor) + sizeof(Rec);
    277         fOrigColors = reinterpret_cast<SkColor*>(
    278                                         sk_malloc_throw(size * fColorCount));
    279     }
    280     else {
    281         fOrigColors = fStorage;
    282     }
    283 
    284     // Now copy over the colors, adding the dummies as needed
    285     {
    286         SkColor* origColors = fOrigColors;
    287         if (dummyFirst) {
    288             *origColors++ = colors[0];
    289         }
    290         memcpy(origColors, colors, colorCount * sizeof(SkColor));
    291         if (dummyLast) {
    292             origColors += colorCount;
    293             *origColors = colors[colorCount - 1];
    294         }
    295     }
    296 
    297     fRecs = (Rec*)(fOrigColors + fColorCount);
    298     if (fColorCount > 2) {
    299         Rec* recs = fRecs;
    300         recs->fPos = 0;
    301         //  recs->fScale = 0; // unused;
    302         recs += 1;
    303         if (pos) {
    304             /*  We need to convert the user's array of relative positions into
    305                 fixed-point positions and scale factors. We need these results
    306                 to be strictly monotonic (no two values equal or out of order).
    307                 Hence this complex loop that just jams a zero for the scale
    308                 value if it sees a segment out of order, and it assures that
    309                 we start at 0 and end at 1.0
    310             */
    311             SkFixed prev = 0;
    312             int startIndex = dummyFirst ? 0 : 1;
    313             int count = colorCount + dummyLast;
    314             for (int i = startIndex; i < count; i++) {
    315                 // force the last value to be 1.0
    316                 SkFixed curr;
    317                 if (i == colorCount) {  // we're really at the dummyLast
    318                     curr = SK_Fixed1;
    319                 } else {
    320                     curr = SkScalarToFixed(pos[i]);
    321                 }
    322                 // pin curr withing range
    323                 if (curr < 0) {
    324                     curr = 0;
    325                 } else if (curr > SK_Fixed1) {
    326                     curr = SK_Fixed1;
    327                 }
    328                 recs->fPos = curr;
    329                 if (curr > prev) {
    330                     recs->fScale = (1 << 24) / (curr - prev);
    331                 } else {
    332                     recs->fScale = 0; // ignore this segment
    333                 }
    334                 // get ready for the next value
    335                 prev = curr;
    336                 recs += 1;
    337             }
    338         } else {    // assume even distribution
    339             SkFixed dp = SK_Fixed1 / (colorCount - 1);
    340             SkFixed p = dp;
    341             SkFixed scale = (colorCount - 1) << 8;  // (1 << 24) / dp
    342             for (int i = 1; i < colorCount; i++) {
    343                 recs->fPos   = p;
    344                 recs->fScale = scale;
    345                 recs += 1;
    346                 p += dp;
    347             }
    348         }
    349     }
    350     this->initCommon();
    351 }
    352 
    353 Gradient_Shader::Gradient_Shader(SkFlattenableReadBuffer& buffer) :
    354     INHERITED(buffer) {
    355     fCacheAlpha = 256;
    356 
    357     fMapper = static_cast<SkUnitMapper*>(buffer.readFlattenable());
    358 
    359     fCache16 = fCache16Storage = NULL;
    360     fCache32 = NULL;
    361     fCache32PixelRef = NULL;
    362 
    363     int colorCount = fColorCount = buffer.readU32();
    364     if (colorCount > kColorStorageCount) {
    365         size_t size = sizeof(SkColor) + sizeof(SkPMColor) + sizeof(Rec);
    366         fOrigColors = (SkColor*)sk_malloc_throw(size * colorCount);
    367     } else {
    368         fOrigColors = fStorage;
    369     }
    370     buffer.read(fOrigColors, colorCount * sizeof(SkColor));
    371 
    372     fTileMode = (TileMode)buffer.readU8();
    373     fTileProc = gTileProcs[fTileMode];
    374     fRecs = (Rec*)(fOrigColors + colorCount);
    375     if (colorCount > 2) {
    376         Rec* recs = fRecs;
    377         recs[0].fPos = 0;
    378         for (int i = 1; i < colorCount; i++) {
    379             recs[i].fPos = buffer.readS32();
    380             recs[i].fScale = buffer.readU32();
    381         }
    382     }
    383     SkReadMatrix(&buffer, &fPtsToUnit);
    384     this->initCommon();
    385 }
    386 
    387 Gradient_Shader::~Gradient_Shader() {
    388     if (fCache16Storage) {
    389         sk_free(fCache16Storage);
    390     }
    391     SkSafeUnref(fCache32PixelRef);
    392     if (fOrigColors != fStorage) {
    393         sk_free(fOrigColors);
    394     }
    395     SkSafeUnref(fMapper);
    396 }
    397 
    398 void Gradient_Shader::initCommon() {
    399     fFlags = 0;
    400     unsigned colorAlpha = 0xFF;
    401     for (int i = 0; i < fColorCount; i++) {
    402         colorAlpha &= SkColorGetA(fOrigColors[i]);
    403     }
    404     fColorsAreOpaque = colorAlpha == 0xFF;
    405 }
    406 
    407 void Gradient_Shader::flatten(SkFlattenableWriteBuffer& buffer) {
    408     this->INHERITED::flatten(buffer);
    409     buffer.writeFlattenable(fMapper);
    410     buffer.write32(fColorCount);
    411     buffer.writeMul4(fOrigColors, fColorCount * sizeof(SkColor));
    412     buffer.write8(fTileMode);
    413     if (fColorCount > 2) {
    414         Rec* recs = fRecs;
    415         for (int i = 1; i < fColorCount; i++) {
    416             buffer.write32(recs[i].fPos);
    417             buffer.write32(recs[i].fScale);
    418         }
    419     }
    420     SkWriteMatrix(&buffer, fPtsToUnit);
    421 }
    422 
    423 bool Gradient_Shader::isOpaque() const {
    424     return fColorsAreOpaque;
    425 }
    426 
    427 bool Gradient_Shader::setContext(const SkBitmap& device,
    428                                  const SkPaint& paint,
    429                                  const SkMatrix& matrix) {
    430     if (!this->INHERITED::setContext(device, paint, matrix)) {
    431         return false;
    432     }
    433 
    434     const SkMatrix& inverse = this->getTotalInverse();
    435 
    436     if (!fDstToIndex.setConcat(fPtsToUnit, inverse)) {
    437         return false;
    438     }
    439 
    440     fDstToIndexProc = fDstToIndex.getMapXYProc();
    441     fDstToIndexClass = (uint8_t)SkShader::ComputeMatrixClass(fDstToIndex);
    442 
    443     // now convert our colors in to PMColors
    444     unsigned paintAlpha = this->getPaintAlpha();
    445 
    446     fFlags = this->INHERITED::getFlags();
    447     if (fColorsAreOpaque && paintAlpha == 0xFF) {
    448         fFlags |= kOpaqueAlpha_Flag;
    449     }
    450     // we can do span16 as long as our individual colors are opaque,
    451     // regardless of the paint's alpha
    452     if (fColorsAreOpaque) {
    453         fFlags |= kHasSpan16_Flag;
    454     }
    455 
    456     this->setCacheAlpha(paintAlpha);
    457     return true;
    458 }
    459 
    460 void Gradient_Shader::setCacheAlpha(U8CPU alpha) const {
    461     // if the new alpha differs from the previous time we were called, inval our cache
    462     // this will trigger the cache to be rebuilt.
    463     // we don't care about the first time, since the cache ptrs will already be NULL
    464     if (fCacheAlpha != alpha) {
    465         fCache16 = NULL;            // inval the cache
    466         fCache32 = NULL;            // inval the cache
    467         fCacheAlpha = alpha;        // record the new alpha
    468         // inform our subclasses
    469         if (fCache32PixelRef) {
    470             fCache32PixelRef->notifyPixelsChanged();
    471         }
    472     }
    473 }
    474 
    475 static inline int blend8(int a, int b, int scale) {
    476     SkASSERT(a == SkToU8(a));
    477     SkASSERT(b == SkToU8(b));
    478     SkASSERT(scale >= 0 && scale <= 256);
    479     return a + ((b - a) * scale >> 8);
    480 }
    481 
    482 static inline uint32_t dot8_blend_packed32(uint32_t s0, uint32_t s1,
    483                                            int blend) {
    484 #if 0
    485     int a = blend8(SkGetPackedA32(s0), SkGetPackedA32(s1), blend);
    486     int r = blend8(SkGetPackedR32(s0), SkGetPackedR32(s1), blend);
    487     int g = blend8(SkGetPackedG32(s0), SkGetPackedG32(s1), blend);
    488     int b = blend8(SkGetPackedB32(s0), SkGetPackedB32(s1), blend);
    489 
    490     return SkPackARGB32(a, r, g, b);
    491 #else
    492     int otherBlend = 256 - blend;
    493 
    494 #if 0
    495     U32 t0 = (((s0 & 0xFF00FF) * blend + (s1 & 0xFF00FF) * otherBlend) >> 8) & 0xFF00FF;
    496     U32 t1 = (((s0 >> 8) & 0xFF00FF) * blend + ((s1 >> 8) & 0xFF00FF) * otherBlend) & 0xFF00FF00;
    497     SkASSERT((t0 & t1) == 0);
    498     return t0 | t1;
    499 #else
    500     return  ((((s0 & 0xFF00FF) * blend + (s1 & 0xFF00FF) * otherBlend) >> 8) & 0xFF00FF) |
    501             ((((s0 >> 8) & 0xFF00FF) * blend + ((s1 >> 8) & 0xFF00FF) * otherBlend) & 0xFF00FF00);
    502 #endif
    503 
    504 #endif
    505 }
    506 
    507 #define Fixed_To_Dot8(x)        (((x) + 0x80) >> 8)
    508 
    509 /** We take the original colors, not our premultiplied PMColors, since we can
    510     build a 16bit table as long as the original colors are opaque, even if the
    511     paint specifies a non-opaque alpha.
    512 */
    513 void Gradient_Shader::Build16bitCache(uint16_t cache[], SkColor c0, SkColor c1,
    514                                       int count) {
    515     SkASSERT(count > 1);
    516     SkASSERT(SkColorGetA(c0) == 0xFF);
    517     SkASSERT(SkColorGetA(c1) == 0xFF);
    518 
    519     SkFixed r = SkColorGetR(c0);
    520     SkFixed g = SkColorGetG(c0);
    521     SkFixed b = SkColorGetB(c0);
    522 
    523     SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
    524     SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
    525     SkFixed db = SkIntToFixed(SkColorGetB(c1) - b) / (count - 1);
    526 
    527     r = SkIntToFixed(r) + 0x8000;
    528     g = SkIntToFixed(g) + 0x8000;
    529     b = SkIntToFixed(b) + 0x8000;
    530 
    531     do {
    532         unsigned rr = r >> 16;
    533         unsigned gg = g >> 16;
    534         unsigned bb = b >> 16;
    535         cache[0] = SkPackRGB16(SkR32ToR16(rr), SkG32ToG16(gg), SkB32ToB16(bb));
    536         cache[kCache16Count] = SkDitherPack888ToRGB16(rr, gg, bb);
    537         cache += 1;
    538         r += dr;
    539         g += dg;
    540         b += db;
    541     } while (--count != 0);
    542 }
    543 
    544 /*
    545  *  2x2 dither a fixed-point color component (8.16) down to 8, matching the
    546  *  semantics of how we 2x2 dither 32->16
    547  */
    548 static inline U8CPU dither_fixed_to_8(SkFixed n) {
    549     n >>= 8;
    550     return ((n << 1) - ((n >> 8 << 8) | (n >> 8))) >> 8;
    551 }
    552 
    553 /*
    554  *  For dithering with premultiply, we want to ceiling the alpha component,
    555  *  to ensure that it is always >= any color component.
    556  */
    557 static inline U8CPU dither_ceil_fixed_to_8(SkFixed n) {
    558     n >>= 8;
    559     return ((n << 1) - (n | (n >> 8))) >> 8;
    560 }
    561 
    562 void Gradient_Shader::Build32bitCache(SkPMColor cache[], SkColor c0, SkColor c1,
    563                                       int count, U8CPU paintAlpha) {
    564     SkASSERT(count > 1);
    565 
    566     // need to apply paintAlpha to our two endpoints
    567     SkFixed a = SkMulDiv255Round(SkColorGetA(c0), paintAlpha);
    568     SkFixed da;
    569     {
    570         int tmp = SkMulDiv255Round(SkColorGetA(c1), paintAlpha);
    571         da = SkIntToFixed(tmp - a) / (count - 1);
    572     }
    573 
    574     SkFixed r = SkColorGetR(c0);
    575     SkFixed g = SkColorGetG(c0);
    576     SkFixed b = SkColorGetB(c0);
    577     SkFixed dr = SkIntToFixed(SkColorGetR(c1) - r) / (count - 1);
    578     SkFixed dg = SkIntToFixed(SkColorGetG(c1) - g) / (count - 1);
    579     SkFixed db = SkIntToFixed(SkColorGetB(c1) - b) / (count - 1);
    580 
    581     a = SkIntToFixed(a) + 0x8000;
    582     r = SkIntToFixed(r) + 0x8000;
    583     g = SkIntToFixed(g) + 0x8000;
    584     b = SkIntToFixed(b) + 0x8000;
    585 
    586     do {
    587         cache[0] = SkPremultiplyARGBInline(a >> 16, r >> 16, g >> 16, b >> 16);
    588         cache[kCache32Count] =
    589             SkPremultiplyARGBInline(dither_ceil_fixed_to_8(a),
    590                                     dither_fixed_to_8(r),
    591                                     dither_fixed_to_8(g),
    592                                     dither_fixed_to_8(b));
    593         cache += 1;
    594         a += da;
    595         r += dr;
    596         g += dg;
    597         b += db;
    598     } while (--count != 0);
    599 }
    600 
    601 static inline int SkFixedToFFFF(SkFixed x) {
    602     SkASSERT((unsigned)x <= SK_Fixed1);
    603     return x - (x >> 16);
    604 }
    605 
    606 static inline U16CPU bitsTo16(unsigned x, const unsigned bits) {
    607     SkASSERT(x < (1U << bits));
    608     if (6 == bits) {
    609         return (x << 10) | (x << 4) | (x >> 2);
    610     }
    611     if (8 == bits) {
    612         return (x << 8) | x;
    613     }
    614     sk_throw();
    615     return 0;
    616 }
    617 
    618 /** We duplicate the last value in each half of the cache so that
    619     interpolation doesn't have to special-case being at the last point.
    620 */
    621 static void complete_16bit_cache(uint16_t* cache, int stride) {
    622     cache[stride - 1] = cache[stride - 2];
    623     cache[2 * stride - 1] = cache[2 * stride - 2];
    624 }
    625 
    626 const uint16_t* Gradient_Shader::getCache16() const {
    627     if (fCache16 == NULL) {
    628         // double the count for dither entries
    629         const int entryCount = kCache16Count * 2;
    630         const size_t allocSize = sizeof(uint16_t) * entryCount;
    631 
    632         if (fCache16Storage == NULL) { // set the storage and our working ptr
    633             fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
    634         }
    635         fCache16 = fCache16Storage;
    636         if (fColorCount == 2) {
    637             Build16bitCache(fCache16, fOrigColors[0], fOrigColors[1],
    638                             kGradient16Length);
    639         } else {
    640             Rec* rec = fRecs;
    641             int prevIndex = 0;
    642             for (int i = 1; i < fColorCount; i++) {
    643                 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache16Shift;
    644                 SkASSERT(nextIndex < kCache16Count);
    645 
    646                 if (nextIndex > prevIndex)
    647                     Build16bitCache(fCache16 + prevIndex, fOrigColors[i-1], fOrigColors[i], nextIndex - prevIndex + 1);
    648                 prevIndex = nextIndex;
    649             }
    650             // one extra space left over at the end for complete_16bit_cache()
    651             SkASSERT(prevIndex == kGradient16Length - 1);
    652         }
    653 
    654         if (fMapper) {
    655             fCache16Storage = (uint16_t*)sk_malloc_throw(allocSize);
    656             uint16_t* linear = fCache16;         // just computed linear data
    657             uint16_t* mapped = fCache16Storage;  // storage for mapped data
    658             SkUnitMapper* map = fMapper;
    659             for (int i = 0; i < kGradient16Length; i++) {
    660                 int index = map->mapUnit16(bitsTo16(i, kCache16Bits)) >> kCache16Shift;
    661                 mapped[i] = linear[index];
    662                 mapped[i + kCache16Count] = linear[index + kCache16Count];
    663             }
    664             sk_free(fCache16);
    665             fCache16 = fCache16Storage;
    666         }
    667         complete_16bit_cache(fCache16, kCache16Count);
    668     }
    669     return fCache16;
    670 }
    671 
    672 /** We duplicate the last value in each half of the cache so that
    673     interpolation doesn't have to special-case being at the last point.
    674 */
    675 static void complete_32bit_cache(SkPMColor* cache, int stride) {
    676     cache[stride - 1] = cache[stride - 2];
    677     cache[2 * stride - 1] = cache[2 * stride - 2];
    678 }
    679 
    680 const SkPMColor* Gradient_Shader::getCache32() const {
    681     if (fCache32 == NULL) {
    682         // double the count for dither entries
    683         const int entryCount = kCache32Count * 2;
    684         const size_t allocSize = sizeof(SkPMColor) * entryCount;
    685 
    686         if (NULL == fCache32PixelRef) {
    687             fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
    688                                           (NULL, allocSize, NULL));
    689         }
    690         fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
    691         if (fColorCount == 2) {
    692             Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
    693                             kGradient32Length, fCacheAlpha);
    694         } else {
    695             Rec* rec = fRecs;
    696             int prevIndex = 0;
    697             for (int i = 1; i < fColorCount; i++) {
    698                 int nextIndex = SkFixedToFFFF(rec[i].fPos) >> kCache32Shift;
    699                 SkASSERT(nextIndex < kGradient32Length);
    700 
    701                 if (nextIndex > prevIndex)
    702                     Build32bitCache(fCache32 + prevIndex, fOrigColors[i-1],
    703                                     fOrigColors[i],
    704                                     nextIndex - prevIndex + 1, fCacheAlpha);
    705                 prevIndex = nextIndex;
    706             }
    707             SkASSERT(prevIndex == kGradient32Length - 1);
    708         }
    709 
    710         if (fMapper) {
    711             SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
    712                                                  (NULL, allocSize, NULL));
    713             SkPMColor* linear = fCache32;           // just computed linear data
    714             SkPMColor* mapped = (SkPMColor*)newPR->getAddr();    // storage for mapped data
    715             SkUnitMapper* map = fMapper;
    716             for (int i = 0; i < kGradient32Length; i++) {
    717                 int index = map->mapUnit16((i << 8) | i) >> 8;
    718                 mapped[i] = linear[index];
    719                 mapped[i + kCache32Count] = linear[index + kCache32Count];
    720             }
    721             fCache32PixelRef->unref();
    722             fCache32PixelRef = newPR;
    723             fCache32 = (SkPMColor*)newPR->getAddr();
    724         }
    725         complete_32bit_cache(fCache32, kCache32Count);
    726     }
    727     return fCache32;
    728 }
    729 
    730 /*
    731  *  Because our caller might rebuild the same (logically the same) gradient
    732  *  over and over, we'd like to return exactly the same "bitmap" if possible,
    733  *  allowing the client to utilize a cache of our bitmap (e.g. with a GPU).
    734  *  To do that, we maintain a private cache of built-bitmaps, based on our
    735  *  colors and positions. Note: we don't try to flatten the fMapper, so if one
    736  *  is present, we skip the cache for now.
    737  */
    738 void Gradient_Shader::commonAsABitmap(SkBitmap* bitmap) const {
    739     // our caller assumes no external alpha, so we ensure that our cache is
    740     // built with 0xFF
    741     this->setCacheAlpha(0xFF);
    742 
    743     // don't have a way to put the mapper into our cache-key yet
    744     if (fMapper) {
    745         // force our cahce32pixelref to be built
    746         (void)this->getCache32();
    747         bitmap->setConfig(SkBitmap::kARGB_8888_Config, kGradient32Length, 1);
    748         bitmap->setPixelRef(fCache32PixelRef);
    749         return;
    750     }
    751 
    752     // build our key: [numColors + colors[] + {positions[]} ]
    753     int count = 1 + fColorCount;
    754     if (fColorCount > 2) {
    755         count += fColorCount - 1;    // fRecs[].fPos
    756     }
    757 
    758     SkAutoSTMalloc<16, int32_t> storage(count);
    759     int32_t* buffer = storage.get();
    760 
    761     *buffer++ = fColorCount;
    762     memcpy(buffer, fOrigColors, fColorCount * sizeof(SkColor));
    763     buffer += fColorCount;
    764     if (fColorCount > 2) {
    765         for (int i = 1; i < fColorCount; i++) {
    766             *buffer++ = fRecs[i].fPos;
    767         }
    768     }
    769     SkASSERT(buffer - storage.get() == count);
    770 
    771     ///////////////////////////////////
    772 
    773     SK_DECLARE_STATIC_MUTEX(gMutex);
    774     static SkBitmapCache* gCache;
    775     // each cache cost 1K of RAM, since each bitmap will be 1x256 at 32bpp
    776     static const int MAX_NUM_CACHED_GRADIENT_BITMAPS = 32;
    777     SkAutoMutexAcquire ama(gMutex);
    778 
    779     if (NULL == gCache) {
    780         gCache = new SkBitmapCache(MAX_NUM_CACHED_GRADIENT_BITMAPS);
    781     }
    782     size_t size = count * sizeof(int32_t);
    783 
    784     if (!gCache->find(storage.get(), size, bitmap)) {
    785         // force our cahce32pixelref to be built
    786         (void)this->getCache32();
    787         // Only expose the linear section of the cache; don't let the caller
    788         // know about the padding at the end to make interpolation faster.
    789         bitmap->setConfig(SkBitmap::kARGB_8888_Config, kGradient32Length, 1);
    790         bitmap->setPixelRef(fCache32PixelRef);
    791 
    792         gCache->add(storage.get(), size, *bitmap);
    793     }
    794 }
    795 
    796 void Gradient_Shader::commonAsAGradient(GradientInfo* info) const {
    797     if (info) {
    798         if (info->fColorCount >= fColorCount) {
    799             if (info->fColors) {
    800                 memcpy(info->fColors, fOrigColors,
    801                        fColorCount * sizeof(SkColor));
    802             }
    803             if (info->fColorOffsets) {
    804                 if (fColorCount == 2) {
    805                     info->fColorOffsets[0] = 0;
    806                     info->fColorOffsets[1] = SK_Scalar1;
    807                 } else if (fColorCount > 2) {
    808                     for (int i = 0; i < fColorCount; i++)
    809                         info->fColorOffsets[i] = SkFixedToScalar(fRecs[i].fPos);
    810                 }
    811             }
    812         }
    813         info->fColorCount = fColorCount;
    814         info->fTileMode = fTileMode;
    815     }
    816 }
    817 
    818 ///////////////////////////////////////////////////////////////////////////////
    819 
    820 static void pts_to_unit_matrix(const SkPoint pts[2], SkMatrix* matrix) {
    821     SkVector    vec = pts[1] - pts[0];
    822     SkScalar    mag = vec.length();
    823     SkScalar    inv = mag ? SkScalarInvert(mag) : 0;
    824 
    825     vec.scale(inv);
    826     matrix->setSinCos(-vec.fY, vec.fX, pts[0].fX, pts[0].fY);
    827     matrix->postTranslate(-pts[0].fX, -pts[0].fY);
    828     matrix->postScale(inv, inv);
    829 }
    830 
    831 ///////////////////////////////////////////////////////////////////////////////
    832 
    833 class Linear_Gradient : public Gradient_Shader {
    834 public:
    835     Linear_Gradient(const SkPoint pts[2],
    836                     const SkColor colors[], const SkScalar pos[], int colorCount,
    837                     SkShader::TileMode mode, SkUnitMapper* mapper)
    838         : Gradient_Shader(colors, pos, colorCount, mode, mapper),
    839           fStart(pts[0]),
    840           fEnd(pts[1])
    841     {
    842         pts_to_unit_matrix(pts, &fPtsToUnit);
    843     }
    844 
    845     virtual bool setContext(const SkBitmap&, const SkPaint&, const SkMatrix&) SK_OVERRIDE;
    846     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
    847     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
    848     virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*,
    849                              SkScalar* twoPointRadialParams) const SK_OVERRIDE;
    850     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE;
    851 
    852     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
    853         return SkNEW_ARGS(Linear_Gradient, (buffer));
    854     }
    855 
    856     virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE {
    857         this->INHERITED::flatten(buffer);
    858         buffer.writeScalar(fStart.fX);
    859         buffer.writeScalar(fStart.fY);
    860         buffer.writeScalar(fEnd.fX);
    861         buffer.writeScalar(fEnd.fY);
    862     }
    863 
    864     SK_DECLARE_FLATTENABLE_REGISTRAR()
    865 
    866 protected:
    867     Linear_Gradient(SkFlattenableReadBuffer& buffer)
    868         : Gradient_Shader(buffer),
    869           fStart(unflatten_point(buffer)),
    870           fEnd(unflatten_point(buffer)) {
    871     }
    872     virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
    873 
    874 private:
    875     typedef Gradient_Shader INHERITED;
    876     const SkPoint fStart;
    877     const SkPoint fEnd;
    878 };
    879 
    880 bool Linear_Gradient::setContext(const SkBitmap& device, const SkPaint& paint,
    881                                  const SkMatrix& matrix) {
    882     if (!this->INHERITED::setContext(device, paint, matrix)) {
    883         return false;
    884     }
    885 
    886     unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask;
    887     if ((fDstToIndex.getType() & ~mask) == 0) {
    888         fFlags |= SkShader::kConstInY32_Flag;
    889         if ((fFlags & SkShader::kHasSpan16_Flag) && !paint.isDither()) {
    890             // only claim this if we do have a 16bit mode (i.e. none of our
    891             // colors have alpha), and if we are not dithering (which obviously
    892             // is not const in Y).
    893             fFlags |= SkShader::kConstInY16_Flag;
    894         }
    895     }
    896     return true;
    897 }
    898 
    899 #define NO_CHECK_ITER               \
    900     do {                            \
    901     unsigned fi = fx >> Gradient_Shader::kCache32Shift; \
    902     SkASSERT(fi <= 0xFF);           \
    903     fx += dx;                       \
    904     *dstC++ = cache[toggle + fi];   \
    905     toggle ^= Gradient_Shader::kDitherStride32; \
    906     } while (0)
    907 
    908 namespace {
    909 
    910 typedef void (*LinearShadeProc)(TileProc proc, SkFixed dx, SkFixed fx,
    911                                 SkPMColor* dstC, const SkPMColor* cache,
    912                                 int toggle, int count);
    913 
    914 // This function is deprecated, and will be replaced by
    915 // shadeSpan_linear_vertical_lerp() once Chrome has been weaned off of it.
    916 void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
    917                                SkPMColor* SK_RESTRICT dstC,
    918                                const SkPMColor* SK_RESTRICT cache,
    919                                int toggle, int count) {
    920     // We're a vertical gradient, so no change in a span.
    921     // If colors change sharply across the gradient, dithering is
    922     // insufficient (it subsamples the color space) and we need to lerp.
    923     unsigned fullIndex = proc(fx);
    924     unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits);
    925     sk_memset32_dither(dstC,
    926             cache[toggle + fi],
    927             cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi],
    928             count);
    929 }
    930 
    931 // Linear interpolation (lerp) is unnecessary if there are no sharp
    932 // discontinuities in the gradient - which must be true if there are
    933 // only 2 colors - but it's cheap.
    934 void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
    935                                     SkPMColor* SK_RESTRICT dstC,
    936                                     const SkPMColor* SK_RESTRICT cache,
    937                                     int toggle, int count) {
    938     // We're a vertical gradient, so no change in a span.
    939     // If colors change sharply across the gradient, dithering is
    940     // insufficient (it subsamples the color space) and we need to lerp.
    941     unsigned fullIndex = proc(fx);
    942     unsigned fi = fullIndex >> (16 - Gradient_Shader::kCache32Bits);
    943     unsigned remainder = fullIndex & Gradient_Shader::kLerpRemainderMask32;
    944     SkPMColor lerp =
    945         SkFastFourByteInterp(
    946             cache[toggle + fi + 1],
    947             cache[toggle + fi], remainder);
    948     SkPMColor dlerp =
    949         SkFastFourByteInterp(
    950             cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi + 1],
    951             cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi], remainder);
    952     sk_memset32_dither(dstC, lerp, dlerp, count);
    953 }
    954 
    955 void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
    956                             SkPMColor* SK_RESTRICT dstC,
    957                             const SkPMColor* SK_RESTRICT cache,
    958                             int toggle, int count) {
    959     SkClampRange range;
    960     range.init(fx, dx, count, 0, Gradient_Shader::kGradient32Length);
    961 
    962     if ((count = range.fCount0) > 0) {
    963         sk_memset32_dither(dstC,
    964             cache[toggle + range.fV0],
    965             cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV0],
    966             count);
    967         dstC += count;
    968     }
    969     if ((count = range.fCount1) > 0) {
    970         int unroll = count >> 3;
    971         fx = range.fFx1;
    972         for (int i = 0; i < unroll; i++) {
    973             NO_CHECK_ITER;  NO_CHECK_ITER;
    974             NO_CHECK_ITER;  NO_CHECK_ITER;
    975             NO_CHECK_ITER;  NO_CHECK_ITER;
    976             NO_CHECK_ITER;  NO_CHECK_ITER;
    977         }
    978         if ((count &= 7) > 0) {
    979             do {
    980                 NO_CHECK_ITER;
    981             } while (--count != 0);
    982         }
    983     }
    984     if ((count = range.fCount2) > 0) {
    985         sk_memset32_dither(dstC,
    986             cache[toggle + range.fV1],
    987             cache[(toggle ^ Gradient_Shader::kDitherStride32) + range.fV1],
    988             count);
    989     }
    990 }
    991 
    992 void shadeSpan_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
    993                              SkPMColor* SK_RESTRICT dstC,
    994                              const SkPMColor* SK_RESTRICT cache,
    995                              int toggle, int count) {
    996     do {
    997         unsigned fi = mirror_8bits(fx >> 8);
    998         SkASSERT(fi <= 0xFF);
    999         fx += dx;
   1000         *dstC++ = cache[toggle + fi];
   1001         toggle ^= Gradient_Shader::kDitherStride32;
   1002     } while (--count != 0);
   1003 }
   1004 
   1005 void shadeSpan_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx,
   1006         SkPMColor* SK_RESTRICT dstC,
   1007         const SkPMColor* SK_RESTRICT cache,
   1008         int toggle, int count) {
   1009     do {
   1010         unsigned fi = repeat_8bits(fx >> 8);
   1011         SkASSERT(fi <= 0xFF);
   1012         fx += dx;
   1013         *dstC++ = cache[toggle + fi];
   1014         toggle ^= Gradient_Shader::kDitherStride32;
   1015     } while (--count != 0);
   1016 }
   1017 
   1018 }
   1019 
   1020 void Linear_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
   1021                                 int count) {
   1022     SkASSERT(count > 0);
   1023 
   1024     SkPoint             srcPt;
   1025     SkMatrix::MapXYProc dstProc = fDstToIndexProc;
   1026     TileProc            proc = fTileProc;
   1027     const SkPMColor* SK_RESTRICT cache = this->getCache32();
   1028 #ifdef USE_DITHER_32BIT_GRADIENT
   1029     int                 toggle = ((x ^ y) & 1) * kDitherStride32;
   1030 #else
   1031     int toggle = 0;
   1032 #endif
   1033 
   1034     if (fDstToIndexClass != kPerspective_MatrixClass) {
   1035         dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
   1036                              SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1037         SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
   1038 
   1039         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   1040             SkFixed dxStorage[1];
   1041             (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
   1042             dx = dxStorage[0];
   1043         } else {
   1044             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   1045             dx = SkScalarToFixed(fDstToIndex.getScaleX());
   1046         }
   1047 
   1048         LinearShadeProc shadeProc = shadeSpan_linear_repeat;
   1049         if (SkFixedNearlyZero(dx)) {
   1050 #ifdef SK_SIMPLE_TWOCOLOR_VERTICAL_GRADIENTS
   1051             if (fColorCount > 2) {
   1052                 shadeProc = shadeSpan_linear_vertical_lerp;
   1053             } else {
   1054                 shadeProc = shadeSpan_linear_vertical;
   1055             }
   1056 #else
   1057             shadeProc = shadeSpan_linear_vertical_lerp;
   1058 #endif
   1059         } else if (proc == clamp_tileproc) {
   1060             shadeProc = shadeSpan_linear_clamp;
   1061         } else if (proc == mirror_tileproc) {
   1062             shadeProc = shadeSpan_linear_mirror;
   1063         } else {
   1064             SkASSERT(proc == repeat_tileproc);
   1065         }
   1066         (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
   1067     } else {
   1068         SkScalar    dstX = SkIntToScalar(x);
   1069         SkScalar    dstY = SkIntToScalar(y);
   1070         do {
   1071             dstProc(fDstToIndex, dstX, dstY, &srcPt);
   1072             unsigned fi = proc(SkScalarToFixed(srcPt.fX));
   1073             SkASSERT(fi <= 0xFFFF);
   1074             *dstC++ = cache[toggle + (fi >> kCache32Shift)];
   1075             toggle ^= Gradient_Shader::kDitherStride32;
   1076             dstX += SK_Scalar1;
   1077         } while (--count != 0);
   1078     }
   1079 }
   1080 
   1081 SkShader::BitmapType Linear_Gradient::asABitmap(SkBitmap* bitmap,
   1082                                                 SkMatrix* matrix,
   1083                                                 TileMode xy[],
   1084                                         SkScalar* twoPointRadialParams) const {
   1085     if (bitmap) {
   1086         this->commonAsABitmap(bitmap);
   1087     }
   1088     if (matrix) {
   1089         matrix->setScale(SkIntToScalar(kGradient32Length), SK_Scalar1);
   1090         matrix->preConcat(fPtsToUnit);
   1091     }
   1092     if (xy) {
   1093         xy[0] = fTileMode;
   1094         xy[1] = kClamp_TileMode;
   1095     }
   1096     return kDefault_BitmapType;
   1097 }
   1098 
   1099 SkShader::GradientType Linear_Gradient::asAGradient(GradientInfo* info) const {
   1100     if (info) {
   1101         commonAsAGradient(info);
   1102         info->fPoint[0] = fStart;
   1103         info->fPoint[1] = fEnd;
   1104     }
   1105     return kLinear_GradientType;
   1106 }
   1107 
   1108 static void dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
   1109                             int count) {
   1110     if (reinterpret_cast<uintptr_t>(dst) & 2) {
   1111         *dst++ = value;
   1112         count -= 1;
   1113         SkTSwap(value, other);
   1114     }
   1115 
   1116     sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1);
   1117 
   1118     if (count & 1) {
   1119         dst[count - 1] = value;
   1120     }
   1121 }
   1122 
   1123 #define NO_CHECK_ITER_16                \
   1124     do {                                \
   1125     unsigned fi = fx >> Gradient_Shader::kCache16Shift;  \
   1126     SkASSERT(fi < Gradient_Shader::kCache16Count);       \
   1127     fx += dx;                           \
   1128     *dstC++ = cache[toggle + fi];       \
   1129     toggle ^= Gradient_Shader::kDitherStride16;            \
   1130     } while (0)
   1131 
   1132 namespace {
   1133 
   1134 typedef void (*LinearShade16Proc)(TileProc proc, SkFixed dx, SkFixed fx,
   1135                                   uint16_t* dstC, const uint16_t* cache,
   1136                                   int toggle, int count);
   1137 
   1138 void shadeSpan16_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
   1139                                  uint16_t* SK_RESTRICT dstC,
   1140                                  const uint16_t* SK_RESTRICT cache,
   1141                                  int toggle, int count) {
   1142     // we're a vertical gradient, so no change in a span
   1143     unsigned fi = proc(fx) >> Gradient_Shader::kCache16Shift;
   1144     SkASSERT(fi < Gradient_Shader::kCache16Count);
   1145     dither_memset16(dstC, cache[toggle + fi],
   1146         cache[(toggle ^ Gradient_Shader::kDitherStride16) + fi], count);
   1147 
   1148 }
   1149 
   1150 void shadeSpan16_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
   1151                               uint16_t* SK_RESTRICT dstC,
   1152                               const uint16_t* SK_RESTRICT cache,
   1153                               int toggle, int count) {
   1154     SkClampRange range;
   1155     range.init(fx, dx, count, 0, Gradient_Shader::kGradient16Length);
   1156 
   1157     if ((count = range.fCount0) > 0) {
   1158         dither_memset16(dstC,
   1159             cache[toggle + range.fV0],
   1160             cache[(toggle ^ Gradient_Shader::kDitherStride16) + range.fV0],
   1161             count);
   1162         dstC += count;
   1163     }
   1164     if ((count = range.fCount1) > 0) {
   1165         int unroll = count >> 3;
   1166         fx = range.fFx1;
   1167         for (int i = 0; i < unroll; i++) {
   1168             NO_CHECK_ITER_16;  NO_CHECK_ITER_16;
   1169             NO_CHECK_ITER_16;  NO_CHECK_ITER_16;
   1170             NO_CHECK_ITER_16;  NO_CHECK_ITER_16;
   1171             NO_CHECK_ITER_16;  NO_CHECK_ITER_16;
   1172         }
   1173         if ((count &= 7) > 0) {
   1174             do {
   1175                 NO_CHECK_ITER_16;
   1176             } while (--count != 0);
   1177         }
   1178     }
   1179     if ((count = range.fCount2) > 0) {
   1180         dither_memset16(dstC,
   1181             cache[toggle + range.fV1],
   1182             cache[(toggle ^ Gradient_Shader::kDitherStride16) + range.fV1],
   1183             count);
   1184     }
   1185 }
   1186 
   1187 void shadeSpan16_linear_mirror(TileProc proc, SkFixed dx, SkFixed fx,
   1188                                uint16_t* SK_RESTRICT dstC,
   1189                                const uint16_t* SK_RESTRICT cache,
   1190                                int toggle, int count) {
   1191     do {
   1192         unsigned fi = mirror_bits(fx >> Gradient_Shader::kCache16Shift,
   1193                                         Gradient_Shader::kCache16Bits);
   1194         SkASSERT(fi < Gradient_Shader::kCache16Count);
   1195         fx += dx;
   1196         *dstC++ = cache[toggle + fi];
   1197         toggle ^= Gradient_Shader::kDitherStride16;
   1198     } while (--count != 0);
   1199 }
   1200 
   1201 void shadeSpan16_linear_repeat(TileProc proc, SkFixed dx, SkFixed fx,
   1202                                uint16_t* SK_RESTRICT dstC,
   1203                                const uint16_t* SK_RESTRICT cache,
   1204                                int toggle, int count) {
   1205     SkASSERT(proc == repeat_tileproc);
   1206     do {
   1207         unsigned fi = repeat_bits(fx >> Gradient_Shader::kCache16Shift,
   1208                                   Gradient_Shader::kCache16Bits);
   1209         SkASSERT(fi < Gradient_Shader::kCache16Count);
   1210         fx += dx;
   1211         *dstC++ = cache[toggle + fi];
   1212         toggle ^= Gradient_Shader::kDitherStride16;
   1213     } while (--count != 0);
   1214 }
   1215 }
   1216 
   1217 void Linear_Gradient::shadeSpan16(int x, int y,
   1218                                   uint16_t* SK_RESTRICT dstC, int count) {
   1219     SkASSERT(count > 0);
   1220 
   1221     SkPoint             srcPt;
   1222     SkMatrix::MapXYProc dstProc = fDstToIndexProc;
   1223     TileProc            proc = fTileProc;
   1224     const uint16_t* SK_RESTRICT cache = this->getCache16();
   1225     int                 toggle = ((x ^ y) & 1) * kDitherStride16;
   1226 
   1227     if (fDstToIndexClass != kPerspective_MatrixClass) {
   1228         dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
   1229                              SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1230         SkFixed dx, fx = SkScalarToFixed(srcPt.fX);
   1231 
   1232         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   1233             SkFixed dxStorage[1];
   1234             (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), dxStorage, NULL);
   1235             dx = dxStorage[0];
   1236         } else {
   1237             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   1238             dx = SkScalarToFixed(fDstToIndex.getScaleX());
   1239         }
   1240 
   1241         LinearShade16Proc shadeProc = shadeSpan16_linear_repeat;
   1242         if (SkFixedNearlyZero(dx)) {
   1243             shadeProc = shadeSpan16_linear_vertical;
   1244         } else if (proc == clamp_tileproc) {
   1245             shadeProc = shadeSpan16_linear_clamp;
   1246         } else if (proc == mirror_tileproc) {
   1247             shadeProc = shadeSpan16_linear_mirror;
   1248         } else {
   1249             SkASSERT(proc == repeat_tileproc);
   1250         }
   1251         (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
   1252     } else {
   1253         SkScalar    dstX = SkIntToScalar(x);
   1254         SkScalar    dstY = SkIntToScalar(y);
   1255         do {
   1256             dstProc(fDstToIndex, dstX, dstY, &srcPt);
   1257             unsigned fi = proc(SkScalarToFixed(srcPt.fX));
   1258             SkASSERT(fi <= 0xFFFF);
   1259 
   1260             int index = fi >> kCache16Shift;
   1261             *dstC++ = cache[toggle + index];
   1262             toggle ^= Gradient_Shader::kDitherStride16;
   1263 
   1264             dstX += SK_Scalar1;
   1265         } while (--count != 0);
   1266     }
   1267 }
   1268 
   1269 ///////////////////////////////////////////////////////////////////////////////
   1270 
   1271 #define kSQRT_TABLE_BITS    11
   1272 #define kSQRT_TABLE_SIZE    (1 << kSQRT_TABLE_BITS)
   1273 
   1274 #include "SkRadialGradient_Table.h"
   1275 
   1276 #if defined(SK_BUILD_FOR_WIN32) && defined(SK_DEBUG)
   1277 
   1278 #include <stdio.h>
   1279 
   1280 void SkRadialGradient_BuildTable() {
   1281     // build it 0..127 x 0..127, so we use 2^15 - 1 in the numerator for our "fixed" table
   1282 
   1283     FILE* file = ::fopen("SkRadialGradient_Table.h", "w");
   1284     SkASSERT(file);
   1285     ::fprintf(file, "static const uint8_t gSqrt8Table[] = {\n");
   1286 
   1287     for (int i = 0; i < kSQRT_TABLE_SIZE; i++) {
   1288         if ((i & 15) == 0) {
   1289             ::fprintf(file, "\t");
   1290         }
   1291 
   1292         uint8_t value = SkToU8(SkFixedSqrt(i * SK_Fixed1 / kSQRT_TABLE_SIZE) >> 8);
   1293 
   1294         ::fprintf(file, "0x%02X", value);
   1295         if (i < kSQRT_TABLE_SIZE-1) {
   1296             ::fprintf(file, ", ");
   1297         }
   1298         if ((i & 15) == 15) {
   1299             ::fprintf(file, "\n");
   1300         }
   1301     }
   1302     ::fprintf(file, "};\n");
   1303     ::fclose(file);
   1304 }
   1305 
   1306 #endif
   1307 
   1308 
   1309 static void rad_to_unit_matrix(const SkPoint& center, SkScalar radius,
   1310                                SkMatrix* matrix) {
   1311     SkScalar    inv = SkScalarInvert(radius);
   1312 
   1313     matrix->setTranslate(-center.fX, -center.fY);
   1314     matrix->postScale(inv, inv);
   1315 }
   1316 
   1317 
   1318 namespace {
   1319 
   1320 typedef void (* RadialShade16Proc)(SkScalar sfx, SkScalar sdx,
   1321         SkScalar sfy, SkScalar sdy,
   1322         uint16_t* dstC, const uint16_t* cache,
   1323         int toggle, int count);
   1324 
   1325 void shadeSpan16_radial_clamp(SkScalar sfx, SkScalar sdx,
   1326         SkScalar sfy, SkScalar sdy,
   1327         uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache,
   1328         int toggle, int count) {
   1329     const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
   1330 
   1331     /* knock these down so we can pin against +- 0x7FFF, which is an
   1332        immediate load, rather than 0xFFFF which is slower. This is a
   1333        compromise, since it reduces our precision, but that appears
   1334        to be visually OK. If we decide this is OK for all of our cases,
   1335        we could (it seems) put this scale-down into fDstToIndex,
   1336        to avoid having to do these extra shifts each time.
   1337     */
   1338     SkFixed fx = SkScalarToFixed(sfx) >> 1;
   1339     SkFixed dx = SkScalarToFixed(sdx) >> 1;
   1340     SkFixed fy = SkScalarToFixed(sfy) >> 1;
   1341     SkFixed dy = SkScalarToFixed(sdy) >> 1;
   1342     // might perform this check for the other modes,
   1343     // but the win will be a smaller % of the total
   1344     if (dy == 0) {
   1345         fy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
   1346         fy *= fy;
   1347         do {
   1348             unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
   1349             unsigned fi = (xx * xx + fy) >> (14 + 16 - kSQRT_TABLE_BITS);
   1350             fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
   1351             fx += dx;
   1352             *dstC++ = cache[toggle +
   1353                             (sqrt_table[fi] >> Gradient_Shader::kSqrt16Shift)];
   1354             toggle ^= Gradient_Shader::kDitherStride16;
   1355         } while (--count != 0);
   1356     } else {
   1357         do {
   1358             unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
   1359             unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
   1360             fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
   1361             fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
   1362             fx += dx;
   1363             fy += dy;
   1364             *dstC++ = cache[toggle +
   1365                             (sqrt_table[fi] >> Gradient_Shader::kSqrt16Shift)];
   1366             toggle ^= Gradient_Shader::kDitherStride16;
   1367         } while (--count != 0);
   1368     }
   1369 }
   1370 
   1371 void shadeSpan16_radial_mirror(SkScalar sfx, SkScalar sdx,
   1372         SkScalar sfy, SkScalar sdy,
   1373         uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache,
   1374         int toggle, int count) {
   1375     do {
   1376 #ifdef SK_SCALAR_IS_FLOAT
   1377         float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy);
   1378         SkFixed dist = SkFloatToFixed(fdist);
   1379 #else
   1380         SkFixed magnitudeSquared = SkFixedSquare(sfx) +
   1381             SkFixedSquare(sfy);
   1382         if (magnitudeSquared < 0) // Overflow.
   1383             magnitudeSquared = SK_FixedMax;
   1384         SkFixed dist = SkFixedSqrt(magnitudeSquared);
   1385 #endif
   1386         unsigned fi = mirror_tileproc(dist);
   1387         SkASSERT(fi <= 0xFFFF);
   1388         *dstC++ = cache[toggle + (fi >> Gradient_Shader::kCache16Shift)];
   1389         toggle ^= Gradient_Shader::kDitherStride16;
   1390         sfx += sdx;
   1391         sfy += sdy;
   1392     } while (--count != 0);
   1393 }
   1394 
   1395 void shadeSpan16_radial_repeat(SkScalar sfx, SkScalar sdx,
   1396         SkScalar sfy, SkScalar sdy,
   1397         uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache,
   1398         int toggle, int count) {
   1399     SkFixed fx = SkScalarToFixed(sfx);
   1400     SkFixed dx = SkScalarToFixed(sdx);
   1401     SkFixed fy = SkScalarToFixed(sfy);
   1402     SkFixed dy = SkScalarToFixed(sdy);
   1403     do {
   1404         SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy));
   1405         unsigned fi = repeat_tileproc(dist);
   1406         SkASSERT(fi <= 0xFFFF);
   1407         fx += dx;
   1408         fy += dy;
   1409         *dstC++ = cache[toggle + (fi >> Gradient_Shader::kCache16Shift)];
   1410         toggle ^= Gradient_Shader::kDitherStride16;
   1411     } while (--count != 0);
   1412 }
   1413 
   1414 }
   1415 
   1416 class Radial_Gradient : public Gradient_Shader {
   1417 public:
   1418     Radial_Gradient(const SkPoint& center, SkScalar radius,
   1419                     const SkColor colors[], const SkScalar pos[], int colorCount,
   1420                     SkShader::TileMode mode, SkUnitMapper* mapper)
   1421         : Gradient_Shader(colors, pos, colorCount, mode, mapper),
   1422           fCenter(center),
   1423           fRadius(radius)
   1424     {
   1425         // make sure our table is insync with our current #define for kSQRT_TABLE_SIZE
   1426         SkASSERT(sizeof(gSqrt8Table) == kSQRT_TABLE_SIZE);
   1427 
   1428         rad_to_unit_matrix(center, radius, &fPtsToUnit);
   1429     }
   1430 
   1431     virtual void shadeSpan(int x, int y, SkPMColor* dstC, int count)
   1432         SK_OVERRIDE;
   1433     virtual void shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC,
   1434                              int count) SK_OVERRIDE {
   1435         SkASSERT(count > 0);
   1436 
   1437         SkPoint             srcPt;
   1438         SkMatrix::MapXYProc dstProc = fDstToIndexProc;
   1439         TileProc            proc = fTileProc;
   1440         const uint16_t* SK_RESTRICT cache = this->getCache16();
   1441         int                 toggle = ((x ^ y) & 1) * kDitherStride16;
   1442 
   1443         if (fDstToIndexClass != kPerspective_MatrixClass) {
   1444             dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
   1445                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1446 
   1447             SkScalar sdx = fDstToIndex.getScaleX();
   1448             SkScalar sdy = fDstToIndex.getSkewY();
   1449 
   1450             if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   1451                 SkFixed storage[2];
   1452                 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y),
   1453                                                &storage[0], &storage[1]);
   1454                 sdx = SkFixedToScalar(storage[0]);
   1455                 sdy = SkFixedToScalar(storage[1]);
   1456             } else {
   1457                 SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   1458             }
   1459 
   1460             RadialShade16Proc shadeProc = shadeSpan16_radial_repeat;
   1461             if (proc == clamp_tileproc) {
   1462                 shadeProc = shadeSpan16_radial_clamp;
   1463             } else if (proc == mirror_tileproc) {
   1464                 shadeProc = shadeSpan16_radial_mirror;
   1465             } else {
   1466                 SkASSERT(proc == repeat_tileproc);
   1467             }
   1468             (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC,
   1469                          cache, toggle, count);
   1470         } else {    // perspective case
   1471             SkScalar dstX = SkIntToScalar(x);
   1472             SkScalar dstY = SkIntToScalar(y);
   1473             do {
   1474                 dstProc(fDstToIndex, dstX, dstY, &srcPt);
   1475                 unsigned fi = proc(SkScalarToFixed(srcPt.length()));
   1476                 SkASSERT(fi <= 0xFFFF);
   1477 
   1478                 int index = fi >> (16 - kCache16Bits);
   1479                 *dstC++ = cache[toggle + index];
   1480                 toggle ^= kDitherStride16;
   1481 
   1482                 dstX += SK_Scalar1;
   1483             } while (--count != 0);
   1484         }
   1485     }
   1486 
   1487     virtual BitmapType asABitmap(SkBitmap* bitmap,
   1488                                  SkMatrix* matrix,
   1489                                  TileMode* xy,
   1490                                  SkScalar* twoPointRadialParams)
   1491             const SK_OVERRIDE {
   1492         if (bitmap) {
   1493             this->commonAsABitmap(bitmap);
   1494         }
   1495         if (matrix) {
   1496             matrix->setScale(SkIntToScalar(kGradient32Length),
   1497                              SkIntToScalar(kGradient32Length));
   1498             matrix->preConcat(fPtsToUnit);
   1499         }
   1500         if (xy) {
   1501             xy[0] = fTileMode;
   1502             xy[1] = kClamp_TileMode;
   1503         }
   1504         return kRadial_BitmapType;
   1505     }
   1506     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE {
   1507         if (info) {
   1508             commonAsAGradient(info);
   1509             info->fPoint[0] = fCenter;
   1510             info->fRadius[0] = fRadius;
   1511         }
   1512         return kRadial_GradientType;
   1513     }
   1514 
   1515     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
   1516         return SkNEW_ARGS(Radial_Gradient, (buffer));
   1517     }
   1518 
   1519     virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE {
   1520         this->INHERITED::flatten(buffer);
   1521         buffer.writeScalar(fCenter.fX);
   1522         buffer.writeScalar(fCenter.fY);
   1523         buffer.writeScalar(fRadius);
   1524     }
   1525 
   1526 protected:
   1527     Radial_Gradient(SkFlattenableReadBuffer& buffer)
   1528         : Gradient_Shader(buffer),
   1529           fCenter(unflatten_point(buffer)),
   1530           fRadius(buffer.readScalar()) {
   1531     }
   1532     virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
   1533 
   1534 private:
   1535     typedef Gradient_Shader INHERITED;
   1536     const SkPoint fCenter;
   1537     const SkScalar fRadius;
   1538 };
   1539 
   1540 namespace {
   1541 
   1542 inline bool radial_completely_pinned(int fx, int dx, int fy, int dy) {
   1543     // fast, overly-conservative test: checks unit square instead
   1544     // of unit circle
   1545     bool xClamped = (fx >= SK_FixedHalf && dx >= 0) ||
   1546                     (fx <= -SK_FixedHalf && dx <= 0);
   1547     bool yClamped = (fy >= SK_FixedHalf && dy >= 0) ||
   1548                     (fy <= -SK_FixedHalf && dy <= 0);
   1549 
   1550     return xClamped || yClamped;
   1551 }
   1552 
   1553 // Return true if (fx * fy) is always inside the unit circle
   1554 // SkPin32 is expensive, but so are all the SkFixedMul in this test,
   1555 // so it shouldn't be run if count is small.
   1556 inline bool no_need_for_radial_pin(int fx, int dx,
   1557                                           int fy, int dy, int count) {
   1558     SkASSERT(count > 0);
   1559     if (SkAbs32(fx) > 0x7FFF || SkAbs32(fy) > 0x7FFF) {
   1560         return false;
   1561     }
   1562     if (fx*fx + fy*fy > 0x7FFF*0x7FFF) {
   1563         return false;
   1564     }
   1565     fx += (count - 1) * dx;
   1566     fy += (count - 1) * dy;
   1567     if (SkAbs32(fx) > 0x7FFF || SkAbs32(fy) > 0x7FFF) {
   1568         return false;
   1569     }
   1570     return fx*fx + fy*fy <= 0x7FFF*0x7FFF;
   1571 }
   1572 
   1573 #define UNPINNED_RADIAL_STEP \
   1574     fi = (fx * fx + fy * fy) >> (14 + 16 - kSQRT_TABLE_BITS); \
   1575     *dstC++ = cache[toggle + \
   1576                     (sqrt_table[fi] >> Gradient_Shader::kSqrt32Shift)]; \
   1577     toggle ^= Gradient_Shader::kDitherStride32; \
   1578     fx += dx; \
   1579     fy += dy;
   1580 
   1581 typedef void (* RadialShadeProc)(SkScalar sfx, SkScalar sdx,
   1582         SkScalar sfy, SkScalar sdy,
   1583         SkPMColor* dstC, const SkPMColor* cache,
   1584         int count, int toggle);
   1585 
   1586 // On Linux, this is faster with SkPMColor[] params than SkPMColor* SK_RESTRICT
   1587 void shadeSpan_radial_clamp(SkScalar sfx, SkScalar sdx,
   1588         SkScalar sfy, SkScalar sdy,
   1589         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1590         int count, int toggle) {
   1591     // Floating point seems to be slower than fixed point,
   1592     // even when we have float hardware.
   1593     const uint8_t* SK_RESTRICT sqrt_table = gSqrt8Table;
   1594     SkFixed fx = SkScalarToFixed(sfx) >> 1;
   1595     SkFixed dx = SkScalarToFixed(sdx) >> 1;
   1596     SkFixed fy = SkScalarToFixed(sfy) >> 1;
   1597     SkFixed dy = SkScalarToFixed(sdy) >> 1;
   1598     if ((count > 4) && radial_completely_pinned(fx, dx, fy, dy)) {
   1599         unsigned fi = Gradient_Shader::kGradient32Length;
   1600         sk_memset32_dither(dstC,
   1601             cache[toggle + fi],
   1602             cache[(toggle ^ Gradient_Shader::kDitherStride32) + fi],
   1603             count);
   1604     } else if ((count > 4) &&
   1605                no_need_for_radial_pin(fx, dx, fy, dy, count)) {
   1606         unsigned fi;
   1607         // 4x unroll appears to be no faster than 2x unroll on Linux
   1608         while (count > 1) {
   1609             UNPINNED_RADIAL_STEP;
   1610             UNPINNED_RADIAL_STEP;
   1611             count -= 2;
   1612         }
   1613         if (count) {
   1614             UNPINNED_RADIAL_STEP;
   1615         }
   1616     }
   1617     else  {
   1618         // Specializing for dy == 0 gains us 25% on Skia benchmarks
   1619         if (dy == 0) {
   1620             unsigned yy = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
   1621             yy *= yy;
   1622             do {
   1623                 unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
   1624                 unsigned fi = (xx * xx + yy) >> (14 + 16 - kSQRT_TABLE_BITS);
   1625                 fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
   1626                 *dstC++ = cache[toggle + (sqrt_table[fi] >>
   1627                     Gradient_Shader::kSqrt32Shift)];
   1628                 toggle ^= Gradient_Shader::kDitherStride32;
   1629                 fx += dx;
   1630             } while (--count != 0);
   1631         } else {
   1632             do {
   1633                 unsigned xx = SkPin32(fx, -0xFFFF >> 1, 0xFFFF >> 1);
   1634                 unsigned fi = SkPin32(fy, -0xFFFF >> 1, 0xFFFF >> 1);
   1635                 fi = (xx * xx + fi * fi) >> (14 + 16 - kSQRT_TABLE_BITS);
   1636                 fi = SkFastMin32(fi, 0xFFFF >> (16 - kSQRT_TABLE_BITS));
   1637                 *dstC++ = cache[toggle + (sqrt_table[fi] >>
   1638                     Gradient_Shader::kSqrt32Shift)];
   1639                 toggle ^= Gradient_Shader::kDitherStride32;
   1640                 fx += dx;
   1641                 fy += dy;
   1642             } while (--count != 0);
   1643         }
   1644     }
   1645 }
   1646 
   1647 // Unrolling this loop doesn't seem to help (when float); we're stalling to
   1648 // get the results of the sqrt (?), and don't have enough extra registers to
   1649 // have many in flight.
   1650 void shadeSpan_radial_mirror(SkScalar sfx, SkScalar sdx,
   1651         SkScalar sfy, SkScalar sdy,
   1652         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1653         int count, int toggle) {
   1654     do {
   1655 #ifdef SK_SCALAR_IS_FLOAT
   1656         float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy);
   1657         SkFixed dist = SkFloatToFixed(fdist);
   1658 #else
   1659         SkFixed magnitudeSquared = SkFixedSquare(sfx) +
   1660             SkFixedSquare(sfy);
   1661         if (magnitudeSquared < 0) // Overflow.
   1662             magnitudeSquared = SK_FixedMax;
   1663         SkFixed dist = SkFixedSqrt(magnitudeSquared);
   1664 #endif
   1665         unsigned fi = mirror_tileproc(dist);
   1666         SkASSERT(fi <= 0xFFFF);
   1667         *dstC++ = cache[toggle + (fi >> Gradient_Shader::kCache32Shift)];
   1668         toggle ^= Gradient_Shader::kDitherStride32;
   1669         sfx += sdx;
   1670         sfy += sdy;
   1671     } while (--count != 0);
   1672 }
   1673 
   1674 void shadeSpan_radial_repeat(SkScalar sfx, SkScalar sdx,
   1675         SkScalar sfy, SkScalar sdy,
   1676         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1677         int count, int toggle) {
   1678     SkFixed fx = SkScalarToFixed(sfx);
   1679     SkFixed dx = SkScalarToFixed(sdx);
   1680     SkFixed fy = SkScalarToFixed(sfy);
   1681     SkFixed dy = SkScalarToFixed(sdy);
   1682     do {
   1683         SkFixed magnitudeSquared = SkFixedSquare(fx) +
   1684             SkFixedSquare(fy);
   1685         if (magnitudeSquared < 0) // Overflow.
   1686             magnitudeSquared = SK_FixedMax;
   1687         SkFixed dist = SkFixedSqrt(magnitudeSquared);
   1688         unsigned fi = repeat_tileproc(dist);
   1689         SkASSERT(fi <= 0xFFFF);
   1690         *dstC++ = cache[toggle + (fi >> Gradient_Shader::kCache32Shift)];
   1691         toggle ^= Gradient_Shader::kDitherStride32;
   1692         fx += dx;
   1693         fy += dy;
   1694     } while (--count != 0);
   1695 }
   1696 }
   1697 
   1698 void Radial_Gradient::shadeSpan(int x, int y,
   1699                                 SkPMColor* SK_RESTRICT dstC, int count) {
   1700     SkASSERT(count > 0);
   1701 
   1702     SkPoint             srcPt;
   1703     SkMatrix::MapXYProc dstProc = fDstToIndexProc;
   1704     TileProc            proc = fTileProc;
   1705     const SkPMColor* SK_RESTRICT cache = this->getCache32();
   1706 #ifdef USE_DITHER_32BIT_GRADIENT
   1707     int toggle = ((x ^ y) & 1) * Gradient_Shader::kDitherStride32;
   1708 #else
   1709     int toggle = 0;
   1710 #endif
   1711 
   1712     if (fDstToIndexClass != kPerspective_MatrixClass) {
   1713         dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
   1714                              SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1715         SkScalar sdx = fDstToIndex.getScaleX();
   1716         SkScalar sdy = fDstToIndex.getSkewY();
   1717 
   1718         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   1719             SkFixed storage[2];
   1720             (void)fDstToIndex.fixedStepInX(SkIntToScalar(y),
   1721                                            &storage[0], &storage[1]);
   1722             sdx = SkFixedToScalar(storage[0]);
   1723             sdy = SkFixedToScalar(storage[1]);
   1724         } else {
   1725             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   1726         }
   1727 
   1728         RadialShadeProc shadeProc = shadeSpan_radial_repeat;
   1729         if (proc == clamp_tileproc) {
   1730             shadeProc = shadeSpan_radial_clamp;
   1731         } else if (proc == mirror_tileproc) {
   1732             shadeProc = shadeSpan_radial_mirror;
   1733         } else {
   1734             SkASSERT(proc == repeat_tileproc);
   1735         }
   1736         (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle);
   1737     } else {    // perspective case
   1738         SkScalar dstX = SkIntToScalar(x);
   1739         SkScalar dstY = SkIntToScalar(y);
   1740         do {
   1741             dstProc(fDstToIndex, dstX, dstY, &srcPt);
   1742             unsigned fi = proc(SkScalarToFixed(srcPt.length()));
   1743             SkASSERT(fi <= 0xFFFF);
   1744             *dstC++ = cache[fi >> Gradient_Shader::kCache32Shift];
   1745             dstX += SK_Scalar1;
   1746         } while (--count != 0);
   1747     }
   1748 }
   1749 
   1750 /* Two-point radial gradients are specified by two circles, each with a center
   1751    point and radius.  The gradient can be considered to be a series of
   1752    concentric circles, with the color interpolated from the start circle
   1753    (at t=0) to the end circle (at t=1).
   1754 
   1755    For each point (x, y) in the span, we want to find the
   1756    interpolated circle that intersects that point.  The center
   1757    of the desired circle (Cx, Cy) falls at some distance t
   1758    along the line segment between the start point (Sx, Sy) and
   1759    end point (Ex, Ey):
   1760 
   1761       Cx = (1 - t) * Sx + t * Ex        (0 <= t <= 1)
   1762       Cy = (1 - t) * Sy + t * Ey
   1763 
   1764    The radius of the desired circle (r) is also a linear interpolation t
   1765    between the start and end radii (Sr and Er):
   1766 
   1767       r = (1 - t) * Sr + t * Er
   1768 
   1769    But
   1770 
   1771       (x - Cx)^2 + (y - Cy)^2 = r^2
   1772 
   1773    so
   1774 
   1775      (x - ((1 - t) * Sx + t * Ex))^2
   1776    + (y - ((1 - t) * Sy + t * Ey))^2
   1777    = ((1 - t) * Sr + t * Er)^2
   1778 
   1779    Solving for t yields
   1780 
   1781      [(Sx - Ex)^2 + (Sy - Ey)^2 - (Er - Sr)^2)] * t^2
   1782    + [2 * (Sx - Ex)(x - Sx) + 2 * (Sy - Ey)(y - Sy) - 2 * (Er - Sr) * Sr] * t
   1783    + [(x - Sx)^2 + (y - Sy)^2 - Sr^2] = 0
   1784 
   1785    To simplify, let Dx = Sx - Ex, Dy = Sy - Ey, Dr = Er - Sr, dx = x - Sx, dy = y - Sy
   1786 
   1787      [Dx^2 + Dy^2 - Dr^2)] * t^2
   1788    + 2 * [Dx * dx + Dy * dy - Dr * Sr] * t
   1789    + [dx^2 + dy^2 - Sr^2] = 0
   1790 
   1791    A quadratic in t.  The two roots of the quadratic reflect the two
   1792    possible circles on which the point may fall.  Solving for t yields
   1793    the gradient value to use.
   1794 
   1795    If a<0, the start circle is entirely contained in the
   1796    end circle, and one of the roots will be <0 or >1 (off the line
   1797    segment).  If a>0, the start circle falls at least partially
   1798    outside the end circle (or vice versa), and the gradient
   1799    defines a "tube" where a point may be on one circle (on the
   1800    inside of the tube) or the other (outside of the tube).  We choose
   1801    one arbitrarily.
   1802 
   1803    In order to keep the math to within the limits of fixed point,
   1804    we divide the entire quadratic by Dr^2, and replace
   1805    (x - Sx)/Dr with x' and (y - Sy)/Dr with y', giving
   1806 
   1807    [Dx^2 / Dr^2 + Dy^2 / Dr^2 - 1)] * t^2
   1808    + 2 * [x' * Dx / Dr + y' * Dy / Dr - Sr / Dr] * t
   1809    + [x'^2 + y'^2 - Sr^2/Dr^2] = 0
   1810 
   1811    (x' and y' are computed by appending the subtract and scale to the
   1812    fDstToIndex matrix in the constructor).
   1813 
   1814    Since the 'A' component of the quadratic is independent of x' and y', it
   1815    is precomputed in the constructor.  Since the 'B' component is linear in
   1816    x' and y', if x and y are linear in the span, 'B' can be computed
   1817    incrementally with a simple delta (db below).  If it is not (e.g.,
   1818    a perspective projection), it must be computed in the loop.
   1819 
   1820 */
   1821 
   1822 namespace {
   1823 
   1824 inline SkFixed two_point_radial(SkScalar b, SkScalar fx, SkScalar fy,
   1825                                 SkScalar sr2d2, SkScalar foura,
   1826                                 SkScalar oneOverTwoA, bool posRoot) {
   1827     SkScalar c = SkScalarSquare(fx) + SkScalarSquare(fy) - sr2d2;
   1828     if (0 == foura) {
   1829         return SkScalarToFixed(SkScalarDiv(-c, b));
   1830     }
   1831 
   1832     SkScalar discrim = SkScalarSquare(b) - SkScalarMul(foura, c);
   1833     if (discrim < 0) {
   1834         discrim = -discrim;
   1835     }
   1836     SkScalar rootDiscrim = SkScalarSqrt(discrim);
   1837     SkScalar result;
   1838     if (posRoot) {
   1839         result = SkScalarMul(-b + rootDiscrim, oneOverTwoA);
   1840     } else {
   1841         result = SkScalarMul(-b - rootDiscrim, oneOverTwoA);
   1842     }
   1843     return SkScalarToFixed(result);
   1844 }
   1845 
   1846 typedef void (* TwoPointRadialShadeProc)(SkScalar fx, SkScalar dx,
   1847         SkScalar fy, SkScalar dy,
   1848         SkScalar b, SkScalar db,
   1849         SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
   1850         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1851         int count);
   1852 
   1853 void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
   1854         SkScalar fy, SkScalar dy,
   1855         SkScalar b, SkScalar db,
   1856         SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
   1857         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1858         int count) {
   1859     for (; count > 0; --count) {
   1860         SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
   1861                                      fOneOverTwoA, posRoot);
   1862         SkFixed index = SkClampMax(t, 0xFFFF);
   1863         SkASSERT(index <= 0xFFFF);
   1864         *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
   1865         fx += dx;
   1866         fy += dy;
   1867         b += db;
   1868     }
   1869 }
   1870 void shadeSpan_twopoint_mirror(SkScalar fx, SkScalar dx,
   1871         SkScalar fy, SkScalar dy,
   1872         SkScalar b, SkScalar db,
   1873         SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
   1874         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1875         int count) {
   1876     for (; count > 0; --count) {
   1877         SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
   1878                                      fOneOverTwoA, posRoot);
   1879         SkFixed index = mirror_tileproc(t);
   1880         SkASSERT(index <= 0xFFFF);
   1881         *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
   1882         fx += dx;
   1883         fy += dy;
   1884         b += db;
   1885     }
   1886 }
   1887 
   1888 void shadeSpan_twopoint_repeat(SkScalar fx, SkScalar dx,
   1889         SkScalar fy, SkScalar dy,
   1890         SkScalar b, SkScalar db,
   1891         SkScalar fSr2D2, SkScalar foura, SkScalar fOneOverTwoA, bool posRoot,
   1892         SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
   1893         int count) {
   1894     for (; count > 0; --count) {
   1895         SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
   1896                                      fOneOverTwoA, posRoot);
   1897         SkFixed index = repeat_tileproc(t);
   1898         SkASSERT(index <= 0xFFFF);
   1899         *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
   1900         fx += dx;
   1901         fy += dy;
   1902         b += db;
   1903     }
   1904 }
   1905 
   1906 
   1907 
   1908 }
   1909 
   1910 class Two_Point_Radial_Gradient : public Gradient_Shader {
   1911 public:
   1912     Two_Point_Radial_Gradient(const SkPoint& start, SkScalar startRadius,
   1913                               const SkPoint& end, SkScalar endRadius,
   1914                               const SkColor colors[], const SkScalar pos[],
   1915                               int colorCount, SkShader::TileMode mode,
   1916                               SkUnitMapper* mapper)
   1917             : Gradient_Shader(colors, pos, colorCount, mode, mapper),
   1918               fCenter1(start),
   1919               fCenter2(end),
   1920               fRadius1(startRadius),
   1921               fRadius2(endRadius) {
   1922         init();
   1923     }
   1924 
   1925     virtual BitmapType asABitmap(SkBitmap* bitmap,
   1926                                  SkMatrix* matrix,
   1927                                  TileMode* xy,
   1928                                  SkScalar* twoPointRadialParams) const {
   1929         if (bitmap) {
   1930             this->commonAsABitmap(bitmap);
   1931         }
   1932         SkScalar diffL = 0; // just to avoid gcc warning
   1933         if (matrix || twoPointRadialParams) {
   1934             diffL = SkScalarSqrt(SkScalarSquare(fDiff.fX) +
   1935                                  SkScalarSquare(fDiff.fY));
   1936         }
   1937         if (matrix) {
   1938             if (diffL) {
   1939                 SkScalar invDiffL = SkScalarInvert(diffL);
   1940                 matrix->setSinCos(-SkScalarMul(invDiffL, fDiff.fY),
   1941                                   SkScalarMul(invDiffL, fDiff.fX));
   1942             } else {
   1943                 matrix->reset();
   1944             }
   1945             matrix->preConcat(fPtsToUnit);
   1946         }
   1947         if (xy) {
   1948             xy[0] = fTileMode;
   1949             xy[1] = kClamp_TileMode;
   1950         }
   1951         if (NULL != twoPointRadialParams) {
   1952             twoPointRadialParams[0] = diffL;
   1953             twoPointRadialParams[1] = fStartRadius;
   1954             twoPointRadialParams[2] = fDiffRadius;
   1955         }
   1956         return kTwoPointRadial_BitmapType;
   1957     }
   1958 
   1959     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE {
   1960         if (info) {
   1961             commonAsAGradient(info);
   1962             info->fPoint[0] = fCenter1;
   1963             info->fPoint[1] = fCenter2;
   1964             info->fRadius[0] = fRadius1;
   1965             info->fRadius[1] = fRadius2;
   1966         }
   1967         return kRadial2_GradientType;
   1968     }
   1969 
   1970     virtual void shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
   1971                            int count) SK_OVERRIDE {
   1972         SkASSERT(count > 0);
   1973 
   1974         // Zero difference between radii:  fill with transparent black.
   1975         if (fDiffRadius == 0) {
   1976           sk_bzero(dstC, count * sizeof(*dstC));
   1977           return;
   1978         }
   1979         SkMatrix::MapXYProc dstProc = fDstToIndexProc;
   1980         TileProc            proc = fTileProc;
   1981         const SkPMColor* SK_RESTRICT cache = this->getCache32();
   1982 
   1983         SkScalar foura = fA * 4;
   1984         bool posRoot = fDiffRadius < 0;
   1985         if (fDstToIndexClass != kPerspective_MatrixClass) {
   1986             SkPoint srcPt;
   1987             dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
   1988                                  SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   1989             SkScalar dx, fx = srcPt.fX;
   1990             SkScalar dy, fy = srcPt.fY;
   1991 
   1992             if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   1993                 SkFixed fixedX, fixedY;
   1994                 (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &fixedX, &fixedY);
   1995                 dx = SkFixedToScalar(fixedX);
   1996                 dy = SkFixedToScalar(fixedY);
   1997             } else {
   1998                 SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   1999                 dx = fDstToIndex.getScaleX();
   2000                 dy = fDstToIndex.getSkewY();
   2001             }
   2002             SkScalar b = (SkScalarMul(fDiff.fX, fx) +
   2003                          SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
   2004             SkScalar db = (SkScalarMul(fDiff.fX, dx) +
   2005                           SkScalarMul(fDiff.fY, dy)) * 2;
   2006 
   2007             TwoPointRadialShadeProc shadeProc = shadeSpan_twopoint_repeat;
   2008             if (proc == clamp_tileproc) {
   2009                 shadeProc = shadeSpan_twopoint_clamp;
   2010             } else if (proc == mirror_tileproc) {
   2011                 shadeProc = shadeSpan_twopoint_mirror;
   2012             } else {
   2013                 SkASSERT(proc == repeat_tileproc);
   2014             }
   2015             (*shadeProc)(fx, dx, fy, dy, b, db,
   2016                          fSr2D2, foura, fOneOverTwoA, posRoot,
   2017                          dstC, cache, count);
   2018         } else {    // perspective case
   2019             SkScalar dstX = SkIntToScalar(x);
   2020             SkScalar dstY = SkIntToScalar(y);
   2021             for (; count > 0; --count) {
   2022                 SkPoint             srcPt;
   2023                 dstProc(fDstToIndex, dstX, dstY, &srcPt);
   2024                 SkScalar fx = srcPt.fX;
   2025                 SkScalar fy = srcPt.fY;
   2026                 SkScalar b = (SkScalarMul(fDiff.fX, fx) +
   2027                              SkScalarMul(fDiff.fY, fy) - fStartRadius) * 2;
   2028                 SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
   2029                                              fOneOverTwoA, posRoot);
   2030                 SkFixed index = proc(t);
   2031                 SkASSERT(index <= 0xFFFF);
   2032                 *dstC++ = cache[index >> Gradient_Shader::kCache32Shift];
   2033                 dstX += SK_Scalar1;
   2034             }
   2035         }
   2036     }
   2037 
   2038     virtual bool setContext(const SkBitmap& device,
   2039                             const SkPaint& paint,
   2040                             const SkMatrix& matrix) SK_OVERRIDE {
   2041         if (!this->INHERITED::setContext(device, paint, matrix)) {
   2042             return false;
   2043         }
   2044 
   2045         // we don't have a span16 proc
   2046         fFlags &= ~kHasSpan16_Flag;
   2047         return true;
   2048     }
   2049 
   2050     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
   2051         return SkNEW_ARGS(Two_Point_Radial_Gradient, (buffer));
   2052     }
   2053 
   2054     virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE {
   2055         this->INHERITED::flatten(buffer);
   2056         buffer.writeScalar(fCenter1.fX);
   2057         buffer.writeScalar(fCenter1.fY);
   2058         buffer.writeScalar(fCenter2.fX);
   2059         buffer.writeScalar(fCenter2.fY);
   2060         buffer.writeScalar(fRadius1);
   2061         buffer.writeScalar(fRadius2);
   2062     }
   2063 
   2064 protected:
   2065     Two_Point_Radial_Gradient(SkFlattenableReadBuffer& buffer)
   2066             : Gradient_Shader(buffer),
   2067               fCenter1(unflatten_point(buffer)),
   2068               fCenter2(unflatten_point(buffer)),
   2069               fRadius1(buffer.readScalar()),
   2070               fRadius2(buffer.readScalar()) {
   2071         init();
   2072     };
   2073     virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
   2074 
   2075 private:
   2076     typedef Gradient_Shader INHERITED;
   2077     const SkPoint fCenter1;
   2078     const SkPoint fCenter2;
   2079     const SkScalar fRadius1;
   2080     const SkScalar fRadius2;
   2081     SkPoint fDiff;
   2082     SkScalar fStartRadius, fDiffRadius, fSr2D2, fA, fOneOverTwoA;
   2083 
   2084     void init() {
   2085         fDiff = fCenter1 - fCenter2;
   2086         fDiffRadius = fRadius2 - fRadius1;
   2087         SkScalar inv = SkScalarInvert(fDiffRadius);
   2088         fDiff.fX = SkScalarMul(fDiff.fX, inv);
   2089         fDiff.fY = SkScalarMul(fDiff.fY, inv);
   2090         fStartRadius = SkScalarMul(fRadius1, inv);
   2091         fSr2D2 = SkScalarSquare(fStartRadius);
   2092         fA = SkScalarSquare(fDiff.fX) + SkScalarSquare(fDiff.fY) - SK_Scalar1;
   2093         fOneOverTwoA = fA ? SkScalarInvert(fA * 2) : 0;
   2094 
   2095         fPtsToUnit.setTranslate(-fCenter1.fX, -fCenter1.fY);
   2096         fPtsToUnit.postScale(inv, inv);
   2097     }
   2098 };
   2099 
   2100 ///////////////////////////////////////////////////////////////////////////////
   2101 
   2102 class Sweep_Gradient : public Gradient_Shader {
   2103 public:
   2104     Sweep_Gradient(SkScalar cx, SkScalar cy, const SkColor colors[],
   2105                    const SkScalar pos[], int count, SkUnitMapper* mapper)
   2106     : Gradient_Shader(colors, pos, count, SkShader::kClamp_TileMode, mapper),
   2107       fCenter(SkPoint::Make(cx, cy))
   2108     {
   2109         fPtsToUnit.setTranslate(-cx, -cy);
   2110     }
   2111     virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
   2112     virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE;
   2113 
   2114     virtual BitmapType asABitmap(SkBitmap* bitmap,
   2115                                  SkMatrix* matrix,
   2116                                  TileMode* xy,
   2117                                  SkScalar* twoPointRadialParams) const SK_OVERRIDE {
   2118         if (bitmap) {
   2119             this->commonAsABitmap(bitmap);
   2120         }
   2121         if (matrix) {
   2122             *matrix = fPtsToUnit;
   2123         }
   2124         if (xy) {
   2125             xy[0] = fTileMode;
   2126             xy[1] = kClamp_TileMode;
   2127         }
   2128         return kSweep_BitmapType;
   2129     }
   2130 
   2131     virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE {
   2132         if (info) {
   2133             commonAsAGradient(info);
   2134             info->fPoint[0] = fCenter;
   2135         }
   2136         return kSweep_GradientType;
   2137     }
   2138 
   2139     static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
   2140         return SkNEW_ARGS(Sweep_Gradient, (buffer));
   2141     }
   2142 
   2143     virtual void flatten(SkFlattenableWriteBuffer& buffer) SK_OVERRIDE {
   2144         this->INHERITED::flatten(buffer);
   2145         buffer.writeScalar(fCenter.fX);
   2146         buffer.writeScalar(fCenter.fY);
   2147     }
   2148 
   2149 protected:
   2150     Sweep_Gradient(SkFlattenableReadBuffer& buffer)
   2151         : Gradient_Shader(buffer),
   2152           fCenter(unflatten_point(buffer)) {
   2153     }
   2154 
   2155     virtual Factory getFactory() SK_OVERRIDE { return CreateProc; }
   2156 
   2157 private:
   2158     typedef Gradient_Shader INHERITED;
   2159     const SkPoint fCenter;
   2160 };
   2161 
   2162 #ifdef COMPUTE_SWEEP_TABLE
   2163 #define PI  3.14159265
   2164 static bool gSweepTableReady;
   2165 static uint8_t gSweepTable[65];
   2166 
   2167 /*  Our table stores precomputed values for atan: [0...1] -> [0..PI/4]
   2168     We scale the results to [0..32]
   2169 */
   2170 static const uint8_t* build_sweep_table() {
   2171     if (!gSweepTableReady) {
   2172         const int N = 65;
   2173         const double DENOM = N - 1;
   2174 
   2175         for (int i = 0; i < N; i++)
   2176         {
   2177             double arg = i / DENOM;
   2178             double v = atan(arg);
   2179             int iv = (int)round(v * DENOM * 2 / PI);
   2180 //            printf("[%d] atan(%g) = %g %d\n", i, arg, v, iv);
   2181             printf("%d, ", iv);
   2182             gSweepTable[i] = iv;
   2183         }
   2184         gSweepTableReady = true;
   2185     }
   2186     return gSweepTable;
   2187 }
   2188 #else
   2189 static const uint8_t gSweepTable[] = {
   2190     0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9, 9,
   2191     10, 11, 11, 12, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18,
   2192     19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26,
   2193     26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32,
   2194     32
   2195 };
   2196 static const uint8_t* build_sweep_table() { return gSweepTable; }
   2197 #endif
   2198 
   2199 // divide numer/denom, with a bias of 6bits. Assumes numer <= denom
   2200 // and denom != 0. Since our table is 6bits big (+1), this is a nice fit.
   2201 // Same as (but faster than) SkFixedDiv(numer, denom) >> 10
   2202 
   2203 //unsigned div_64(int numer, int denom);
   2204 static unsigned div_64(int numer, int denom) {
   2205     SkASSERT(numer <= denom);
   2206     SkASSERT(numer > 0);
   2207     SkASSERT(denom > 0);
   2208 
   2209     int nbits = SkCLZ(numer);
   2210     int dbits = SkCLZ(denom);
   2211     int bits = 6 - nbits + dbits;
   2212     SkASSERT(bits <= 6);
   2213 
   2214     if (bits < 0) {  // detect underflow
   2215         return 0;
   2216     }
   2217 
   2218     denom <<= dbits - 1;
   2219     numer <<= nbits - 1;
   2220 
   2221     unsigned result = 0;
   2222 
   2223     // do the first one
   2224     if ((numer -= denom) >= 0) {
   2225         result = 1;
   2226     } else {
   2227         numer += denom;
   2228     }
   2229 
   2230     // Now fall into our switch statement if there are more bits to compute
   2231     if (bits > 0) {
   2232         // make room for the rest of the answer bits
   2233         result <<= bits;
   2234         switch (bits) {
   2235         case 6:
   2236             if ((numer = (numer << 1) - denom) >= 0)
   2237                 result |= 32;
   2238             else
   2239                 numer += denom;
   2240         case 5:
   2241             if ((numer = (numer << 1) - denom) >= 0)
   2242                 result |= 16;
   2243             else
   2244                 numer += denom;
   2245         case 4:
   2246             if ((numer = (numer << 1) - denom) >= 0)
   2247                 result |= 8;
   2248             else
   2249                 numer += denom;
   2250         case 3:
   2251             if ((numer = (numer << 1) - denom) >= 0)
   2252                 result |= 4;
   2253             else
   2254                 numer += denom;
   2255         case 2:
   2256             if ((numer = (numer << 1) - denom) >= 0)
   2257                 result |= 2;
   2258             else
   2259                 numer += denom;
   2260         case 1:
   2261         default:    // not strictly need, but makes GCC make better ARM code
   2262             if ((numer = (numer << 1) - denom) >= 0)
   2263                 result |= 1;
   2264             else
   2265                 numer += denom;
   2266         }
   2267     }
   2268     return result;
   2269 }
   2270 
   2271 // Given x,y in the first quadrant, return 0..63 for the angle [0..90]
   2272 static unsigned atan_0_90(SkFixed y, SkFixed x) {
   2273 #ifdef SK_DEBUG
   2274     {
   2275         static bool gOnce;
   2276         if (!gOnce) {
   2277             gOnce = true;
   2278             SkASSERT(div_64(55, 55) == 64);
   2279             SkASSERT(div_64(128, 256) == 32);
   2280             SkASSERT(div_64(2326528, 4685824) == 31);
   2281             SkASSERT(div_64(753664, 5210112) == 9);
   2282             SkASSERT(div_64(229376, 4882432) == 3);
   2283             SkASSERT(div_64(2, 64) == 2);
   2284             SkASSERT(div_64(1, 64) == 1);
   2285             // test that we handle underflow correctly
   2286             SkASSERT(div_64(12345, 0x54321234) == 0);
   2287         }
   2288     }
   2289 #endif
   2290 
   2291     SkASSERT(y > 0 && x > 0);
   2292     const uint8_t* table = build_sweep_table();
   2293 
   2294     unsigned result;
   2295     bool swap = (x < y);
   2296     if (swap) {
   2297         // first part of the atan(v) = PI/2 - atan(1/v) identity
   2298         // since our div_64 and table want v <= 1, where v = y/x
   2299         SkTSwap<SkFixed>(x, y);
   2300     }
   2301 
   2302     result = div_64(y, x);
   2303 
   2304 #ifdef SK_DEBUG
   2305     {
   2306         unsigned result2 = SkDivBits(y, x, 6);
   2307         SkASSERT(result2 == result ||
   2308                  (result == 1 && result2 == 0));
   2309     }
   2310 #endif
   2311 
   2312     SkASSERT(result < SK_ARRAY_COUNT(gSweepTable));
   2313     result = table[result];
   2314 
   2315     if (swap) {
   2316         // complete the atan(v) = PI/2 - atan(1/v) identity
   2317         result = 64 - result;
   2318         // pin to 63
   2319         result -= result >> 6;
   2320     }
   2321 
   2322     SkASSERT(result <= 63);
   2323     return result;
   2324 }
   2325 
   2326 //  returns angle in a circle [0..2PI) -> [0..255]
   2327 #ifdef SK_SCALAR_IS_FLOAT
   2328 static unsigned SkATan2_255(float y, float x) {
   2329     //    static const float g255Over2PI = 255 / (2 * SK_ScalarPI);
   2330     static const float g255Over2PI = 40.584510488433314f;
   2331 
   2332     float result = sk_float_atan2(y, x);
   2333     if (result < 0) {
   2334         result += 2 * SK_ScalarPI;
   2335     }
   2336     SkASSERT(result >= 0);
   2337     // since our value is always >= 0, we can cast to int, which is faster than
   2338     // calling floorf()
   2339     int ir = (int)(result * g255Over2PI);
   2340     SkASSERT(ir >= 0 && ir <= 255);
   2341     return ir;
   2342 }
   2343 #else
   2344 static unsigned SkATan2_255(SkFixed y, SkFixed x) {
   2345     if (x == 0) {
   2346         if (y == 0) {
   2347             return 0;
   2348         }
   2349         return y < 0 ? 192 : 64;
   2350     }
   2351     if (y == 0) {
   2352         return x < 0 ? 128 : 0;
   2353     }
   2354 
   2355     /*  Find the right quadrant for x,y
   2356         Since atan_0_90 only handles the first quadrant, we rotate x,y
   2357         appropriately before calling it, and then add the right amount
   2358         to account for the real quadrant.
   2359         quadrant 0 : add 0                  | x > 0 && y > 0
   2360         quadrant 1 : add 64 (90 degrees)    | x < 0 && y > 0
   2361         quadrant 2 : add 128 (180 degrees)  | x < 0 && y < 0
   2362         quadrant 3 : add 192 (270 degrees)  | x > 0 && y < 0
   2363 
   2364         map x<0 to (1 << 6)
   2365         map y<0 to (3 << 6)
   2366         add = map_x ^ map_y
   2367     */
   2368     int xsign = x >> 31;
   2369     int ysign = y >> 31;
   2370     int add = ((-xsign) ^ (ysign & 3)) << 6;
   2371 
   2372 #ifdef SK_DEBUG
   2373     if (0 == add)
   2374         SkASSERT(x > 0 && y > 0);
   2375     else if (64 == add)
   2376         SkASSERT(x < 0 && y > 0);
   2377     else if (128 == add)
   2378         SkASSERT(x < 0 && y < 0);
   2379     else if (192 == add)
   2380         SkASSERT(x > 0 && y < 0);
   2381     else
   2382         SkDEBUGFAIL("bad value for add");
   2383 #endif
   2384 
   2385     /*  This ^ trick makes x, y positive, and the swap<> handles quadrants
   2386         where we need to rotate x,y by 90 or -90
   2387     */
   2388     x = (x ^ xsign) - xsign;
   2389     y = (y ^ ysign) - ysign;
   2390     if (add & 64) {             // quads 1 or 3 need to swap x,y
   2391         SkTSwap<SkFixed>(x, y);
   2392     }
   2393 
   2394     unsigned result = add + atan_0_90(y, x);
   2395     SkASSERT(result < 256);
   2396     return result;
   2397 }
   2398 #endif
   2399 
   2400 void Sweep_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC,
   2401                                int count) {
   2402     SkMatrix::MapXYProc proc = fDstToIndexProc;
   2403     const SkMatrix&     matrix = fDstToIndex;
   2404     const SkPMColor* SK_RESTRICT cache = this->getCache32();
   2405     SkPoint             srcPt;
   2406 
   2407     if (fDstToIndexClass != kPerspective_MatrixClass) {
   2408         proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
   2409                      SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   2410         SkScalar dx, fx = srcPt.fX;
   2411         SkScalar dy, fy = srcPt.fY;
   2412 
   2413         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   2414             SkFixed storage[2];
   2415             (void)matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf,
   2416                                       &storage[0], &storage[1]);
   2417             dx = SkFixedToScalar(storage[0]);
   2418             dy = SkFixedToScalar(storage[1]);
   2419         } else {
   2420             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   2421             dx = matrix.getScaleX();
   2422             dy = matrix.getSkewY();
   2423         }
   2424 
   2425         for (; count > 0; --count) {
   2426             *dstC++ = cache[SkATan2_255(fy, fx)];
   2427             fx += dx;
   2428             fy += dy;
   2429         }
   2430     } else {  // perspective case
   2431         for (int stop = x + count; x < stop; x++) {
   2432             proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
   2433                          SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   2434             *dstC++ = cache[SkATan2_255(srcPt.fY, srcPt.fX)];
   2435         }
   2436     }
   2437 }
   2438 
   2439 void Sweep_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC,
   2440                                  int count) {
   2441     SkMatrix::MapXYProc proc = fDstToIndexProc;
   2442     const SkMatrix&     matrix = fDstToIndex;
   2443     const uint16_t* SK_RESTRICT cache = this->getCache16();
   2444     int                 toggle = ((x ^ y) & 1) * kDitherStride16;
   2445     SkPoint             srcPt;
   2446 
   2447     if (fDstToIndexClass != kPerspective_MatrixClass) {
   2448         proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
   2449                      SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   2450         SkScalar dx, fx = srcPt.fX;
   2451         SkScalar dy, fy = srcPt.fY;
   2452 
   2453         if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
   2454             SkFixed storage[2];
   2455             (void)matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf,
   2456                                       &storage[0], &storage[1]);
   2457             dx = SkFixedToScalar(storage[0]);
   2458             dy = SkFixedToScalar(storage[1]);
   2459         } else {
   2460             SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
   2461             dx = matrix.getScaleX();
   2462             dy = matrix.getSkewY();
   2463         }
   2464 
   2465         for (; count > 0; --count) {
   2466             int index = SkATan2_255(fy, fx) >> (8 - kCache16Bits);
   2467             *dstC++ = cache[toggle + index];
   2468             toggle ^= kDitherStride16;
   2469             fx += dx;
   2470             fy += dy;
   2471         }
   2472     } else {  // perspective case
   2473         for (int stop = x + count; x < stop; x++) {
   2474             proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
   2475                          SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
   2476 
   2477             int index = SkATan2_255(srcPt.fY, srcPt.fX);
   2478             index >>= (8 - kCache16Bits);
   2479             *dstC++ = cache[toggle + index];
   2480             toggle ^= kDitherStride16;
   2481         }
   2482     }
   2483 }
   2484 
   2485 ///////////////////////////////////////////////////////////////////////////////
   2486 ///////////////////////////////////////////////////////////////////////////////
   2487 
   2488 // assumes colors is SkColor* and pos is SkScalar*
   2489 #define EXPAND_1_COLOR(count)               \
   2490     SkColor tmp[2];                         \
   2491     do {                                    \
   2492         if (1 == count) {                   \
   2493             tmp[0] = tmp[1] = colors[0];    \
   2494             colors = tmp;                   \
   2495             pos = NULL;                     \
   2496             count = 2;                      \
   2497         }                                   \
   2498     } while (0)
   2499 
   2500 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2],
   2501                                          const SkColor colors[],
   2502                                          const SkScalar pos[], int colorCount,
   2503                                          SkShader::TileMode mode,
   2504                                          SkUnitMapper* mapper) {
   2505     if (NULL == pts || NULL == colors || colorCount < 1) {
   2506         return NULL;
   2507     }
   2508     EXPAND_1_COLOR(colorCount);
   2509 
   2510     return SkNEW_ARGS(Linear_Gradient,
   2511                       (pts, colors, pos, colorCount, mode, mapper));
   2512 }
   2513 
   2514 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius,
   2515                                          const SkColor colors[],
   2516                                          const SkScalar pos[], int colorCount,
   2517                                          SkShader::TileMode mode,
   2518                                          SkUnitMapper* mapper) {
   2519     if (radius <= 0 || NULL == colors || colorCount < 1) {
   2520         return NULL;
   2521     }
   2522     EXPAND_1_COLOR(colorCount);
   2523 
   2524     return SkNEW_ARGS(Radial_Gradient,
   2525                       (center, radius, colors, pos, colorCount, mode, mapper));
   2526 }
   2527 
   2528 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start,
   2529                                                  SkScalar startRadius,
   2530                                                  const SkPoint& end,
   2531                                                  SkScalar endRadius,
   2532                                                  const SkColor colors[],
   2533                                                  const SkScalar pos[],
   2534                                                  int colorCount,
   2535                                                  SkShader::TileMode mode,
   2536                                                  SkUnitMapper* mapper) {
   2537     if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) {
   2538         return NULL;
   2539     }
   2540     EXPAND_1_COLOR(colorCount);
   2541 
   2542     return SkNEW_ARGS(Two_Point_Radial_Gradient,
   2543                       (start, startRadius, end, endRadius, colors, pos,
   2544                        colorCount, mode, mapper));
   2545 }
   2546 
   2547 SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy,
   2548                                         const SkColor colors[],
   2549                                         const SkScalar pos[],
   2550                                         int count, SkUnitMapper* mapper) {
   2551     if (NULL == colors || count < 1) {
   2552         return NULL;
   2553     }
   2554     EXPAND_1_COLOR(count);
   2555 
   2556     return SkNEW_ARGS(Sweep_Gradient, (cx, cy, colors, pos, count, mapper));
   2557 }
   2558 
   2559 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
   2560     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Linear_Gradient)
   2561     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Radial_Gradient)
   2562 
   2563     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Sweep_Gradient)
   2564 
   2565     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Two_Point_Radial_Gradient)
   2566 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
   2567