blob: 75d2791b3b2a44b09018499c7969e8cc0bdddf92 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkBitmapProcState.h"
reed@android.com152f7482009-08-07 19:14:34 +00009#include "SkBitmapProcState_filter.h"
reed@android.com8a1c16f2008-12-17 15:59:43 +000010#include "SkColorPriv.h"
11#include "SkFilterProc.h"
12#include "SkPaint.h"
13#include "SkShader.h" // for tilemodes
14
reed@android.com8a1c16f2008-12-17 15:59:43 +000015// returns expanded * 5bits
16static 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
36static 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
44static 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
64static 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
reed@android.com152f7482009-08-07 19:14:34 +000087#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 +000088
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
reed@android.com8a1c16f2008-12-17 15:59:43 +000096#include "SkBitmapProcState_sample.h"
97
reed@android.com152f7482009-08-07 19:14:34 +000098#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000101#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)
reed@android.com152f7482009-08-07 19:14:34 +0000106#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
107#define RETURNDST(src) SkAlphaMulQ(src, alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000109#include "SkBitmapProcState_sample.h"
110
111// SRC == 565
112
113#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000114#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000127#include "SkBitmapProcState_sample.h"
128
reed@android.com152f7482009-08-07 19:14:34 +0000129#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136#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)
reed@android.com152f7482009-08-07 19:14:34 +0000141#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
142#define RETURNDST(src) SkAlphaMulQ(SkPixel16ToPixel32(src), alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000144#include "SkBitmapProcState_sample.h"
145
146// SRC == Index8
147
148#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000149#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 +0000150
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]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false)
160#include "SkBitmapProcState_sample.h"
161
reed@android.com152f7482009-08-07 19:14:34 +0000162#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000165#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)
reed@android.com152f7482009-08-07 19:14:34 +0000170#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale; \
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 const SkPMColor* SK_RESTRICT table = state.fBitmap->getColorTable()->lockColors()
reed@android.com152f7482009-08-07 19:14:34 +0000172#define RETURNDST(src) SkAlphaMulQ(table[src], alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173#define SRC_TO_FILTER(src) table[src]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000174#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlockColors(false)
175#include "SkBitmapProcState_sample.h"
176
177// SRC == 4444
178
179#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000180#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 +0000181
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); \
reed@android.com152f7482009-08-07 19:14:34 +0000186 SkASSERT(state.fAlphaScale == 256)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000187#define RETURNDST(src) SkPixel4444ToPixel32(src)
188#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000189#include "SkBitmapProcState_sample.h"
190
reed@android.com152f7482009-08-07 19:14:34 +0000191#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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000198#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); \
reed@android.com152f7482009-08-07 19:14:34 +0000202 SkASSERT(state.fAlphaScale < 256)
203#define PREAMBLE(state) unsigned alphaScale = state.fAlphaScale
204#define RETURNDST(src) SkAlphaMulQ(SkPixel4444ToPixel32(src), alphaScale)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205#define SRC_TO_FILTER(src) src
reed@android.com8a1c16f2008-12-17 15:59:43 +0000206#include "SkBitmapProcState_sample.h"
207
208// SRC == A8
209
210#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000211#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000216
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000225#include "SkBitmapProcState_sample.h"
226
227/*****************************************************************************
228 *
229 * D16 functions
230 *
231 */
232
233// SRC == 8888
234
235#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000236#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000242
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000250#include "SkBitmapProcState_sample.h"
251
252// SRC == 565
253
254#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000255#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000260
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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000267#include "SkBitmapProcState_sample.h"
268
269// SRC == Index8
270
271#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000272#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)
reed@android.com8a1c16f2008-12-17 15:59:43 +0000277
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]
reed@android.com8a1c16f2008-12-17 15:59:43 +0000286#define POSTAMBLE(state) state.fBitmap->getColorTable()->unlock16BitCache()
287#include "SkBitmapProcState_sample.h"
288
reed@android.coma44b4cc2009-07-16 02:03:58 +0000289///////////////////////////////////////////////////////////////////////////////
290
291#undef FILTER_PROC
reed@android.com152f7482009-08-07 19:14:34 +0000292#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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000298
reed@android.comb577b412009-10-27 17:49:32 +0000299// clamp
300
reed@android.coma44b4cc2009-07-16 02:03:58 +0000301#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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000311#include "SkBitmapProcState_shaderproc.h"
312
reed@android.comaa9152a2009-07-17 21:24:56 +0000313
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
reed@android.comaa9152a2009-07-17 21:24:56 +0000324#include "SkBitmapProcState_shaderproc.h"
325
reed@android.comb577b412009-10-27 17:49:32 +0000326
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
reed@android.coma44b4cc2009-07-16 02:03:58 +0000343///////////////////////////////////////////////////////////////////////////////
344
reed@android.com8a1c16f2008-12-17 15:59:43 +0000345static 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
351bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
352 if (fOrigBitmap.width() == 0 || fOrigBitmap.height() == 0) {
353 return false;
354 }
reed@android.coma44b4cc2009-07-16 02:03:58 +0000355
reed@android.com07d1f002009-08-13 19:35:48 +0000356 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) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000362 m = &inv;
363 } else {
364 fUnitInvMatrix = inv;
365 fUnitInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
366 m = &fUnitInvMatrix;
367 }
reed@android.com07d1f002009-08-13 19:35:48 +0000368
reed@android.com8a1c16f2008-12-17 15:59:43 +0000369 fBitmap = &fOrigBitmap;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000370 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 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000388
389 fInvMatrix = m;
390 fInvProc = m->getMapXYProc();
391 fInvType = m->getType();
392 fInvSx = SkScalarToFixed(m->getScaleX());
reed@google.com4bc0a9d2012-03-07 21:47:41 +0000393 fInvSxFractionalInt = SkScalarToFractionalInt(m->getScaleX());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000394 fInvKy = SkScalarToFixed(m->getSkewY());
reed@google.com411215a2012-03-08 20:13:46 +0000395 fInvKyFractionalInt = SkScalarToFractionalInt(m->getSkewY());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000396
397 fAlphaScale = SkAlpha255To256(paint.getAlpha());
398
399 // pick-up filtering from the paint, but only if the matrix is
400 // more complex than identity/translate (i.e. no need to pay the cost
401 // of filtering if we're not scaled etc.).
402 // note: we explicitly check inv, since m might be scaled due to unitinv
403 // trickery, but we don't want to see that for this test
404 fDoFilter = paint.isFilterBitmap() &&
405 (inv.getType() > SkMatrix::kTranslate_Mask &&
406 valid_for_filtering(fBitmap->width() | fBitmap->height()));
407
reed@android.com7a99eb12009-07-16 01:13:14 +0000408 fShaderProc32 = NULL;
409 fShaderProc16 = NULL;
410 fSampleProc32 = NULL;
411 fSampleProc16 = NULL;
reed@android.com48534f92009-07-16 20:53:26 +0000412
reed@android.com07d1f002009-08-13 19:35:48 +0000413 fMatrixProc = this->chooseMatrixProc(trivial_matrix);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000414 if (NULL == fMatrixProc) {
415 return false;
416 }
417
418 ///////////////////////////////////////////////////////////////////////
419
420 int index = 0;
421 if (fAlphaScale < 256) { // note: this distinction is not used for D16
422 index |= 1;
423 }
424 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
425 index |= 2;
426 }
427 if (fDoFilter) {
428 index |= 4;
429 }
430 // bits 3,4,5 encoding the source bitmap format
431 switch (fBitmap->config()) {
432 case SkBitmap::kARGB_8888_Config:
433 index |= 0;
434 break;
435 case SkBitmap::kRGB_565_Config:
436 index |= 8;
437 break;
438 case SkBitmap::kIndex8_Config:
439 index |= 16;
440 break;
441 case SkBitmap::kARGB_4444_Config:
442 index |= 24;
443 break;
444 case SkBitmap::kA8_Config:
445 index |= 32;
446 fPaintPMColor = SkPreMultiplyColor(paint.getColor());
reed@android.com3469c762009-02-24 19:03:20 +0000447 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000448 default:
449 return false;
450 }
451
452 static const SampleProc32 gSample32[] = {
453 S32_opaque_D32_nofilter_DXDY,
454 S32_alpha_D32_nofilter_DXDY,
455 S32_opaque_D32_nofilter_DX,
456 S32_alpha_D32_nofilter_DX,
457 S32_opaque_D32_filter_DXDY,
458 S32_alpha_D32_filter_DXDY,
459 S32_opaque_D32_filter_DX,
460 S32_alpha_D32_filter_DX,
461
462 S16_opaque_D32_nofilter_DXDY,
463 S16_alpha_D32_nofilter_DXDY,
464 S16_opaque_D32_nofilter_DX,
465 S16_alpha_D32_nofilter_DX,
466 S16_opaque_D32_filter_DXDY,
467 S16_alpha_D32_filter_DXDY,
468 S16_opaque_D32_filter_DX,
469 S16_alpha_D32_filter_DX,
470
471 SI8_opaque_D32_nofilter_DXDY,
472 SI8_alpha_D32_nofilter_DXDY,
473 SI8_opaque_D32_nofilter_DX,
474 SI8_alpha_D32_nofilter_DX,
475 SI8_opaque_D32_filter_DXDY,
476 SI8_alpha_D32_filter_DXDY,
477 SI8_opaque_D32_filter_DX,
478 SI8_alpha_D32_filter_DX,
479
480 S4444_opaque_D32_nofilter_DXDY,
481 S4444_alpha_D32_nofilter_DXDY,
482 S4444_opaque_D32_nofilter_DX,
483 S4444_alpha_D32_nofilter_DX,
484 S4444_opaque_D32_filter_DXDY,
485 S4444_alpha_D32_filter_DXDY,
486 S4444_opaque_D32_filter_DX,
487 S4444_alpha_D32_filter_DX,
488
489 // A8 treats alpha/opauqe the same (equally efficient)
490 SA8_alpha_D32_nofilter_DXDY,
491 SA8_alpha_D32_nofilter_DXDY,
492 SA8_alpha_D32_nofilter_DX,
493 SA8_alpha_D32_nofilter_DX,
494 SA8_alpha_D32_filter_DXDY,
495 SA8_alpha_D32_filter_DXDY,
496 SA8_alpha_D32_filter_DX,
497 SA8_alpha_D32_filter_DX
498 };
499
500 static const SampleProc16 gSample16[] = {
501 S32_D16_nofilter_DXDY,
502 S32_D16_nofilter_DX,
503 S32_D16_filter_DXDY,
504 S32_D16_filter_DX,
505
506 S16_D16_nofilter_DXDY,
507 S16_D16_nofilter_DX,
508 S16_D16_filter_DXDY,
509 S16_D16_filter_DX,
510
511 SI8_D16_nofilter_DXDY,
512 SI8_D16_nofilter_DX,
513 SI8_D16_filter_DXDY,
514 SI8_D16_filter_DX,
515
516 // Don't support 4444 -> 565
517 NULL, NULL, NULL, NULL,
518 // Don't support A8 -> 565
519 NULL, NULL, NULL, NULL
520 };
reed@android.com48534f92009-07-16 20:53:26 +0000521
reed@android.com8a1c16f2008-12-17 15:59:43 +0000522 fSampleProc32 = gSample32[index];
523 index >>= 1; // shift away any opaque/alpha distinction
524 fSampleProc16 = gSample16[index];
525
reed@android.coma44b4cc2009-07-16 02:03:58 +0000526 // our special-case shaderprocs
reed@android.comaa9152a2009-07-17 21:24:56 +0000527 if (S16_D16_filter_DX == fSampleProc16) {
528 if (clamp_clamp) {
529 fShaderProc16 = Clamp_S16_D16_filter_DX_shaderproc;
530 } else if (SkShader::kRepeat_TileMode == fTileModeX &&
531 SkShader::kRepeat_TileMode == fTileModeY) {
532 fShaderProc16 = Repeat_S16_D16_filter_DX_shaderproc;
533 }
reed@android.comb577b412009-10-27 17:49:32 +0000534 } else if (SI8_opaque_D32_filter_DX == fSampleProc32 && clamp_clamp) {
535 fShaderProc32 = Clamp_SI8_opaque_D32_filter_DX_shaderproc;
reed@android.coma44b4cc2009-07-16 02:03:58 +0000536 }
reed@android.comc9a1d4b2009-08-03 15:05:55 +0000537
538 // see if our platform has any accelerated overrides
539 this->platformProcs();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000540 return true;
541}
542
reed@android.com4c128c42009-08-14 13:54:37 +0000543///////////////////////////////////////////////////////////////////////////////
544/*
545 The storage requirements for the different matrix procs are as follows,
546 where each X or Y is 2 bytes, and N is the number of pixels/elements:
547
548 scale/translate nofilter Y(4bytes) + N * X
549 affine/perspective nofilter N * (X Y)
550 scale/translate filter Y Y + N * (X X)
551 affine/perspective filter N * (Y Y X X)
552 */
553int SkBitmapProcState::maxCountForBufferSize(size_t bufferSize) const {
554 int32_t size = static_cast<int32_t>(bufferSize);
reed@android.com4c128c42009-08-14 13:54:37 +0000555
556 size &= ~3; // only care about 4-byte aligned chunks
557 if (fInvType <= (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)) {
558 size -= 4; // the shared Y (or YY) coordinate
559 if (size < 0) {
560 size = 0;
561 }
reed@android.com258cb222010-04-14 13:36:33 +0000562 size >>= 1;
reed@android.com4c128c42009-08-14 13:54:37 +0000563 } else {
reed@android.com258cb222010-04-14 13:36:33 +0000564 size >>= 2;
reed@android.com4c128c42009-08-14 13:54:37 +0000565 }
566
reed@android.com258cb222010-04-14 13:36:33 +0000567 if (fDoFilter) {
568 size >>= 1;
569 }
570
571 return size;
reed@android.com4c128c42009-08-14 13:54:37 +0000572}
573