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 0 : 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 0 : SkASSERT((unsigned)x <= 0xF);
20 0 : SkASSERT((unsigned)y <= 0xF);
21 :
22 0 : a00 = SkExpand_rgb_16(a00);
23 0 : a01 = SkExpand_rgb_16(a01);
24 0 : a10 = SkExpand_rgb_16(a10);
25 0 : a11 = SkExpand_rgb_16(a11);
26 :
27 0 : 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 0 : a11 * xy;
32 : }
33 :
34 : // turn an expanded 565 * 5bits into SkPMColor
35 : // g:11 | r:10 | x:1 | b:10
36 0 : static inline SkPMColor SkExpanded_565_To_PMColor(uint32_t c) {
37 0 : unsigned r = (c >> 13) & 0xFF;
38 0 : unsigned g = (c >> 24);
39 0 : unsigned b = (c >> 2) & 0xFF;
40 0 : return SkPackARGB32(0xFF, r, g, b);
41 : }
42 :
43 : // returns answer in SkPMColor format
44 0 : 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 0 : SkASSERT((unsigned)x <= 0xF);
48 0 : SkASSERT((unsigned)y <= 0xF);
49 :
50 0 : a00 = SkExpand_4444(a00);
51 0 : a01 = SkExpand_4444(a01);
52 0 : a10 = SkExpand_4444(a10);
53 0 : a11 = SkExpand_4444(a11);
54 :
55 0 : int xy = x * y >> 4;
56 : uint32_t result = a00 * (16 - y - x + xy) +
57 : a01 * (x - xy) +
58 : a10 * (y - xy) +
59 0 : a11 * xy;
60 :
61 0 : return SkCompact_8888(result);
62 : }
63 :
64 0 : static inline U8CPU Filter_8(unsigned x, unsigned y,
65 : U8CPU a00, U8CPU a01,
66 : U8CPU a10, U8CPU a11) {
67 0 : SkASSERT((unsigned)x <= 0xF);
68 0 : SkASSERT((unsigned)y <= 0xF);
69 :
70 0 : 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 0 : a11 * xy;
75 :
76 0 : 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 0 : 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 0 : return (dimension & ~0x3FFF) == 0;
349 : }
350 :
351 0 : bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
352 0 : if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
353 0 : return false;
354 : }
355 :
356 : const SkMatrix* m;
357 0 : bool trivial_matrix = (inv.getType() & ~SkMatrix::kTranslate_Mask) == 0;
358 : bool clamp_clamp = SkShader::kClamp_TileMode == fTileModeX &&
359 0 : SkShader::kClamp_TileMode == fTileModeY;
360 :
361 0 : if (clamp_clamp || trivial_matrix) {
362 0 : m = &inv;
363 : } else {
364 0 : fUnitInvMatrix = inv;
365 0 : fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
366 0 : m = &fUnitInvMatrix;
367 : }
368 :
369 0 : fBitmap = &fOrigBitmap;
370 0 : if (fOrigBitmap.hasMipMap()) {
371 : int shift = fOrigBitmap.extractMipLevel(&fMipBitmap,
372 0 : SkScalarToFixed(m->getScaleX()),
373 0 : SkScalarToFixed(m->getSkewY()));
374 :
375 0 : if (shift > 0) {
376 0 : if (m != &fUnitInvMatrix) {
377 0 : fUnitInvMatrix = *m;
378 0 : m = &fUnitInvMatrix;
379 : }
380 :
381 0 : SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift);
382 0 : fUnitInvMatrix.postScale(scale, scale);
383 :
384 : // now point here instead of fOrigBitmap
385 0 : fBitmap = &fMipBitmap;
386 : }
387 : }
388 :
389 0 : fInvMatrix = m;
390 0 : fInvProc = m->getMapXYProc();
391 0 : fInvType = m->getType();
392 0 : fInvSx = SkScalarToFixed(m->getScaleX());
393 0 : fInvKy = SkScalarToFixed(m->getSkewY());
394 :
395 0 : 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 0 : fDoFilter = paint.isFilterBitmap() &&
403 0 : (inv.getType() > SkMatrix::kTranslate_Mask &&
404 0 : valid_for_filtering(fBitmap->width() | fBitmap->height()));
405 :
406 0 : fShaderProc32 = NULL;
407 0 : fShaderProc16 = NULL;
408 0 : fSampleProc32 = NULL;
409 0 : fSampleProc16 = NULL;
410 :
411 0 : fMatrixProc = this->chooseMatrixProc(trivial_matrix);
412 0 : if (NULL == fMatrixProc) {
413 0 : return false;
414 : }
415 :
416 : ///////////////////////////////////////////////////////////////////////
417 :
418 0 : int index = 0;
419 0 : if (fAlphaScale < 256) { // note: this distinction is not used for D16
420 0 : index |= 1;
421 : }
422 0 : if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
423 0 : index |= 2;
424 : }
425 0 : if (fDoFilter) {
426 0 : index |= 4;
427 : }
428 : // bits 3,4,5 encoding the source bitmap format
429 0 : switch (fBitmap->config()) {
430 : case SkBitmap::kARGB_8888_Config:
431 0 : index |= 0;
432 0 : break;
433 : case SkBitmap::kRGB_565_Config:
434 0 : index |= 8;
435 0 : break;
436 : case SkBitmap::kIndex8_Config:
437 0 : index |= 16;
438 0 : break;
439 : case SkBitmap::kARGB_4444_Config:
440 0 : index |= 24;
441 0 : break;
442 : case SkBitmap::kA8_Config:
443 0 : index |= 32;
444 0 : fPaintPMColor = SkPreMultiplyColor(paint.getColor());
445 0 : break;
446 : default:
447 0 : 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 0 : fSampleProc32 = gSample32[index];
521 0 : index >>= 1; // shift away any opaque/alpha distinction
522 0 : fSampleProc16 = gSample16[index];
523 :
524 : // our special-case shaderprocs
525 0 : if (S16_D16_filter_DX == fSampleProc16) {
526 0 : if (clamp_clamp) {
527 0 : fShaderProc16 = Clamp_S16_D16_filter_DX_shaderproc;
528 0 : } else if (SkShader::kRepeat_TileMode == fTileModeX &&
529 : SkShader::kRepeat_TileMode == fTileModeY) {
530 0 : fShaderProc16 = Repeat_S16_D16_filter_DX_shaderproc;
531 : }
532 0 : } else if (SI8_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) {
533 0 : fShaderProc32 = Clamp_SI8_opaque_D32_filter_DX_shaderproc;
534 : }
535 :
536 : // see if our platform has any accelerated overrides
537 0 : this->platformProcs();
538 0 : 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 0 : int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
552 0 : int32_t size = static_cast<int32_t>(bufferSize);
553 :
554 0 : size &= ~3; // only care about 4-byte aligned chunks
555 0 : if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
556 0 : size -= 4; // the shared Y (or YY) coordinate
557 0 : if (size < 0) {
558 0 : size = 0;
559 : }
560 0 : size >>= 1;
561 : } else {
562 0 : size >>= 2;
563 : }
564 :
565 0 : if (fDoFilter) {
566 0 : size >>= 1;
567 : }
568 :
569 0 : return size;
570 : }
571 :
|