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