blob: eabd9665e1c3d7e0f74dc58c37a300a1ad2181be [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SkBitmapProcState.h"
reed@android.com152f7482009-08-07 19:14:34 +00002#include "SkBitmapProcState_filter.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +00003#include "SkColorPriv.h"
4#include "SkFilterProc.h"
5#include "SkPaint.h"
6#include "SkShader.h" // for tilemodes
7
reed@android.com8a1c16f2008-12-17 15:59:43 +00008// returns expanded * 5bits
9static 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
29static 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
37static 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
57static 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
reed@android.com152f7482009-08-07 19:14:34 +000080#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_opaque(x, y, a, b, c, d, dst)
reed@android.com8a1c16f2008-12-17 15:59:43 +000081
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
reed@android.com8a1c16f2008-12-17 15:59:43 +000089#include "SkBitmapProcState_sample.h"
90
reed@android.com152f7482009-08-07 19:14:34 +000091#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
reed@android.com8a1c16f2008-12-17 15:59:43 +000094#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)
reed@android.com152f7482009-08-07 19:14:34 +000099#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
100#define RETURNDST(src) SkAlphaMulQ(src, alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000101#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102#include "SkBitmapProcState_sample.h"
103
104// SRC == 565
105
106#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000107#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000112
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000120#include "SkBitmapProcState_sample.h"
121
reed@android.com152f7482009-08-07 19:14:34 +0000122#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129#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)
reed@android.com152f7482009-08-07 19:14:34 +0000134#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
135#define RETURNDST(src) SkAlphaMulQ(SkPixel16ToPixel32(src), alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000137#include "SkBitmapProcState_sample.h"
138
139// SRC == Index8
140
141#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000142#define FILTER_PROC(x, y, a, b, c, d, dst) Filter_32_opaque(x, y, a, b, c, d, dst)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143
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]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false)
153#include "SkBitmapProcState_sample.h"
154
reed@android.com152f7482009-08-07 19:14:34 +0000155#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158#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)
reed@android.com152f7482009-08-07 19:14:34 +0000163#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale; \
reed@android.com8a1c16f2008-12-17 15:59:43 +0000164 const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors()
reed@android.com152f7482009-08-07 19:14:34 +0000165#define RETURNDST(src) SkAlphaMulQ(table[src], alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000166#define SRC_TO_FILTER(src) table[src]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000167#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false)
168#include "SkBitmapProcState_sample.h"
169
170// SRC == 4444
171
172#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000173#define FILTER_PROC(x, y, a, b, c, d, dst) *(dst) = Filter_4444_D32(x, y, a, b, c, d)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000174
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); \
reed@android.com152f7482009-08-07 19:14:34 +0000179 SkASSERT(state.fAlphaScale == 256)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000180#define RETURNDST(src) SkPixel4444ToPixel32(src)
181#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000182#include "SkBitmapProcState_sample.h"
183
reed@android.com152f7482009-08-07 19:14:34 +0000184#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000191#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); \
reed@android.com152f7482009-08-07 19:14:34 +0000195 SkASSERT(state.fAlphaScale < 256)
196#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
197#define RETURNDST(src) SkAlphaMulQ(SkPixel4444ToPixel32(src), alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000198#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000199#include "SkBitmapProcState_sample.h"
200
201// SRC == A8
202
203#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000204#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000209
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000218#include "SkBitmapProcState_sample.h"
219
220/*****************************************************************************
221 *
222 * D16 functions
223 *
224 */
225
226// SRC == 8888
227
228#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000229#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000243#include "SkBitmapProcState_sample.h"
244
245// SRC == 565
246
247#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000248#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000253
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000260#include "SkBitmapProcState_sample.h"
261
262// SRC == Index8
263
264#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000265#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000270
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]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000279#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlock16BitCache()
280#include "SkBitmapProcState_sample.h"
281
reed@android.coma44b4cc2009-07-16 02:03:58 +0000282///////////////////////////////////////////////////////////////////////////////
283
284#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000285#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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000291
reed@android.comb577b412009-10-27 17:49:32 +0000292// clamp
293
reed@android.coma44b4cc2009-07-16 02:03:58 +0000294#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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000304#include "SkBitmapProcState_shaderproc.h"
305
reed@android.comaa9152a2009-07-17 21:24:56 +0000306
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
reed@android.comaa9152a2009-07-17 21:24:56 +0000317#include "SkBitmapProcState_shaderproc.h"
318
reed@android.comb577b412009-10-27 17:49:32 +0000319
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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000336///////////////////////////////////////////////////////////////////////////////
337
reed@android.com8a1c16f2008-12-17 15:59:43 +0000338static 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
344bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
345 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
346 return false;
347 }
reed@android.coma44b4cc2009-07-16 02:03:58 +0000348
reed@android.com07d1f002009-08-13 19:35:48 +0000349 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) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000355 m = &inv;
356 } else {
357 fUnitInvMatrix = inv;
358 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
359 m = &fUnitInvMatrix;
360 }
reed@android.com07d1f002009-08-13 19:35:48 +0000361
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362 fBitmap = &fOrigBitmap;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000363 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 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000381
382 fInvMatrix = m;
383 fInvProc = m->getMapXYProc();
384 fInvType = m->getType();
385 fInvSx = SkScalarToFixed(m->getScaleX());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000386 fInvKy = SkScalarToFixed(m->getSkewY());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000387
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
reed@android.com7a99eb12009-07-16 01:13:14 +0000399 fShaderProc32 = NULL;
400 fShaderProc16 = NULL;
401 fSampleProc32 = NULL;
402 fSampleProc16 = NULL;
reed@android.com48534f92009-07-16 20:53:26 +0000403
reed@android.com07d1f002009-08-13 19:35:48 +0000404 fMatrixProc = this->chooseMatrixProc(trivial_matrix);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000405 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());
reed@android.com3469c762009-02-24 19:03:20 +0000438 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000439 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 };
reed@android.com48534f92009-07-16 20:53:26 +0000512
reed@android.com8a1c16f2008-12-17 15:59:43 +0000513 fSampleProc32 = gSample32[index];
514 index >>= 1; // shift away any opaque/alpha distinction
515 fSampleProc16 = gSample16[index];
516
reed@android.coma44b4cc2009-07-16 02:03:58 +0000517 // our special-case shaderprocs
reed@android.comaa9152a2009-07-17 21:24:56 +0000518 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 }
reed@android.comb577b412009-10-27 17:49:32 +0000525 } else if (SI8_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) {
526 fShaderProc32 = Clamp_SI8_opaque_D32_filter_DX_shaderproc;
reed@android.coma44b4cc2009-07-16 02:03:58 +0000527 }
reed@android.comc9a1d4b2009-08-03 15:05:55 +0000528
529 // see if our platform has any accelerated overrides
530 this->platformProcs();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000531 return true;
532}
533
reed@android.com4c128c42009-08-14 13:54:37 +0000534///////////////////////////////////////////////////////////////////////////////
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 */
544int 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