• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
Filter_565_Expanded(unsigned x,unsigned y,uint32_t a00,uint32_t a01,uint32_t a10,uint32_t a11)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
SkExpanded_565_To_PMColor(uint32_t c)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
Filter_4444_D32(unsigned x,unsigned y,uint32_t a00,uint32_t a01,uint32_t a10,uint32_t a11)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 
Filter_8(unsigned x,unsigned y,U8CPU a00,U8CPU a01,U8CPU a10,U8CPU a11)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 
valid_for_filtering(unsigned dimension)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 
chooseProcs(const SkMatrix & inv,const SkPaint & paint)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  */
maxCountForBufferSize(size_t bufferSize) const551 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