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