OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBlitMask.h" | 8 #include "SkBlitMask.h" |
9 #include "SkColor.h" | 9 #include "SkColor.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 | 105 |
106 do { | 106 do { |
107 proc(dstRow, srcRow, color, width, opaqueDst); | 107 proc(dstRow, srcRow, color, width, opaqueDst); |
108 dstRow = (SkPMColor*)((char*)dstRow + dstRB); | 108 dstRow = (SkPMColor*)((char*)dstRow + dstRB); |
109 srcRow = (const uint16_t*)((const char*)srcRow + maskRB); | 109 srcRow = (const uint16_t*)((const char*)srcRow + maskRB); |
110 } while (--height != 0); | 110 } while (--height != 0); |
111 } | 111 } |
112 | 112 |
113 /////////////////////////////////////////////////////////////////////////////// | 113 /////////////////////////////////////////////////////////////////////////////// |
114 | 114 |
115 static void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst, | |
116 const SkPMColor* SK_RESTRICT src, | |
117 SkColor color, int width) { | |
118 int srcR = SkColorGetR(color); | |
119 int srcG = SkColorGetG(color); | |
120 int srcB = SkColorGetB(color); | |
121 | |
122 for (int i = 0; i < width; i++) { | |
123 SkPMColor mask = src[i]; | |
124 if (0 == mask) { | |
125 continue; | |
126 } | |
127 | |
128 SkPMColor d = dst[i]; | |
129 | |
130 int maskR = SkGetPackedR32(mask); | |
131 int maskG = SkGetPackedG32(mask); | |
132 int maskB = SkGetPackedB32(mask); | |
133 | |
134 // Now upscale them to 0..256, so we can use SkAlphaBlend | |
135 maskR = SkAlpha255To256(maskR); | |
136 maskG = SkAlpha255To256(maskG); | |
137 maskB = SkAlpha255To256(maskB); | |
138 | |
139 int dstR = SkGetPackedR32(d); | |
140 int dstG = SkGetPackedG32(d); | |
141 int dstB = SkGetPackedB32(d); | |
142 | |
143 // LCD blitting is only supported if the dst is known/required | |
144 // to be opaque | |
145 dst[i] = SkPackARGB32(0xFF, | |
146 SkAlphaBlend(srcR, dstR, maskR), | |
147 SkAlphaBlend(srcG, dstG, maskG), | |
148 SkAlphaBlend(srcB, dstB, maskB)); | |
149 } | |
150 } | |
151 | |
152 static void blit_lcd32_row(SkPMColor* SK_RESTRICT dst, | |
153 const SkPMColor* SK_RESTRICT src, | |
154 SkColor color, int width) { | |
155 int srcA = SkColorGetA(color); | |
156 int srcR = SkColorGetR(color); | |
157 int srcG = SkColorGetG(color); | |
158 int srcB = SkColorGetB(color); | |
159 | |
160 srcA = SkAlpha255To256(srcA); | |
161 | |
162 for (int i = 0; i < width; i++) { | |
163 SkPMColor mask = src[i]; | |
164 if (0 == mask) { | |
165 continue; | |
166 } | |
167 | |
168 SkPMColor d = dst[i]; | |
169 | |
170 int maskR = SkGetPackedR32(mask); | |
171 int maskG = SkGetPackedG32(mask); | |
172 int maskB = SkGetPackedB32(mask); | |
173 | |
174 // Now upscale them to 0..256, so we can use SkAlphaBlend | |
175 maskR = SkAlpha255To256(maskR); | |
176 maskG = SkAlpha255To256(maskG); | |
177 maskB = SkAlpha255To256(maskB); | |
178 | |
179 maskR = maskR * srcA >> 8; | |
180 maskG = maskG * srcA >> 8; | |
181 maskB = maskB * srcA >> 8; | |
182 | |
183 int dstR = SkGetPackedR32(d); | |
184 int dstG = SkGetPackedG32(d); | |
185 int dstB = SkGetPackedB32(d); | |
186 | |
187 // LCD blitting is only supported if the dst is known/required | |
188 // to be opaque | |
189 dst[i] = SkPackARGB32(0xFF, | |
190 SkAlphaBlend(srcR, dstR, maskR), | |
191 SkAlphaBlend(srcG, dstG, maskG), | |
192 SkAlphaBlend(srcB, dstB, maskB)); | |
193 } | |
194 } | |
195 | |
196 static void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB, | |
197 const void* SK_RESTRICT mask, size_t maskRB, | |
198 SkColor color, int width, int height) { | |
199 SkASSERT(height > 0); | |
200 SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; | |
201 const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; | |
202 | |
203 do { | |
204 blit_lcd32_row(dstRow, srcRow, color, width); | |
205 dstRow = (SkPMColor*)((char*)dstRow + dstRB); | |
206 srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); | |
207 } while (--height != 0); | |
208 } | |
209 | |
210 static void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB, | |
211 const void* SK_RESTRICT mask, size_t maskRB, | |
212 SkColor color, int width, int height) { | |
213 SkASSERT(height > 0); | |
214 SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst; | |
215 const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask; | |
216 | |
217 do { | |
218 blit_lcd32_opaque_row(dstRow, srcRow, color, width); | |
219 dstRow = (SkPMColor*)((char*)dstRow + dstRB); | |
220 srcRow = (const SkPMColor*)((const char*)srcRow + maskRB); | |
221 } while (--height != 0); | |
222 } | |
223 | |
224 /////////////////////////////////////////////////////////////////////////////// | |
225 | |
226 static SkBlitMask::ColorProc D32_A8_Factory(SkColor color) { | 115 static SkBlitMask::ColorProc D32_A8_Factory(SkColor color) { |
227 if (SK_ColorBLACK == color) { | 116 if (SK_ColorBLACK == color) { |
228 return D32_A8_Black; | 117 return D32_A8_Black; |
229 } else if (0xFF == SkColorGetA(color)) { | 118 } else if (0xFF == SkColorGetA(color)) { |
230 return D32_A8_Opaque; | 119 return D32_A8_Opaque; |
231 } else { | 120 } else { |
232 return D32_A8_Color; | 121 return D32_A8_Color; |
233 } | 122 } |
234 } | 123 } |
235 | 124 |
236 static SkBlitMask::ColorProc D32_LCD32_Factory(SkColor color) { | |
237 return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend; | |
238 } | |
239 | |
240 SkBlitMask::ColorProc SkBlitMask::ColorFactory(SkColorType ct, | 125 SkBlitMask::ColorProc SkBlitMask::ColorFactory(SkColorType ct, |
241 SkMask::Format format, | 126 SkMask::Format format, |
242 SkColor color) { | 127 SkColor color) { |
243 ColorProc proc = PlatformColorProcs(ct, format, color); | 128 ColorProc proc = PlatformColorProcs(ct, format, color); |
244 if (proc) { | 129 if (proc) { |
245 return proc; | 130 return proc; |
246 } | 131 } |
247 | 132 |
248 switch (ct) { | 133 switch (ct) { |
249 case kN32_SkColorType: | 134 case kN32_SkColorType: |
250 switch (format) { | 135 switch (format) { |
251 case SkMask::kA8_Format: | 136 case SkMask::kA8_Format: |
252 return D32_A8_Factory(color); | 137 return D32_A8_Factory(color); |
253 case SkMask::kLCD16_Format: | 138 case SkMask::kLCD16_Format: |
254 return D32_LCD16_Proc; | 139 return D32_LCD16_Proc; |
255 case SkMask::kLCD32_Format: | |
256 return D32_LCD32_Factory(color); | |
257 default: | 140 default: |
258 break; | 141 break; |
259 } | 142 } |
260 break; | 143 break; |
261 default: | 144 default: |
262 break; | 145 break; |
263 } | 146 } |
264 return NULL; | 147 return NULL; |
265 } | 148 } |
266 | 149 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 | 352 |
470 // LCD blitting is only supported if the dst is known/required | 353 // LCD blitting is only supported if the dst is known/required |
471 // to be opaque | 354 // to be opaque |
472 dst[i] = SkPackARGB32(0xFF, | 355 dst[i] = SkPackARGB32(0xFF, |
473 SkBlend32(srcR, dstR, maskR), | 356 SkBlend32(srcR, dstR, maskR), |
474 SkBlend32(srcG, dstG, maskG), | 357 SkBlend32(srcG, dstG, maskG), |
475 SkBlend32(srcB, dstB, maskB)); | 358 SkBlend32(srcB, dstB, maskB)); |
476 } | 359 } |
477 } | 360 } |
478 | 361 |
479 static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst, | |
480 const SkPMColor* SK_RESTRICT mask, | |
481 const SkPMColor* SK_RESTRICT src, int count) { | |
482 for (int i = 0; i < count; ++i) { | |
483 SkPMColor m = mask[i]; | |
484 if (0 == m) { | |
485 continue; | |
486 } | |
487 | |
488 SkPMColor s = src[i]; | |
489 int srcA = SkGetPackedA32(s); | |
490 int srcR = SkGetPackedR32(s); | |
491 int srcG = SkGetPackedG32(s); | |
492 int srcB = SkGetPackedB32(s); | |
493 | |
494 srcA = SkAlpha255To256(srcA); | |
495 | |
496 SkPMColor d = dst[i]; | |
497 | |
498 int maskR = SkGetPackedR32(m); | |
499 int maskG = SkGetPackedG32(m); | |
500 int maskB = SkGetPackedB32(m); | |
501 | |
502 // Now upscale them to 0..256 | |
503 maskR = SkAlpha255To256(maskR); | |
504 maskG = SkAlpha255To256(maskG); | |
505 maskB = SkAlpha255To256(maskB); | |
506 | |
507 int dstR = SkGetPackedR32(d); | |
508 int dstG = SkGetPackedG32(d); | |
509 int dstB = SkGetPackedB32(d); | |
510 | |
511 // LCD blitting is only supported if the dst is known/required | |
512 // to be opaque | |
513 dst[i] = SkPackARGB32(0xFF, | |
514 src_alpha_blend(srcR, dstR, srcA, maskR), | |
515 src_alpha_blend(srcG, dstG, srcA, maskG), | |
516 src_alpha_blend(srcB, dstB, srcA, maskB)); | |
517 } | |
518 } | |
519 | |
520 static void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst, | |
521 const SkPMColor* SK_RESTRICT mask, | |
522 const SkPMColor* SK_RESTRICT src, int count) { | |
523 for (int i = 0; i < count; ++i) { | |
524 SkPMColor m = mask[i]; | |
525 if (0 == m) { | |
526 continue; | |
527 } | |
528 | |
529 SkPMColor s = src[i]; | |
530 SkPMColor d = dst[i]; | |
531 | |
532 int maskR = SkGetPackedR32(m); | |
533 int maskG = SkGetPackedG32(m); | |
534 int maskB = SkGetPackedB32(m); | |
535 | |
536 int srcR = SkGetPackedR32(s); | |
537 int srcG = SkGetPackedG32(s); | |
538 int srcB = SkGetPackedB32(s); | |
539 | |
540 int dstR = SkGetPackedR32(d); | |
541 int dstG = SkGetPackedG32(d); | |
542 int dstB = SkGetPackedB32(d); | |
543 | |
544 // Now upscale them to 0..256, so we can use SkAlphaBlend | |
545 maskR = SkAlpha255To256(maskR); | |
546 maskG = SkAlpha255To256(maskG); | |
547 maskB = SkAlpha255To256(maskB); | |
548 | |
549 // LCD blitting is only supported if the dst is known/required | |
550 // to be opaque | |
551 dst[i] = SkPackARGB32(0xFF, | |
552 SkAlphaBlend(srcR, dstR, maskR), | |
553 SkAlphaBlend(srcG, dstG, maskG), | |
554 SkAlphaBlend(srcB, dstB, maskB)); | |
555 } | |
556 } | |
557 | |
558 SkBlitMask::RowProc SkBlitMask::RowFactory(SkColorType ct, | 362 SkBlitMask::RowProc SkBlitMask::RowFactory(SkColorType ct, |
559 SkMask::Format format, | 363 SkMask::Format format, |
560 RowFlags flags) { | 364 RowFlags flags) { |
561 // make this opt-in until chrome can rebaseline | 365 // make this opt-in until chrome can rebaseline |
562 RowProc proc = PlatformRowProcs(ct, format, flags); | 366 RowProc proc = PlatformRowProcs(ct, format, flags); |
563 if (proc) { | 367 if (proc) { |
564 return proc; | 368 return proc; |
565 } | 369 } |
566 | 370 |
567 static const RowProc gProcs[] = { | 371 static const RowProc gProcs[] = { |
568 // need X coordinate to handle BW | 372 // need X coordinate to handle BW |
569 false ? (RowProc)BW_RowProc_Blend : NULL, // suppress unused warning | 373 false ? (RowProc)BW_RowProc_Blend : NULL, // suppress unused warning |
570 false ? (RowProc)BW_RowProc_Opaque : NULL, // suppress unused warning | 374 false ? (RowProc)BW_RowProc_Opaque : NULL, // suppress unused warning |
571 (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, | 375 (RowProc)A8_RowProc_Blend, (RowProc)A8_RowProc_Opaque, |
572 (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, | 376 (RowProc)LCD16_RowProc_Blend, (RowProc)LCD16_RowProc_Opaque, |
573 (RowProc)LCD32_RowProc_Blend, (RowProc)LCD32_RowProc_Opaque, | |
574 }; | 377 }; |
575 | 378 |
576 int index; | 379 int index; |
577 switch (ct) { | 380 switch (ct) { |
578 case kN32_SkColorType: | 381 case kN32_SkColorType: |
579 switch (format) { | 382 switch (format) { |
580 case SkMask::kBW_Format: index = 0; break; | 383 case SkMask::kBW_Format: index = 0; break; |
581 case SkMask::kA8_Format: index = 2; break; | 384 case SkMask::kA8_Format: index = 2; break; |
582 case SkMask::kLCD16_Format: index = 4; break; | 385 case SkMask::kLCD16_Format: index = 4; break; |
583 case SkMask::kLCD32_Format: index = 6; break; | |
584 default: | 386 default: |
585 return NULL; | 387 return NULL; |
586 } | 388 } |
587 if (flags & kSrcIsOpaque_RowFlag) { | 389 if (flags & kSrcIsOpaque_RowFlag) { |
588 index |= 1; | 390 index |= 1; |
589 } | 391 } |
590 SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs)); | 392 SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs)); |
591 return gProcs[index]; | 393 return gProcs[index]; |
592 default: | 394 default: |
593 break; | 395 break; |
594 } | 396 } |
595 return NULL; | 397 return NULL; |
596 } | 398 } |
OLD | NEW |