Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      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 #include "SkBitmapProcState.h"
      9 #include "SkBitmapProcState_filter.h"
     10 #include "SkColorPriv.h"
     11 #include "SkFilterProc.h"
     12 #include "SkPaint.h"
     13 #include "SkShader.h"   // for tilemodes
     14 
     15 // returns expanded * 5bits
     16 static inline uint32_t Filter_565_Expanded(unsigned x, unsigned y,
     17                                            uint32_t a00, uint32_t a01,
     18                                            uint32_t a10, uint32_t a11) {
     19     SkASSERT((unsigned)x <= 0xF);
     20     SkASSERT((unsigned)y <= 0xF);
     21 
     22     a00 = SkExpand_rgb_16(a00);
     23     a01 = SkExpand_rgb_16(a01);
     24     a10 = SkExpand_rgb_16(a10);
     25     a11 = SkExpand_rgb_16(a11);
     26 
     27     int xy = x * y >> 3;
     28     return  a00 * (32 - 2*y - 2*x + xy) +
     29             a01 * (2*x - xy) +
     30             a10 * (2*y - xy) +
     31             a11 * xy;
     32 }
     33 
     34 // turn an expanded 565 * 5bits into SkPMColor
     35 // g:11 | r:10 | x:1 | b:10
     36 static inline SkPMColor SkExpanded_565_To_PMColor(uint32_t c) {
     37     unsigned r = (c >> 13) & 0xFF;
     38     unsigned g = (c >> 24);
     39     unsigned b = (c >> 2) & 0xFF;
     40     return SkPackARGB32(0xFF, r, g, b);
     41 }
     42 
     43 // returns answer in SkPMColor format
     44 static inline SkPMColor Filter_4444_D32(unsigned x, unsigned y,
     45                                         uint32_t a00, uint32_t a01,
     46                                         uint32_t a10, uint32_t a11) {
     47     SkASSERT((unsigned)x <= 0xF);
     48     SkASSERT((unsigned)y <= 0xF);
     49 
     50     a00 = SkExpand_4444(a00);
     51     a01 = SkExpand_4444(a01);
     52     a10 = SkExpand_4444(a10);
     53     a11 = SkExpand_4444(a11);
     54 
     55     int xy = x * y >> 4;
     56     uint32_t result =   a00 * (16 - y - x + xy) +
     57                         a01 * (x - xy) +
     58                         a10 * (y - xy) +
     59                         a11 * xy;
     60 
     61     return SkCompact_8888(result);
     62 }
     63 
     64 static inline U8CPU Filter_8(unsigned x, unsigned y,
     65                              U8CPU a00, U8CPU a01,
     66                              U8CPU a10, U8CPU a11) {
     67     SkASSERT((unsigned)x <= 0xF);
     68     SkASSERT((unsigned)y <= 0xF);
     69 
     70     int xy = x * y;
     71     unsigned result =   a00 * (256 - 16*y - 16*x + xy) +
     72                         a01 * (16*x - xy) +
     73                         a10 * (16*y - xy) +
     74                         a11 * xy;
     75 
     76     return result >> 8;
     77 }
     78 
     79 /*****************************************************************************
     80  *
     81  *  D32 functions
     82  *
     83  */
     84 
     85 // SRC == 8888
     86 
     87 #define FILTER_PROC(x, y, a, b, c, d, dst)   Filter_32_opaque(x, y, a, b, c, d, dst)
     88 
     89 #define MAKENAME(suffix)        S32_opaque_D32 ## suffix
     90 #define DSTSIZE                 32
     91 #define SRCTYPE                 SkPMColor
     92 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \
     93                                 SkASSERT(state.fAlphaScale == 256)
     94 #define RETURNDST(src)          src
     95 #define SRC_TO_FILTER(src)      src
     96 #include "SkBitmapProcState_sample.h"
     97 
     98 #undef FILTER_PROC
     99 #define FILTER_PROC(x, y, a, b, c, d, dst)   Filter_32_alpha(x, y, a, b, c, d, dst, alphaScale)
    100 
    101 #define MAKENAME(suffix)        S32_alpha_D32 ## suffix
    102 #define DSTSIZE                 32
    103 #define SRCTYPE                 SkPMColor
    104 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \
    105                                 SkASSERT(state.fAlphaScale < 256)
    106 #define PREAMBLE(state)         unsigned alphaScale = state.fAlphaScale
    107 #define RETURNDST(src)          SkAlphaMulQ(src, alphaScale)
    108 #define SRC_TO_FILTER(src)      src
    109 #include "SkBitmapProcState_sample.h"
    110 
    111 // SRC == 565
    112 
    113 #undef FILTER_PROC
    114 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    115     do {                                                        \
    116         uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d);   \
    117         *(dst) = SkExpanded_565_To_PMColor(tmp);                \
    118     } while (0)
    119 
    120 #define MAKENAME(suffix)        S16_opaque_D32 ## suffix
    121 #define DSTSIZE                 32
    122 #define SRCTYPE                 uint16_t
    123 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config); \
    124                                 SkASSERT(state.fAlphaScale == 256)
    125 #define RETURNDST(src)          SkPixel16ToPixel32(src)
    126 #define SRC_TO_FILTER(src)      src
    127 #include "SkBitmapProcState_sample.h"
    128 
    129 #undef FILTER_PROC
    130 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    131     do {                                                                    \
    132         uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d);               \
    133         *(dst) = SkAlphaMulQ(SkExpanded_565_To_PMColor(tmp), alphaScale);   \
    134     } while (0)
    135 
    136 #define MAKENAME(suffix)        S16_alpha_D32 ## suffix
    137 #define DSTSIZE                 32
    138 #define SRCTYPE                 uint16_t
    139 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config); \
    140                                 SkASSERT(state.fAlphaScale < 256)
    141 #define PREAMBLE(state)         unsigned alphaScale = state.fAlphaScale
    142 #define RETURNDST(src)          SkAlphaMulQ(SkPixel16ToPixel32(src), alphaScale)
    143 #define SRC_TO_FILTER(src)      src
    144 #include "SkBitmapProcState_sample.h"
    145 
    146 // SRC == Index8
    147 
    148 #undef FILTER_PROC
    149 #define FILTER_PROC(x, y, a, b, c, d, dst)   Filter_32_opaque(x, y, a, b, c, d, dst)
    150 
    151 #define MAKENAME(suffix)        SI8_opaque_D32 ## suffix
    152 #define DSTSIZE                 32
    153 #define SRCTYPE                 uint8_t
    154 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \
    155                                 SkASSERT(state.fAlphaScale == 256)
    156 #define PREAMBLE(state)         const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors()
    157 #define RETURNDST(src)          table[src]
    158 #define SRC_TO_FILTER(src)      table[src]
    159 #define POSTAMBLE(state)        state.fBitmap->getColorTable()->unlockColors(false)
    160 #include "SkBitmapProcState_sample.h"
    161 
    162 #undef FILTER_PROC
    163 #define FILTER_PROC(x, y, a, b, c, d, dst)   Filter_32_alpha(x, y, a, b, c, d, dst, alphaScale)
    164 
    165 #define MAKENAME(suffix)        SI8_alpha_D32 ## suffix
    166 #define DSTSIZE                 32
    167 #define SRCTYPE                 uint8_t
    168 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \
    169                                 SkASSERT(state.fAlphaScale < 256)
    170 #define PREAMBLE(state)         unsigned alphaScale = state.fAlphaScale; \
    171                                 const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors()
    172 #define RETURNDST(src)          SkAlphaMulQ(table[src], alphaScale)
    173 #define SRC_TO_FILTER(src)      table[src]
    174 #define POSTAMBLE(state)        state.fBitmap->getColorTable()->unlockColors(false)
    175 #include "SkBitmapProcState_sample.h"
    176 
    177 // SRC == 4444
    178 
    179 #undef FILTER_PROC
    180 #define FILTER_PROC(x, y, a, b, c, d, dst)  *(dst) = Filter_4444_D32(x, y, a, b, c, d)
    181 
    182 #define MAKENAME(suffix)        S4444_opaque_D32 ## suffix
    183 #define DSTSIZE                 32
    184 #define SRCTYPE                 SkPMColor16
    185 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_4444_Config); \
    186                                 SkASSERT(state.fAlphaScale == 256)
    187 #define RETURNDST(src)          SkPixel4444ToPixel32(src)
    188 #define SRC_TO_FILTER(src)      src
    189 #include "SkBitmapProcState_sample.h"
    190 
    191 #undef FILTER_PROC
    192 #define FILTER_PROC(x, y, a, b, c, d, dst)  \
    193     do {                                                    \
    194         uint32_t tmp = Filter_4444_D32(x, y, a, b, c, d);   \
    195         *(dst) = SkAlphaMulQ(tmp, alphaScale);              \
    196     } while (0)
    197 
    198 #define MAKENAME(suffix)        S4444_alpha_D32 ## suffix
    199 #define DSTSIZE                 32
    200 #define SRCTYPE                 SkPMColor16
    201 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_4444_Config); \
    202                                 SkASSERT(state.fAlphaScale < 256)
    203 #define PREAMBLE(state)         unsigned alphaScale = state.fAlphaScale
    204 #define RETURNDST(src)          SkAlphaMulQ(SkPixel4444ToPixel32(src), alphaScale)
    205 #define SRC_TO_FILTER(src)      src
    206 #include "SkBitmapProcState_sample.h"
    207 
    208 // SRC == A8
    209 
    210 #undef FILTER_PROC
    211 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    212     do {                                                        \
    213         unsigned tmp = Filter_8(x, y, a, b, c, d);              \
    214         *(dst) = SkAlphaMulQ(pmColor, SkAlpha255To256(tmp));    \
    215     } while (0)
    216 
    217 #define MAKENAME(suffix)        SA8_alpha_D32 ## suffix
    218 #define DSTSIZE                 32
    219 #define SRCTYPE                 uint8_t
    220 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kA8_Config); \
    221                                 SkASSERT(state.fAlphaScale == 256)
    222 #define PREAMBLE(state)         const SkPMColor pmColor = state.fPaintPMColor;
    223 #define RETURNDST(src)          SkAlphaMulQ(pmColor, SkAlpha255To256(src))
    224 #define SRC_TO_FILTER(src)      src
    225 #include "SkBitmapProcState_sample.h"
    226 
    227 /*****************************************************************************
    228  *
    229  *  D16 functions
    230  *
    231  */
    232 
    233 // SRC == 8888
    234 
    235 #undef FILTER_PROC
    236 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    237     do {                                                \
    238         SkPMColor dstColor;                             \
    239         Filter_32_opaque(x, y, a, b, c, d, &dstColor);  \
    240         (*dst) = SkPixel32ToPixel16(dstColor);          \
    241     } while (0)
    242 
    243 #define MAKENAME(suffix)        S32_D16 ## suffix
    244 #define DSTSIZE                 16
    245 #define SRCTYPE                 SkPMColor
    246 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kARGB_8888_Config); \
    247                                 SkASSERT(state.fBitmap->isOpaque())
    248 #define RETURNDST(src)          SkPixel32ToPixel16(src)
    249 #define SRC_TO_FILTER(src)      src
    250 #include "SkBitmapProcState_sample.h"
    251 
    252 // SRC == 565
    253 
    254 #undef FILTER_PROC
    255 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    256     do {                                                        \
    257         uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d);   \
    258         *(dst) = SkCompact_rgb_16((tmp) >> 5);                  \
    259     } while (0)
    260 
    261 #define MAKENAME(suffix)        S16_D16 ## suffix
    262 #define DSTSIZE                 16
    263 #define SRCTYPE                 uint16_t
    264 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config)
    265 #define RETURNDST(src)          src
    266 #define SRC_TO_FILTER(src)      src
    267 #include "SkBitmapProcState_sample.h"
    268 
    269 // SRC == Index8
    270 
    271 #undef FILTER_PROC
    272 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    273     do {                                                        \
    274         uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d);   \
    275         *(dst) = SkCompact_rgb_16((tmp) >> 5);                  \
    276     } while (0)
    277 
    278 #define MAKENAME(suffix)        SI8_D16 ## suffix
    279 #define DSTSIZE                 16
    280 #define SRCTYPE                 uint8_t
    281 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config); \
    282                                 SkASSERT(state.fBitmap->isOpaque())
    283 #define PREAMBLE(state)         const uint16_t* SK_RESTRICT table = state.fBitmap->getColorTable()->lock16BitCache()
    284 #define RETURNDST(src)          table[src]
    285 #define SRC_TO_FILTER(src)      table[src]
    286 #define POSTAMBLE(state)        state.fBitmap->getColorTable()->unlock16BitCache()
    287 #include "SkBitmapProcState_sample.h"
    288 
    289 ///////////////////////////////////////////////////////////////////////////////
    290 
    291 #undef FILTER_PROC
    292 #define FILTER_PROC(x, y, a, b, c, d, dst) \
    293     do {                                                        \
    294         uint32_t tmp = Filter_565_Expanded(x, y, a, b, c, d);   \
    295         *(dst) = SkCompact_rgb_16((tmp) >> 5);                  \
    296     } while (0)
    297 
    298 
    299 // clamp
    300 
    301 #define TILEX_PROCF(fx, max)    SkClampMax((fx) >> 16, max)
    302 #define TILEY_PROCF(fy, max)    SkClampMax((fy) >> 16, max)
    303 #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF)
    304 #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF)
    305 
    306 #define MAKENAME(suffix)        Clamp_S16_D16 ## suffix
    307 #define SRCTYPE                 uint16_t
    308 #define DSTTYPE                 uint16_t
    309 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config)
    310 #define SRC_TO_FILTER(src)      src
    311 #include "SkBitmapProcState_shaderproc.h"
    312 
    313 
    314 #define TILEX_PROCF(fx, max)    (((fx) & 0xFFFF) * ((max) + 1) >> 16)
    315 #define TILEY_PROCF(fy, max)    (((fy) & 0xFFFF) * ((max) + 1) >> 16)
    316 #define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
    317 #define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
    318 
    319 #define MAKENAME(suffix)        Repeat_S16_D16 ## suffix
    320 #define SRCTYPE                 uint16_t
    321 #define DSTTYPE                 uint16_t
    322 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kRGB_565_Config)
    323 #define SRC_TO_FILTER(src)      src
    324 #include "SkBitmapProcState_shaderproc.h"
    325 
    326 
    327 #define TILEX_PROCF(fx, max)    SkClampMax((fx) >> 16, max)
    328 #define TILEY_PROCF(fy, max)    SkClampMax((fy) >> 16, max)
    329 #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF)
    330 #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF)
    331 
    332 #undef FILTER_PROC
    333 #define FILTER_PROC(x, y, a, b, c, d, dst)   Filter_32_opaque(x, y, a, b, c, d, dst)
    334 #define MAKENAME(suffix)        Clamp_SI8_opaque_D32 ## suffix
    335 #define SRCTYPE                 uint8_t
    336 #define DSTTYPE                 uint32_t
    337 #define CHECKSTATE(state)       SkASSERT(state.fBitmap->config() == SkBitmap::kIndex8_Config)
    338 #define PREAMBLE(state)         const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors()
    339 #define SRC_TO_FILTER(src)      table[src]
    340 #define POSTAMBLE(state)        state.fBitmap->getColorTable()->unlockColors(false)
    341 #include "SkBitmapProcState_shaderproc.h"
    342 
    343 ///////////////////////////////////////////////////////////////////////////////
    344 
    345 static bool valid_for_filtering(unsigned dimension) {
    346     // for filtering, width and height must fit in 14bits, since we use steal
    347     // 2 bits from each to store our 4bit subpixel data
    348     return (dimension & ~0x3FFF) == 0;
    349 }
    350 
    351 bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
    352     if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
    353         return false;
    354     }
    355 
    356     const SkMatrix* m;
    357     bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0;
    358     bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX &&
    359                        SkShader::kClamp_TileMode == fTileModeY;
    360 
    361     if (clamp_clamp || trivial_matrix) {
    362         m = &inv;
    363     } else {
    364         fUnitInvMatrix = inv;
    365         fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
    366         m = &fUnitInvMatrix;
    367     }
    368 
    369     fBitmap = &fOrigBitmap;
    370     if (fOrigBitmap.hasMipMap()) {
    371         int shift = fOrigBitmap.extractMipLevel(&fMipBitmap,
    372                                                 SkScalarToFixed(m->getScaleX()),
    373                                                 SkScalarToFixed(m->getSkewY()));
    374 
    375         if (shift > 0) {
    376             if (m != &fUnitInvMatrix) {
    377                 fUnitInvMatrix = *m;
    378                 m = &fUnitInvMatrix;
    379             }
    380 
    381             SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
    382             fUnitInvMatrix.postScale(scale, scale);
    383 
    384             // now point here instead of fOrigBitmap
    385             fBitmap = &fMipBitmap;
    386         }
    387     }
    388 
    389     fInvMatrix      = m;
    390     fInvProc        = m->getMapXYProc();
    391     fInvType        = m->getType();
    392     fInvSx          = SkScalarToFixed(m->getScaleX());
    393     fInvKy          = SkScalarToFixed(m->getSkewY());
    394 
    395     fAlphaScale = SkAlpha255To256(paint.getAlpha());
    396 
    397     // pick-up filtering from the paint, but only if the matrix is
    398     // more complex than identity/translate (i.e. no need to pay the cost
    399     // of filtering if we're not scaled etc.).
    400     // note: we explicitly check inv, since m might be scaled due to unitinv
    401     //       trickery, but we don't want to see that for this test
    402     fDoFilter = paint.isFilterBitmap() &&
    403                 (inv.getType() > SkMatrix::kTranslate_Mask &&
    404                  valid_for_filtering(fBitmap->width() | fBitmap->height()));
    405 
    406     fShaderProc32 = NULL;
    407     fShaderProc16 = NULL;
    408     fSampleProc32 = NULL;
    409     fSampleProc16 = NULL;
    410 
    411     fMatrixProc = this->chooseMatrixProc(trivial_matrix);
    412     if (NULL == fMatrixProc) {
    413         return false;
    414     }
    415 
    416     ///////////////////////////////////////////////////////////////////////
    417 
    418     int index = 0;
    419     if (fAlphaScale < 256) {  // note: this distinction is not used for D16
    420         index |= 1;
    421     }
    422     if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
    423         index |= 2;
    424     }
    425     if (fDoFilter) {
    426         index |= 4;
    427     }
    428     // bits 3,4,5 encoding the source bitmap format
    429     switch (fBitmap->config()) {
    430         case SkBitmap::kARGB_8888_Config:
    431             index |= 0;
    432             break;
    433         case SkBitmap::kRGB_565_Config:
    434             index |= 8;
    435             break;
    436         case SkBitmap::kIndex8_Config:
    437             index |= 16;
    438             break;
    439         case SkBitmap::kARGB_4444_Config:
    440             index |= 24;
    441             break;
    442         case SkBitmap::kA8_Config:
    443             index |= 32;
    444             fPaintPMColor = SkPreMultiplyColor(paint.getColor());
    445             break;
    446         default:
    447             return false;
    448     }
    449 
    450     static const SampleProc32 gSample32[] = {
    451         S32_opaque_D32_nofilter_DXDY,
    452         S32_alpha_D32_nofilter_DXDY,
    453         S32_opaque_D32_nofilter_DX,
    454         S32_alpha_D32_nofilter_DX,
    455         S32_opaque_D32_filter_DXDY,
    456         S32_alpha_D32_filter_DXDY,
    457         S32_opaque_D32_filter_DX,
    458         S32_alpha_D32_filter_DX,
    459 
    460         S16_opaque_D32_nofilter_DXDY,
    461         S16_alpha_D32_nofilter_DXDY,
    462         S16_opaque_D32_nofilter_DX,
    463         S16_alpha_D32_nofilter_DX,
    464         S16_opaque_D32_filter_DXDY,
    465         S16_alpha_D32_filter_DXDY,
    466         S16_opaque_D32_filter_DX,
    467         S16_alpha_D32_filter_DX,
    468 
    469         SI8_opaque_D32_nofilter_DXDY,
    470         SI8_alpha_D32_nofilter_DXDY,
    471         SI8_opaque_D32_nofilter_DX,
    472         SI8_alpha_D32_nofilter_DX,
    473         SI8_opaque_D32_filter_DXDY,
    474         SI8_alpha_D32_filter_DXDY,
    475         SI8_opaque_D32_filter_DX,
    476         SI8_alpha_D32_filter_DX,
    477 
    478         S4444_opaque_D32_nofilter_DXDY,
    479         S4444_alpha_D32_nofilter_DXDY,
    480         S4444_opaque_D32_nofilter_DX,
    481         S4444_alpha_D32_nofilter_DX,
    482         S4444_opaque_D32_filter_DXDY,
    483         S4444_alpha_D32_filter_DXDY,
    484         S4444_opaque_D32_filter_DX,
    485         S4444_alpha_D32_filter_DX,
    486 
    487         // A8 treats alpha/opauqe the same (equally efficient)
    488         SA8_alpha_D32_nofilter_DXDY,
    489         SA8_alpha_D32_nofilter_DXDY,
    490         SA8_alpha_D32_nofilter_DX,
    491         SA8_alpha_D32_nofilter_DX,
    492         SA8_alpha_D32_filter_DXDY,
    493         SA8_alpha_D32_filter_DXDY,
    494         SA8_alpha_D32_filter_DX,
    495         SA8_alpha_D32_filter_DX
    496     };
    497 
    498     static const SampleProc16 gSample16[] = {
    499         S32_D16_nofilter_DXDY,
    500         S32_D16_nofilter_DX,
    501         S32_D16_filter_DXDY,
    502         S32_D16_filter_DX,
    503 
    504         S16_D16_nofilter_DXDY,
    505         S16_D16_nofilter_DX,
    506         S16_D16_filter_DXDY,
    507         S16_D16_filter_DX,
    508 
    509         SI8_D16_nofilter_DXDY,
    510         SI8_D16_nofilter_DX,
    511         SI8_D16_filter_DXDY,
    512         SI8_D16_filter_DX,
    513 
    514         // Don't support 4444 -> 565
    515         NULL, NULL, NULL, NULL,
    516         // Don't support A8 -> 565
    517         NULL, NULL, NULL, NULL
    518     };
    519 
    520     fSampleProc32 = gSample32[index];
    521     index >>= 1;    // shift away any opaque/alpha distinction
    522     fSampleProc16 = gSample16[index];
    523 
    524     // our special-case shaderprocs
    525     if (S16_D16_filter_DX == fSampleProc16) {
    526         if (clamp_clamp) {
    527             fShaderProc16 = Clamp_S16_D16_filter_DX_shaderproc;
    528         } else if (SkShader::kRepeat_TileMode == fTileModeX &&
    529                    SkShader::kRepeat_TileMode == fTileModeY) {
    530             fShaderProc16 = Repeat_S16_D16_filter_DX_shaderproc;
    531         }
    532     } else if (SI8_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) {
    533         fShaderProc32 = Clamp_SI8_opaque_D32_filter_DX_shaderproc;
    534     }
    535 
    536     // see if our platform has any accelerated overrides
    537     this->platformProcs();
    538     return true;
    539 }
    540 
    541 ///////////////////////////////////////////////////////////////////////////////
    542 /*
    543     The storage requirements for the different matrix procs are as follows,
    544     where each X or Y is 2 bytes, and N is the number of pixels/elements:
    545 
    546     scale/translate     nofilter      Y(4bytes) + N * X
    547     affine/perspective  nofilter      N * (X Y)
    548     scale/translate     filter        Y Y + N * (X X)
    549     affine/perspective  filter        N * (Y Y X X)
    550  */
    551 int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
    552     int32_t size = static_cast<int32_t>(bufferSize);
    553 
    554     size &= ~3; // only care about 4-byte aligned chunks
    555     if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
    556         size -= 4;   // the shared Y (or YY) coordinate
    557         if (size < 0) {
    558             size = 0;
    559         }
    560         size >>= 1;
    561     } else {
    562         size >>= 2;
    563     }
    564 
    565     if (fDoFilter) {
    566         size >>= 1;
    567     }
    568 
    569     return size;
    570 }
    571 
    572