OLD | NEW |
| (Empty) |
1 /* libs/graphics/sgl/SkSpriteBlitter_RGB16.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkSpriteBlitter.h" | |
19 #include "SkBlitRow.h" | |
20 #include "SkTemplates.h" | |
21 #include "SkUtils.h" | |
22 #include "SkColorPriv.h" | |
23 | |
24 #define D16_S32A_Opaque_Pixel(dst, sc) \ | |
25 do { \ | |
26 if (sc) { \ | |
27 *dst = SkSrcOver32To16(sc, *dst); \ | |
28 } \ | |
29 } while (0) | |
30 | |
31 static inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc, | |
32 unsigned src_scale) { | |
33 uint16_t dc = *dst; | |
34 unsigned sa = SkGetPackedA32(sc); | |
35 unsigned dr, dg, db; | |
36 | |
37 if (255 == sa) { | |
38 dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale); | |
39 dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale); | |
40 db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale); | |
41 } else { | |
42 unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale); | |
43 dr = (SkPacked32ToR16(sc) * src_scale + | |
44 SkGetPackedR16(dc) * dst_scale) >> 8; | |
45 dg = (SkPacked32ToG16(sc) * src_scale + | |
46 SkGetPackedG16(dc) * dst_scale) >> 8; | |
47 db = (SkPacked32ToB16(sc) * src_scale + | |
48 SkGetPackedB16(dc) * dst_scale) >> 8; | |
49 } | |
50 *dst = SkPackRGB16(dr, dg, db); | |
51 } | |
52 | |
53 #define D16_S32A_Blend_Pixel(dst, sc, src_scale) \ | |
54 do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0) | |
55 | |
56 | |
57 /////////////////////////////////////////////////////////////////////////////// | |
58 | |
59 class Sprite_D16_S16_Opaque : public SkSpriteBlitter { | |
60 public: | |
61 Sprite_D16_S16_Opaque(const SkBitmap& source) | |
62 : SkSpriteBlitter(source) {} | |
63 | |
64 // overrides | |
65 virtual void blitRect(int x, int y, int width, int height) { | |
66 SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); | |
67 const SK_RESTRICT uint16_t* src = fSource->getAddr16(x - fLeft, | |
68 y - fTop); | |
69 unsigned dstRB = fDevice->rowBytes(); | |
70 unsigned srcRB = fSource->rowBytes(); | |
71 | |
72 while (--height >= 0) { | |
73 memcpy(dst, src, width << 1); | |
74 dst = (uint16_t*)((char*)dst + dstRB); | |
75 src = (const uint16_t*)((const char*)src + srcRB); | |
76 } | |
77 } | |
78 }; | |
79 | |
80 #define D16_S16_Blend_Pixel(dst, sc, scale) \ | |
81 do { \ | |
82 uint16_t dc = *dst; \ | |
83 *dst = SkBlendRGB16(sc, dc, scale); \ | |
84 } while (0) | |
85 | |
86 #define SkSPRITE_CLASSNAME Sprite_D16_S16_Blend | |
87 #define SkSPRITE_ARGS , uint8_t alpha | |
88 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
89 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
90 #define SkSPRITE_DST_TYPE uint16_t | |
91 #define SkSPRITE_SRC_TYPE uint16_t | |
92 #define SkSPRITE_DST_GETADDR getAddr16 | |
93 #define SkSPRITE_SRC_GETADDR getAddr16 | |
94 #define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlph
a); | |
95 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale) | |
96 #define SkSPRITE_NEXT_ROW | |
97 #define SkSPRITE_POSTAMBLE(srcBM) | |
98 #include "SkSpriteBlitterTemplate.h" | |
99 | |
100 /////////////////////////////////////////////////////////////////////////////// | |
101 | |
102 #define D16_S4444_Opaque(dst, sc) \ | |
103 do { \ | |
104 uint16_t dc = *dst; \ | |
105 *dst = SkSrcOver4444To16(sc, dc); \ | |
106 } while (0) | |
107 | |
108 #define SkSPRITE_CLASSNAME Sprite_D16_S4444_Opaque | |
109 #define SkSPRITE_ARGS | |
110 #define SkSPRITE_FIELDS | |
111 #define SkSPRITE_INIT | |
112 #define SkSPRITE_DST_TYPE uint16_t | |
113 #define SkSPRITE_SRC_TYPE SkPMColor16 | |
114 #define SkSPRITE_DST_GETADDR getAddr16 | |
115 #define SkSPRITE_SRC_GETADDR getAddr16 | |
116 #define SkSPRITE_PREAMBLE(srcBM, x, y) | |
117 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src) | |
118 #define SkSPRITE_NEXT_ROW | |
119 #define SkSPRITE_POSTAMBLE(srcBM) | |
120 #include "SkSpriteBlitterTemplate.h" | |
121 | |
122 #define D16_S4444_Blend(dst, sc, scale16) \ | |
123 do { \ | |
124 uint16_t dc = *dst; \ | |
125 *dst = SkBlend4444To16(sc, dc, scale16); \ | |
126 } while (0) | |
127 | |
128 | |
129 #define SkSPRITE_CLASSNAME Sprite_D16_S4444_Blend | |
130 #define SkSPRITE_ARGS , uint8_t alpha | |
131 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
132 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
133 #define SkSPRITE_DST_TYPE uint16_t | |
134 #define SkSPRITE_SRC_TYPE uint16_t | |
135 #define SkSPRITE_DST_GETADDR getAddr16 | |
136 #define SkSPRITE_SRC_GETADDR getAddr16 | |
137 #define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha)
; | |
138 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale) | |
139 #define SkSPRITE_NEXT_ROW | |
140 #define SkSPRITE_POSTAMBLE(srcBM) | |
141 #include "SkSpriteBlitterTemplate.h" | |
142 | |
143 /////////////////////////////////////////////////////////////////////////////// | |
144 | |
145 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Opaque | |
146 #define SkSPRITE_ARGS | |
147 #define SkSPRITE_FIELDS | |
148 #define SkSPRITE_INIT | |
149 #define SkSPRITE_DST_TYPE uint16_t | |
150 #define SkSPRITE_SRC_TYPE uint8_t | |
151 #define SkSPRITE_DST_GETADDR getAddr16 | |
152 #define SkSPRITE_SRC_GETADDR getAddr8 | |
153 #define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getC
olorTable()->lockColors() | |
154 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[sr
c]) | |
155 #define SkSPRITE_NEXT_ROW | |
156 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(
false) | |
157 #include "SkSpriteBlitterTemplate.h" | |
158 | |
159 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8A_Blend | |
160 #define SkSPRITE_ARGS , uint8_t alpha | |
161 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
162 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
163 #define SkSPRITE_DST_TYPE uint16_t | |
164 #define SkSPRITE_SRC_TYPE uint8_t | |
165 #define SkSPRITE_DST_GETADDR getAddr16 | |
166 #define SkSPRITE_SRC_GETADDR getAddr8 | |
167 #define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.getC
olorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); | |
168 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src
], src_scale) | |
169 #define SkSPRITE_NEXT_ROW | |
170 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlockColors(
false); | |
171 #include "SkSpriteBlitterTemplate.h" | |
172 | |
173 /////////////////////////////////////////////////////////////////////////////// | |
174 | |
175 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Opaque | |
176 #define SkSPRITE_ARGS | |
177 #define SkSPRITE_FIELDS | |
178 #define SkSPRITE_INIT | |
179 #define SkSPRITE_DST_TYPE uint16_t | |
180 #define SkSPRITE_SRC_TYPE uint8_t | |
181 #define SkSPRITE_DST_GETADDR getAddr16 | |
182 #define SkSPRITE_SRC_GETADDR getAddr8 | |
183 #define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getCo
lorTable()->lock16BitCache() | |
184 #define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src] | |
185 #define SkSPRITE_NEXT_ROW | |
186 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCa
che() | |
187 #include "SkSpriteBlitterTemplate.h" | |
188 | |
189 #define SkSPRITE_CLASSNAME Sprite_D16_SIndex8_Blend | |
190 #define SkSPRITE_ARGS , uint8_t alpha | |
191 #define SkSPRITE_FIELDS uint8_t fSrcAlpha; | |
192 #define SkSPRITE_INIT fSrcAlpha = alpha; | |
193 #define SkSPRITE_DST_TYPE uint16_t | |
194 #define SkSPRITE_SRC_TYPE uint8_t | |
195 #define SkSPRITE_DST_GETADDR getAddr16 | |
196 #define SkSPRITE_SRC_GETADDR getAddr8 | |
197 #define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.getCo
lorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha); | |
198 #define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src]
, src_scale) | |
199 #define SkSPRITE_NEXT_ROW | |
200 #define SkSPRITE_POSTAMBLE(srcBM) srcBM.getColorTable()->unlock16BitCa
che(); | |
201 #include "SkSpriteBlitterTemplate.h" | |
202 | |
203 /////////////////////////////////////////////////////////////////////////////// | |
204 | |
205 class Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter { | |
206 public: | |
207 Sprite_D16_S32_BlitRowProc(const SkBitmap& source) | |
208 : SkSpriteBlitter(source) {} | |
209 | |
210 // overrides | |
211 | |
212 virtual void setup(const SkBitmap& device, int left, int top, | |
213 const SkPaint& paint) { | |
214 this->INHERITED::setup(device, left, top, paint); | |
215 | |
216 unsigned flags = 0; | |
217 | |
218 if (paint.getAlpha() < 0xFF) { | |
219 flags |= SkBlitRow::kGlobalAlpha_Flag; | |
220 } | |
221 if (!fSource->isOpaque()) { | |
222 flags |= SkBlitRow::kSrcPixelAlpha_Flag; | |
223 } | |
224 if (paint.isDither()) { | |
225 flags |= SkBlitRow::kDither_Flag; | |
226 } | |
227 fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); | |
228 } | |
229 | |
230 virtual void blitRect(int x, int y, int width, int height) { | |
231 SK_RESTRICT uint16_t* dst = fDevice->getAddr16(x, y); | |
232 const SK_RESTRICT SkPMColor* src = fSource->getAddr32(x - fLeft, | |
233 y - fTop); | |
234 unsigned dstRB = fDevice->rowBytes(); | |
235 unsigned srcRB = fSource->rowBytes(); | |
236 SkBlitRow::Proc proc = fProc; | |
237 U8CPU alpha = fPaint->getAlpha(); | |
238 | |
239 while (--height >= 0) { | |
240 proc(dst, src, width, alpha, x, y); | |
241 y += 1; | |
242 dst = (SK_RESTRICT uint16_t*)((char*)dst + dstRB); | |
243 src = (const SK_RESTRICT SkPMColor*)((const char*)src + srcRB); | |
244 } | |
245 } | |
246 | |
247 private: | |
248 SkBlitRow::Proc fProc; | |
249 | |
250 typedef SkSpriteBlitter INHERITED; | |
251 }; | |
252 | |
253 /////////////////////////////////////////////////////////////////////////////// | |
254 | |
255 #include "SkTemplatesPriv.h" | |
256 | |
257 SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, | |
258 const SkPaint& paint, | |
259 void* storage, size_t storageSize) { | |
260 if (paint.getMaskFilter() != NULL) { // may add cases for this | |
261 return NULL; | |
262 } | |
263 if (paint.getXfermode() != NULL) { // may add cases for this | |
264 return NULL; | |
265 } | |
266 if (paint.getColorFilter() != NULL) { // may add cases for this | |
267 return NULL; | |
268 } | |
269 | |
270 SkSpriteBlitter* blitter = NULL; | |
271 unsigned alpha = paint.getAlpha(); | |
272 | |
273 switch (source.getConfig()) { | |
274 case SkBitmap::kARGB_8888_Config: | |
275 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc, | |
276 storage, storageSize, (source)); | |
277 break; | |
278 case SkBitmap::kARGB_4444_Config: | |
279 if (255 == alpha) { | |
280 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque, | |
281 storage, storageSize, (source)); | |
282 } else { | |
283 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend, | |
284 storage, storageSize, (source, alpha >> 4)); | |
285 } | |
286 break; | |
287 case SkBitmap::kRGB_565_Config: | |
288 if (255 == alpha) { | |
289 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque, | |
290 storage, storageSize, (source)); | |
291 } else { | |
292 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend, | |
293 storage, storageSize, (source, alpha)); | |
294 } | |
295 break; | |
296 case SkBitmap::kIndex8_Config: | |
297 if (source.isOpaque()) { | |
298 if (255 == alpha) { | |
299 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque, | |
300 storage, storageSize, (source)); | |
301 } else { | |
302 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend, | |
303 storage, storageSize, (source, alpha)); | |
304 } | |
305 } else { | |
306 if (255 == alpha) { | |
307 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque, | |
308 storage, storageSize, (source)); | |
309 } else { | |
310 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend, | |
311 storage, storageSize, (source, alpha)); | |
312 } | |
313 } | |
314 break; | |
315 default: | |
316 break; | |
317 } | |
318 return blitter; | |
319 } | |
320 | |
OLD | NEW |