OLD | NEW |
| (Empty) |
1 /* libs/graphics/sgl/SkSpriteBlitter_ARGB32.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 "SkTemplates.h" | |
20 #include "SkUtils.h" | |
21 #include "SkColorPriv.h" | |
22 | |
23 #define D32_S32A_Opaque_Pixel(dst, sc) \ | |
24 do { \ | |
25 if (sc) { \ | |
26 unsigned srcA = SkGetPackedA32(sc); \ | |
27 uint32_t result = sc; \ | |
28 if (srcA != 0xFF) { \ | |
29 result += SkAlphaMulQ(*dst, SkAlpha255To256(255 - srcA)); \ | |
30 } \ | |
31 *dst = result; \ | |
32 } \ | |
33 } while (0) | |
34 | |
35 #define SkSPRITE_CLASSNAME Sprite_D32_S32A_Opaque | |
36 #define SkSPRITE_ARGS | |
37 #define SkSPRITE_FIELDS | |
38 #define SkSPRITE_INIT | |
39 #define SkSPRITE_DST_TYPE uint32_t | |
40 #define SkSPRITE_SRC_TYPE uint32_t | |
41 #define SkSPRITE_DST_GETADDR getAddr32 | |
42 #define SkSPRITE_SRC_GETADDR getAddr32 | |
43 #define SkSPRITE_PREAMBLE(srcBM, x, y) | |
44 #define SkSPRITE_BLIT_PIXEL(dst, src) D32_S32A_Opaque_Pixel(dst, src) | |
45 #define SkSPRITE_NEXT_ROW | |
46 #define SkSPRITE_POSTAMBLE(srcBM) | |
47 #include "SkSpriteBlitterTemplate.h" | |
48 | |
49 /////////////////////////////////////////////////////////////////////////////// | |
50 | |
51 class Sprite_D32_S32_Opaque : public SkSpriteBlitter { | |
52 public: | |
53 Sprite_D32_S32_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
54 | |
55 virtual void blitRect(int x, int y, int width, int height) { | |
56 SkASSERT(width > 0 && height > 0); | |
57 SK_RESTRICT uint32_t* dst = fDevice->getAddr32(x, y); | |
58 const SK_RESTRICT uint32_t* src = fSource->getAddr32(x - fLeft, | |
59 y - fTop); | |
60 unsigned dstRB = fDevice->rowBytes(); | |
61 unsigned srcRB = fSource->rowBytes(); | |
62 size_t size = width * sizeof(uint32_t); | |
63 | |
64 do { | |
65 memcpy(dst, src, size); | |
66 dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); | |
67 src = (const SK_RESTRICT uint32_t*)((const char*)src + srcRB); | |
68 } while (--height != 0); | |
69 } | |
70 }; | |
71 | |
72 /////////////////////////////////////////////////////////////////////////////// | |
73 | |
74 #include "SkColorFilter.h" | |
75 #include "SkXfermode.h" | |
76 | |
77 class Sprite_D32_XferFilter : public SkSpriteBlitter { | |
78 public: | |
79 Sprite_D32_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
80 : SkSpriteBlitter(source) { | |
81 fColorFilter = paint.getColorFilter(); | |
82 fColorFilter->safeRef(); | |
83 | |
84 fXfermode = paint.getXfermode(); | |
85 fXfermode->safeRef(); | |
86 | |
87 fBufferSize = 0; | |
88 fBuffer = NULL; | |
89 } | |
90 | |
91 virtual ~Sprite_D32_XferFilter() { | |
92 delete[] fBuffer; | |
93 fXfermode->safeUnref(); | |
94 fColorFilter->safeUnref(); | |
95 } | |
96 | |
97 virtual void setup(const SkBitmap& device, int left, int top, | |
98 const SkPaint& paint) { | |
99 this->INHERITED::setup(device, left, top, paint); | |
100 | |
101 int width = device.width(); | |
102 if (width > fBufferSize) { | |
103 fBufferSize = width; | |
104 delete[] fBuffer; | |
105 fBuffer = new SkPMColor[width]; | |
106 } | |
107 } | |
108 | |
109 protected: | |
110 SkColorFilter* fColorFilter; | |
111 SkXfermode* fXfermode; | |
112 int fBufferSize; | |
113 SkPMColor* fBuffer; | |
114 | |
115 private: | |
116 typedef SkSpriteBlitter INHERITED; | |
117 }; | |
118 | |
119 /////////////////////////////////////////////////////////////////////////////// | |
120 | |
121 class Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter { | |
122 public: | |
123 Sprite_D32_S32A_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
124 : Sprite_D32_XferFilter(source, paint) {} | |
125 | |
126 virtual void blitRect(int x, int y, int width, int height) { | |
127 SkASSERT(width > 0 && height > 0); | |
128 SK_RESTRICT uint32_t* dst = fDevice->getAddr32(x, y); | |
129 const SK_RESTRICT uint32_t* src = fSource->getAddr32(x - fLeft, | |
130 y - fTop); | |
131 unsigned dstRB = fDevice->rowBytes(); | |
132 unsigned srcRB = fSource->rowBytes(); | |
133 SkColorFilter* colorFilter = fColorFilter; | |
134 SkXfermode* xfermode = fXfermode; | |
135 | |
136 do { | |
137 const SkPMColor* tmp = src; | |
138 | |
139 if (NULL != colorFilter) { | |
140 colorFilter->filterSpan(src, width, fBuffer); | |
141 tmp = fBuffer; | |
142 } | |
143 | |
144 if (NULL != xfermode) { | |
145 xfermode->xfer32(dst, tmp, width, NULL); | |
146 } else { | |
147 for (int i = 0; i < width; i++) { | |
148 dst[i] = SkPMSrcOver(tmp[i], dst[i]); | |
149 } | |
150 } | |
151 | |
152 dst = (SK_RESTRICT uint32_t*)((char*)dst + dstRB); | |
153 src = (const SK_RESTRICT uint32_t*)((const char*)src + srcRB); | |
154 } while (--height != 0); | |
155 } | |
156 | |
157 private: | |
158 typedef Sprite_D32_XferFilter INHERITED; | |
159 }; | |
160 | |
161 static void fillbuffer(SK_RESTRICT SkPMColor dst[], | |
162 const SK_RESTRICT SkPMColor16 src[], int count) { | |
163 SkASSERT(count > 0); | |
164 | |
165 do { | |
166 *dst++ = SkPixel4444ToPixel32(*src++); | |
167 } while (--count != 0); | |
168 } | |
169 | |
170 class Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter { | |
171 public: | |
172 Sprite_D32_S4444_XferFilter(const SkBitmap& source, const SkPaint& paint) | |
173 : Sprite_D32_XferFilter(source, paint) {} | |
174 | |
175 virtual void blitRect(int x, int y, int width, int height) { | |
176 SkASSERT(width > 0 && height > 0); | |
177 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
178 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
179 y - fTop); | |
180 unsigned dstRB = fDevice->rowBytes(); | |
181 unsigned srcRB = fSource->rowBytes(); | |
182 SK_RESTRICT SkPMColor* buffer = fBuffer; | |
183 SkColorFilter* colorFilter = fColorFilter; | |
184 SkXfermode* xfermode = fXfermode; | |
185 | |
186 do { | |
187 fillbuffer(buffer, src, width); | |
188 | |
189 if (NULL != colorFilter) { | |
190 colorFilter->filterSpan(buffer, width, buffer); | |
191 } | |
192 if (NULL != xfermode) { | |
193 xfermode->xfer32(dst, buffer, width, NULL); | |
194 } else { | |
195 for (int i = 0; i < width; i++) { | |
196 dst[i] = SkPMSrcOver(buffer[i], dst[i]); | |
197 } | |
198 } | |
199 | |
200 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
201 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
202 } while (--height != 0); | |
203 } | |
204 | |
205 private: | |
206 typedef Sprite_D32_XferFilter INHERITED; | |
207 }; | |
208 | |
209 /////////////////////////////////////////////////////////////////////////////// | |
210 | |
211 static void src_row(SK_RESTRICT SkPMColor dst[], | |
212 const SK_RESTRICT SkPMColor16 src[], int count) { | |
213 do { | |
214 *dst = SkPixel4444ToPixel32(*src); | |
215 src += 1; | |
216 dst += 1; | |
217 } while (--count != 0); | |
218 } | |
219 | |
220 class Sprite_D32_S4444_Opaque : public SkSpriteBlitter { | |
221 public: | |
222 Sprite_D32_S4444_Opaque(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
223 | |
224 virtual void blitRect(int x, int y, int width, int height) { | |
225 SkASSERT(width > 0 && height > 0); | |
226 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
227 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
228 y - fTop); | |
229 unsigned dstRB = fDevice->rowBytes(); | |
230 unsigned srcRB = fSource->rowBytes(); | |
231 | |
232 do { | |
233 src_row(dst, src, width); | |
234 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
235 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
236 } while (--height != 0); | |
237 } | |
238 }; | |
239 | |
240 static void srcover_row(SK_RESTRICT SkPMColor dst[], | |
241 const SK_RESTRICT SkPMColor16 src[], int count) { | |
242 do { | |
243 *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst); | |
244 src += 1; | |
245 dst += 1; | |
246 } while (--count != 0); | |
247 } | |
248 | |
249 class Sprite_D32_S4444 : public SkSpriteBlitter { | |
250 public: | |
251 Sprite_D32_S4444(const SkBitmap& source) : SkSpriteBlitter(source) {} | |
252 | |
253 virtual void blitRect(int x, int y, int width, int height) { | |
254 SkASSERT(width > 0 && height > 0); | |
255 SK_RESTRICT SkPMColor* dst = fDevice->getAddr32(x, y); | |
256 const SK_RESTRICT SkPMColor16* src = fSource->getAddr16(x - fLeft, | |
257 y - fTop); | |
258 unsigned dstRB = fDevice->rowBytes(); | |
259 unsigned srcRB = fSource->rowBytes(); | |
260 | |
261 do { | |
262 srcover_row(dst, src, width); | |
263 dst = (SK_RESTRICT SkPMColor*)((char*)dst + dstRB); | |
264 src = (const SK_RESTRICT SkPMColor16*)((const char*)src + srcRB); | |
265 } while (--height != 0); | |
266 } | |
267 }; | |
268 | |
269 /////////////////////////////////////////////////////////////////////////////// | |
270 | |
271 #include "SkTemplatesPriv.h" | |
272 | |
273 SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, | |
274 const SkPaint& paint, | |
275 void* storage, size_t storageSize) { | |
276 if (paint.getMaskFilter() != NULL || paint.getAlpha() != 0xFF) { | |
277 return NULL; | |
278 } | |
279 | |
280 SkXfermode* xfermode = paint.getXfermode(); | |
281 SkColorFilter* filter = paint.getColorFilter(); | |
282 SkSpriteBlitter* blitter = NULL; | |
283 | |
284 switch (source.getConfig()) { | |
285 case SkBitmap::kARGB_4444_Config: | |
286 if (xfermode || filter) { | |
287 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, | |
288 storage, storageSize, (source, paint)); | |
289 } else if (source.isOpaque()) { | |
290 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque, | |
291 storage, storageSize, (source)); | |
292 } else { | |
293 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444, | |
294 storage, storageSize, (source)); | |
295 } | |
296 break; | |
297 case SkBitmap::kARGB_8888_Config: | |
298 if (xfermode || filter) { | |
299 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, | |
300 storage, storageSize, (source, paint)); | |
301 } else if (source.isOpaque()) { | |
302 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32_Opaque, | |
303 storage, storageSize, (source)); | |
304 } else { | |
305 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_Opaque, | |
306 storage, storageSize, (source)); | |
307 } | |
308 break; | |
309 default: | |
310 break; | |
311 } | |
312 return blitter; | |
313 } | |
314 | |
OLD | NEW |