1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkBlitRow.h" 11 #include "SkCoreBlitters.h" 12 #include "SkColorPriv.h" 13 #include "SkDither.h" 14 #include "SkShader.h" 15 #include "SkTemplatesPriv.h" 16 #include "SkUtils.h" 17 #include "SkXfermode.h" 18 19 #if defined(__ARM_HAVE_NEON) && defined(SK_CPU_LENDIAN) 20 #define SK_USE_NEON 21 #include <arm_neon.h> 22 #else 23 // if we don't have neon, then our black blitter is worth the extra code 24 #define USE_BLACK_BLITTER 25 #endif 26 27 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, 28 int count) { 29 if (count > 0) { 30 // see if we need to write one short before we can cast to an 4byte ptr 31 // (we do this subtract rather than (unsigned)dst so we don't get warnings 32 // on 64bit machines) 33 if (((char*)dst - (char*)0) & 2) { 34 *dst++ = value; 35 count -= 1; 36 SkTSwap(value, other); 37 } 38 39 // fast way to set [value,other] pairs 40 #ifdef SK_CPU_BENDIAN 41 sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1); 42 #else 43 sk_memset32((uint32_t*)dst, (other << 16) | value, count >> 1); 44 #endif 45 46 if (count & 1) { 47 dst[count - 1] = value; 48 } 49 } 50 } 51 52 /////////////////////////////////////////////////////////////////////////////// 53 54 class SkRGB16_Blitter : public SkRasterBlitter { 55 public: 56 SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint); 57 virtual void blitH(int x, int y, int width); 58 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 59 const int16_t* runs); 60 virtual void blitV(int x, int y, int height, SkAlpha alpha); 61 virtual void blitRect(int x, int y, int width, int height); 62 virtual void blitMask(const SkMask&, 63 const SkIRect&); 64 virtual const SkBitmap* justAnOpaqueColor(uint32_t*); 65 66 protected: 67 SkPMColor fSrcColor32; 68 uint32_t fExpandedRaw16; 69 unsigned fScale; 70 uint16_t fColor16; // already scaled by fScale 71 uint16_t fRawColor16; // unscaled 72 uint16_t fRawDither16; // unscaled 73 SkBool8 fDoDither; 74 75 // illegal 76 SkRGB16_Blitter& operator=(const SkRGB16_Blitter&); 77 78 typedef SkRasterBlitter INHERITED; 79 }; 80 81 class SkRGB16_Opaque_Blitter : public SkRGB16_Blitter { 82 public: 83 SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint); 84 virtual void blitH(int x, int y, int width); 85 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 86 const int16_t* runs); 87 virtual void blitV(int x, int y, int height, SkAlpha alpha); 88 virtual void blitRect(int x, int y, int width, int height); 89 virtual void blitMask(const SkMask&, 90 const SkIRect&); 91 92 private: 93 typedef SkRGB16_Blitter INHERITED; 94 }; 95 96 #ifdef USE_BLACK_BLITTER 97 class SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter { 98 public: 99 SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint); 100 virtual void blitMask(const SkMask&, const SkIRect&); 101 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 102 const int16_t* runs); 103 104 private: 105 typedef SkRGB16_Opaque_Blitter INHERITED; 106 }; 107 #endif 108 109 class SkRGB16_Shader_Blitter : public SkShaderBlitter { 110 public: 111 SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint); 112 virtual ~SkRGB16_Shader_Blitter(); 113 virtual void blitH(int x, int y, int width); 114 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 115 const int16_t* runs); 116 virtual void blitRect(int x, int y, int width, int height); 117 118 protected: 119 SkPMColor* fBuffer; 120 SkBlitRow::Proc fOpaqueProc; 121 SkBlitRow::Proc fAlphaProc; 122 123 private: 124 // illegal 125 SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&); 126 127 typedef SkShaderBlitter INHERITED; 128 }; 129 130 // used only if the shader can perform shadSpan16 131 class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter { 132 public: 133 SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint); 134 virtual void blitH(int x, int y, int width); 135 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 136 const int16_t* runs); 137 virtual void blitRect(int x, int y, int width, int height); 138 139 private: 140 typedef SkRGB16_Shader_Blitter INHERITED; 141 }; 142 143 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { 144 public: 145 SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint); 146 virtual ~SkRGB16_Shader_Xfermode_Blitter(); 147 virtual void blitH(int x, int y, int width); 148 virtual void blitAntiH(int x, int y, const SkAlpha* antialias, 149 const int16_t* runs); 150 151 private: 152 SkXfermode* fXfermode; 153 SkPMColor* fBuffer; 154 uint8_t* fAAExpand; 155 156 // illegal 157 SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&); 158 159 typedef SkShaderBlitter INHERITED; 160 }; 161 162 /////////////////////////////////////////////////////////////////////////////// 163 #ifdef USE_BLACK_BLITTER 164 SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint) 165 : INHERITED(device, paint) { 166 SkASSERT(paint.getShader() == NULL); 167 SkASSERT(paint.getColorFilter() == NULL); 168 SkASSERT(paint.getXfermode() == NULL); 169 SkASSERT(paint.getColor() == SK_ColorBLACK); 170 } 171 172 #if 1 173 #define black_8_pixels(mask, dst) \ 174 do { \ 175 if (mask & 0x80) dst[0] = 0; \ 176 if (mask & 0x40) dst[1] = 0; \ 177 if (mask & 0x20) dst[2] = 0; \ 178 if (mask & 0x10) dst[3] = 0; \ 179 if (mask & 0x08) dst[4] = 0; \ 180 if (mask & 0x04) dst[5] = 0; \ 181 if (mask & 0x02) dst[6] = 0; \ 182 if (mask & 0x01) dst[7] = 0; \ 183 } while (0) 184 #else 185 static inline black_8_pixels(U8CPU mask, uint16_t dst[]) 186 { 187 if (mask & 0x80) dst[0] = 0; 188 if (mask & 0x40) dst[1] = 0; 189 if (mask & 0x20) dst[2] = 0; 190 if (mask & 0x10) dst[3] = 0; 191 if (mask & 0x08) dst[4] = 0; 192 if (mask & 0x04) dst[5] = 0; 193 if (mask & 0x02) dst[6] = 0; 194 if (mask & 0x01) dst[7] = 0; 195 } 196 #endif 197 198 #define SK_BLITBWMASK_NAME SkRGB16_Black_BlitBW 199 #define SK_BLITBWMASK_ARGS 200 #define SK_BLITBWMASK_BLIT8(mask, dst) black_8_pixels(mask, dst) 201 #define SK_BLITBWMASK_GETADDR getAddr16 202 #define SK_BLITBWMASK_DEVTYPE uint16_t 203 #include "SkBlitBWMaskTemplate.h" 204 205 void SkRGB16_Black_Blitter::blitMask(const SkMask& mask, 206 const SkIRect& clip) { 207 if (mask.fFormat == SkMask::kBW_Format) { 208 SkRGB16_Black_BlitBW(fDevice, mask, clip); 209 } else { 210 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 211 const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 212 unsigned width = clip.width(); 213 unsigned height = clip.height(); 214 unsigned deviceRB = fDevice.rowBytes() - (width << 1); 215 unsigned maskRB = mask.fRowBytes - width; 216 217 SkASSERT((int)height > 0); 218 SkASSERT((int)width > 0); 219 SkASSERT((int)deviceRB >= 0); 220 SkASSERT((int)maskRB >= 0); 221 222 do { 223 unsigned w = width; 224 do { 225 unsigned aa = *alpha++; 226 *device = SkAlphaMulRGB16(*device, SkAlpha255To256(255 - aa)); 227 device += 1; 228 } while (--w != 0); 229 device = (uint16_t*)((char*)device + deviceRB); 230 alpha += maskRB; 231 } while (--height != 0); 232 } 233 } 234 235 void SkRGB16_Black_Blitter::blitAntiH(int x, int y, 236 const SkAlpha* SK_RESTRICT antialias, 237 const int16_t* SK_RESTRICT runs) { 238 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 239 240 for (;;) { 241 int count = runs[0]; 242 SkASSERT(count >= 0); 243 if (count <= 0) { 244 return; 245 } 246 runs += count; 247 248 unsigned aa = antialias[0]; 249 antialias += count; 250 if (aa) { 251 if (aa == 255) { 252 memset(device, 0, count << 1); 253 } else { 254 aa = SkAlpha255To256(255 - aa); 255 do { 256 *device = SkAlphaMulRGB16(*device, aa); 257 device += 1; 258 } while (--count != 0); 259 continue; 260 } 261 } 262 device += count; 263 } 264 } 265 #endif 266 267 /////////////////////////////////////////////////////////////////////////////// 268 /////////////////////////////////////////////////////////////////////////////// 269 270 SkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkBitmap& device, 271 const SkPaint& paint) 272 : INHERITED(device, paint) {} 273 274 void SkRGB16_Opaque_Blitter::blitH(int x, int y, int width) { 275 SkASSERT(width > 0); 276 SkASSERT(x + width <= fDevice.width()); 277 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 278 uint16_t srcColor = fColor16; 279 280 SkASSERT(fRawColor16 == srcColor); 281 if (fDoDither) { 282 uint16_t ditherColor = fRawDither16; 283 if ((x ^ y) & 1) { 284 SkTSwap(ditherColor, srcColor); 285 } 286 sk_dither_memset16(device, srcColor, ditherColor, width); 287 } else { 288 sk_memset16(device, srcColor, width); 289 } 290 } 291 292 // return 1 or 0 from a bool 293 static inline int Bool2Int(int value) { 294 return !!value; 295 } 296 297 void SkRGB16_Opaque_Blitter::blitAntiH(int x, int y, 298 const SkAlpha* SK_RESTRICT antialias, 299 const int16_t* SK_RESTRICT runs) { 300 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 301 uint16_t srcColor = fRawColor16; 302 uint32_t srcExpanded = fExpandedRaw16; 303 int ditherInt = Bool2Int(fDoDither); 304 uint16_t ditherColor = fRawDither16; 305 // if we have no dithering, this will always fail 306 if ((x ^ y) & ditherInt) { 307 SkTSwap(ditherColor, srcColor); 308 } 309 for (;;) { 310 int count = runs[0]; 311 SkASSERT(count >= 0); 312 if (count <= 0) { 313 return; 314 } 315 runs += count; 316 317 unsigned aa = antialias[0]; 318 antialias += count; 319 if (aa) { 320 if (aa == 255) { 321 if (ditherInt) { 322 sk_dither_memset16(device, srcColor, 323 ditherColor, count); 324 } else { 325 sk_memset16(device, srcColor, count); 326 } 327 } else { 328 // TODO: respect fDoDither 329 unsigned scale5 = SkAlpha255To256(aa) >> 3; 330 uint32_t src32 = srcExpanded * scale5; 331 scale5 = 32 - scale5; // now we can use it on the device 332 int n = count; 333 do { 334 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 335 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 336 } while (--n != 0); 337 goto DONE; 338 } 339 } 340 device += count; 341 342 DONE: 343 // if we have no dithering, this will always fail 344 if (count & ditherInt) { 345 SkTSwap(ditherColor, srcColor); 346 } 347 } 348 } 349 350 #define solid_8_pixels(mask, dst, color) \ 351 do { \ 352 if (mask & 0x80) dst[0] = color; \ 353 if (mask & 0x40) dst[1] = color; \ 354 if (mask & 0x20) dst[2] = color; \ 355 if (mask & 0x10) dst[3] = color; \ 356 if (mask & 0x08) dst[4] = color; \ 357 if (mask & 0x04) dst[5] = color; \ 358 if (mask & 0x02) dst[6] = color; \ 359 if (mask & 0x01) dst[7] = color; \ 360 } while (0) 361 362 #define SK_BLITBWMASK_NAME SkRGB16_BlitBW 363 #define SK_BLITBWMASK_ARGS , uint16_t color 364 #define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst, color) 365 #define SK_BLITBWMASK_GETADDR getAddr16 366 #define SK_BLITBWMASK_DEVTYPE uint16_t 367 #include "SkBlitBWMaskTemplate.h" 368 369 static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) { 370 return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5)); 371 } 372 373 void SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask, 374 const SkIRect& clip) { 375 if (mask.fFormat == SkMask::kBW_Format) { 376 SkRGB16_BlitBW(fDevice, mask, clip, fColor16); 377 return; 378 } 379 380 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 381 const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 382 int width = clip.width(); 383 int height = clip.height(); 384 unsigned deviceRB = fDevice.rowBytes() - (width << 1); 385 unsigned maskRB = mask.fRowBytes - width; 386 uint32_t expanded32 = fExpandedRaw16; 387 388 #ifdef SK_USE_NEON 389 #define UNROLL 8 390 do { 391 int w = width; 392 if (w >= UNROLL) { 393 uint32x4_t color; /* can use same one */ 394 uint32x4_t dev_lo, dev_hi; 395 uint32x4_t t1, t2; 396 uint32x4_t wn1, wn2; 397 uint16x4_t odev_lo, odev_hi; 398 uint16x4_t alpha_lo, alpha_hi; 399 uint16x8_t alpha_full; 400 401 color = vdupq_n_u32(expanded32); 402 403 do { 404 /* alpha is 8x8, widen and split to get pair of 16x4's */ 405 alpha_full = vmovl_u8(vld1_u8(alpha)); 406 alpha_full = vaddq_u16(alpha_full, vshrq_n_u16(alpha_full,7)); 407 alpha_full = vshrq_n_u16(alpha_full, 3); 408 alpha_lo = vget_low_u16(alpha_full); 409 alpha_hi = vget_high_u16(alpha_full); 410 411 dev_lo = vmovl_u16(vld1_u16(device)); 412 dev_hi = vmovl_u16(vld1_u16(device+4)); 413 414 /* unpack in 32 bits */ 415 dev_lo = vorrq_u32( 416 vandq_u32(dev_lo, vdupq_n_u32(0x0000F81F)), 417 vshlq_n_u32(vandq_u32(dev_lo, 418 vdupq_n_u32(0x000007E0)), 419 16) 420 ); 421 dev_hi = vorrq_u32( 422 vandq_u32(dev_hi, vdupq_n_u32(0x0000F81F)), 423 vshlq_n_u32(vandq_u32(dev_hi, 424 vdupq_n_u32(0x000007E0)), 425 16) 426 ); 427 428 /* blend the two */ 429 t1 = vmulq_u32(vsubq_u32(color, dev_lo), vmovl_u16(alpha_lo)); 430 t1 = vshrq_n_u32(t1, 5); 431 dev_lo = vaddq_u32(dev_lo, t1); 432 433 t1 = vmulq_u32(vsubq_u32(color, dev_hi), vmovl_u16(alpha_hi)); 434 t1 = vshrq_n_u32(t1, 5); 435 dev_hi = vaddq_u32(dev_hi, t1); 436 437 /* re-compact and store */ 438 wn1 = vandq_u32(dev_lo, vdupq_n_u32(0x0000F81F)), 439 wn2 = vshrq_n_u32(dev_lo, 16); 440 wn2 = vandq_u32(wn2, vdupq_n_u32(0x000007E0)); 441 odev_lo = vmovn_u32(vorrq_u32(wn1, wn2)); 442 443 wn1 = vandq_u32(dev_hi, vdupq_n_u32(0x0000F81F)), 444 wn2 = vshrq_n_u32(dev_hi, 16); 445 wn2 = vandq_u32(wn2, vdupq_n_u32(0x000007E0)); 446 odev_hi = vmovn_u32(vorrq_u32(wn1, wn2)); 447 448 vst1_u16(device, odev_lo); 449 vst1_u16(device+4, odev_hi); 450 451 device += UNROLL; 452 alpha += UNROLL; 453 w -= UNROLL; 454 } while (w >= UNROLL); 455 } 456 457 /* residuals (which is everything if we have no neon) */ 458 while (w > 0) { 459 *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 460 SkAlpha255To256(*alpha++) >> 3); 461 device += 1; 462 --w; 463 } 464 device = (uint16_t*)((char*)device + deviceRB); 465 alpha += maskRB; 466 } while (--height != 0); 467 #undef UNROLL 468 #else // non-neon code 469 do { 470 int w = width; 471 do { 472 *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 473 SkAlpha255To256(*alpha++) >> 3); 474 device += 1; 475 } while (--w != 0); 476 device = (uint16_t*)((char*)device + deviceRB); 477 alpha += maskRB; 478 } while (--height != 0); 479 #endif 480 } 481 482 void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 483 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 484 unsigned deviceRB = fDevice.rowBytes(); 485 486 // TODO: respect fDoDither 487 unsigned scale5 = SkAlpha255To256(alpha) >> 3; 488 uint32_t src32 = fExpandedRaw16 * scale5; 489 scale5 = 32 - scale5; 490 do { 491 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 492 *device = SkCompact_rgb_16((src32 + dst32) >> 5); 493 device = (uint16_t*)((char*)device + deviceRB); 494 } while (--height != 0); 495 } 496 497 void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { 498 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 499 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 500 unsigned deviceRB = fDevice.rowBytes(); 501 uint16_t color16 = fColor16; 502 503 if (fDoDither) { 504 uint16_t ditherColor = fRawDither16; 505 if ((x ^ y) & 1) { 506 SkTSwap(ditherColor, color16); 507 } 508 while (--height >= 0) { 509 sk_dither_memset16(device, color16, ditherColor, width); 510 SkTSwap(ditherColor, color16); 511 device = (uint16_t*)((char*)device + deviceRB); 512 } 513 } else { // no dither 514 while (--height >= 0) { 515 sk_memset16(device, color16, width); 516 device = (uint16_t*)((char*)device + deviceRB); 517 } 518 } 519 } 520 521 /////////////////////////////////////////////////////////////////////////////// 522 523 SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) 524 : INHERITED(device) { 525 SkColor color = paint.getColor(); 526 527 fSrcColor32 = SkPreMultiplyColor(color); 528 fScale = SkAlpha255To256(SkColorGetA(color)); 529 530 int r = SkColorGetR(color); 531 int g = SkColorGetG(color); 532 int b = SkColorGetB(color); 533 534 fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b); 535 // if we're dithered, use fRawDither16 to hold that. 536 if ((fDoDither = paint.isDither()) != false) { 537 fRawDither16 = SkDitherPack888ToRGB16(r, g, b); 538 } 539 540 fExpandedRaw16 = SkExpand_rgb_16(fRawColor16); 541 542 fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), 543 SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), 544 SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); 545 } 546 547 const SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { 548 if (!fDoDither && 256 == fScale) { 549 *value = fRawColor16; 550 return &fDevice; 551 } 552 return NULL; 553 } 554 555 static uint32_t pmcolor_to_expand16(SkPMColor c) { 556 unsigned r = SkGetPackedR32(c); 557 unsigned g = SkGetPackedG32(c); 558 unsigned b = SkGetPackedB32(c); 559 return (g << 24) | (r << 13) | (b << 2); 560 } 561 562 static inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) { 563 SkASSERT(count > 0); 564 uint32_t src_expand = pmcolor_to_expand16(src); 565 unsigned scale = SkAlpha255To256(0xFF - SkGetPackedA32(src)) >> 3; 566 do { 567 uint32_t dst_expand = SkExpand_rgb_16(*dst) * scale; 568 *dst = SkCompact_rgb_16((src_expand + dst_expand) >> 5); 569 dst += 1; 570 } while (--count != 0); 571 } 572 573 void SkRGB16_Blitter::blitH(int x, int y, int width) { 574 SkASSERT(width > 0); 575 SkASSERT(x + width <= fDevice.width()); 576 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 577 578 // TODO: respect fDoDither 579 blend32_16_row(fSrcColor32, device, width); 580 } 581 582 void SkRGB16_Blitter::blitAntiH(int x, int y, 583 const SkAlpha* SK_RESTRICT antialias, 584 const int16_t* SK_RESTRICT runs) { 585 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 586 uint32_t srcExpanded = fExpandedRaw16; 587 unsigned scale = fScale; 588 589 // TODO: respect fDoDither 590 for (;;) { 591 int count = runs[0]; 592 SkASSERT(count >= 0); 593 if (count <= 0) { 594 return; 595 } 596 runs += count; 597 598 unsigned aa = antialias[0]; 599 antialias += count; 600 if (aa) { 601 unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); 602 uint32_t src32 = srcExpanded * scale5; 603 scale5 = 32 - scale5; 604 do { 605 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 606 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 607 } while (--count != 0); 608 continue; 609 } 610 device += count; 611 } 612 } 613 614 static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, 615 U16CPU srcColor) { 616 if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); 617 if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale); 618 if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale); 619 if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale); 620 if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale); 621 if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale); 622 if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale); 623 if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale); 624 } 625 626 #define SK_BLITBWMASK_NAME SkRGB16_BlendBW 627 #define SK_BLITBWMASK_ARGS , unsigned dst_scale, U16CPU src_color 628 #define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, dst_scale, src_color) 629 #define SK_BLITBWMASK_GETADDR getAddr16 630 #define SK_BLITBWMASK_DEVTYPE uint16_t 631 #include "SkBlitBWMaskTemplate.h" 632 633 void SkRGB16_Blitter::blitMask(const SkMask& mask, 634 const SkIRect& clip) { 635 if (mask.fFormat == SkMask::kBW_Format) { 636 SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); 637 return; 638 } 639 640 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 641 const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 642 int width = clip.width(); 643 int height = clip.height(); 644 unsigned deviceRB = fDevice.rowBytes() - (width << 1); 645 unsigned maskRB = mask.fRowBytes - width; 646 uint32_t color32 = fExpandedRaw16; 647 648 unsigned scale256 = fScale; 649 do { 650 int w = width; 651 do { 652 unsigned aa = *alpha++; 653 unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); 654 uint32_t src32 = color32 * scale; 655 uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); 656 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 657 } while (--w != 0); 658 device = (uint16_t*)((char*)device + deviceRB); 659 alpha += maskRB; 660 } while (--height != 0); 661 } 662 663 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 664 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 665 unsigned deviceRB = fDevice.rowBytes(); 666 667 // TODO: respect fDoDither 668 unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); 669 uint32_t src32 = fExpandedRaw16 * scale5; 670 scale5 = 32 - scale5; 671 do { 672 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 673 *device = SkCompact_rgb_16((src32 + dst32) >> 5); 674 device = (uint16_t*)((char*)device + deviceRB); 675 } while (--height != 0); 676 } 677 678 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { 679 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 680 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 681 unsigned deviceRB = fDevice.rowBytes(); 682 SkPMColor src32 = fSrcColor32; 683 684 while (--height >= 0) { 685 blend32_16_row(src32, device, width); 686 device = (uint16_t*)((char*)device + deviceRB); 687 } 688 } 689 690 /////////////////////////////////////////////////////////////////////////////// 691 692 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, 693 const SkPaint& paint) 694 : SkRGB16_Shader_Blitter(device, paint) { 695 SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); 696 } 697 698 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { 699 SkASSERT(x + width <= fDevice.width()); 700 701 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 702 SkShader* shader = fShader; 703 704 int alpha = shader->getSpan16Alpha(); 705 if (0xFF == alpha) { 706 shader->shadeSpan16(x, y, device, width); 707 } else { 708 uint16_t* span16 = (uint16_t*)fBuffer; 709 shader->shadeSpan16(x, y, span16, width); 710 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); 711 } 712 } 713 714 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { 715 SkShader* shader = fShader; 716 uint16_t* dst = fDevice.getAddr16(x, y); 717 size_t dstRB = fDevice.rowBytes(); 718 int alpha = shader->getSpan16Alpha(); 719 720 if (0xFF == alpha) { 721 if (fShaderFlags & SkShader::kConstInY16_Flag) { 722 // have the shader blit directly into the device the first time 723 shader->shadeSpan16(x, y, dst, width); 724 // and now just memcpy that line on the subsequent lines 725 if (--height > 0) { 726 const uint16_t* orig = dst; 727 do { 728 dst = (uint16_t*)((char*)dst + dstRB); 729 memcpy(dst, orig, width << 1); 730 } while (--height); 731 } 732 } else { // need to call shadeSpan16 for every line 733 do { 734 shader->shadeSpan16(x, y, dst, width); 735 y += 1; 736 dst = (uint16_t*)((char*)dst + dstRB); 737 } while (--height); 738 } 739 } else { 740 int scale = SkAlpha255To256(alpha); 741 uint16_t* span16 = (uint16_t*)fBuffer; 742 if (fShaderFlags & SkShader::kConstInY16_Flag) { 743 shader->shadeSpan16(x, y, span16, width); 744 do { 745 SkBlendRGB16(span16, dst, scale, width); 746 dst = (uint16_t*)((char*)dst + dstRB); 747 } while (--height); 748 } else { 749 do { 750 shader->shadeSpan16(x, y, span16, width); 751 SkBlendRGB16(span16, dst, scale, width); 752 y += 1; 753 dst = (uint16_t*)((char*)dst + dstRB); 754 } while (--height); 755 } 756 } 757 } 758 759 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, 760 const SkAlpha* SK_RESTRICT antialias, 761 const int16_t* SK_RESTRICT runs) { 762 SkShader* shader = fShader; 763 SkPMColor* SK_RESTRICT span = fBuffer; 764 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 765 766 int alpha = shader->getSpan16Alpha(); 767 uint16_t* span16 = (uint16_t*)span; 768 769 if (0xFF == alpha) { 770 for (;;) { 771 int count = *runs; 772 if (count <= 0) { 773 break; 774 } 775 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 776 777 int aa = *antialias; 778 if (aa == 255) { 779 // go direct to the device! 780 shader->shadeSpan16(x, y, device, count); 781 } else if (aa) { 782 shader->shadeSpan16(x, y, span16, count); 783 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 784 } 785 device += count; 786 runs += count; 787 antialias += count; 788 x += count; 789 } 790 } else { // span alpha is < 255 791 alpha = SkAlpha255To256(alpha); 792 for (;;) { 793 int count = *runs; 794 if (count <= 0) { 795 break; 796 } 797 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 798 799 int aa = SkAlphaMul(*antialias, alpha); 800 if (aa) { 801 shader->shadeSpan16(x, y, span16, count); 802 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 803 } 804 805 device += count; 806 runs += count; 807 antialias += count; 808 x += count; 809 } 810 } 811 } 812 813 /////////////////////////////////////////////////////////////////////////////// 814 815 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, 816 const SkPaint& paint) 817 : INHERITED(device, paint) { 818 SkASSERT(paint.getXfermode() == NULL); 819 820 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); 821 822 // compute SkBlitRow::Procs 823 unsigned flags = 0; 824 825 uint32_t shaderFlags = fShaderFlags; 826 // shaders take care of global alpha, so we never set it in SkBlitRow 827 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { 828 flags |= SkBlitRow::kSrcPixelAlpha_Flag; 829 } 830 // don't dither if the shader is really 16bit 831 if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) { 832 flags |= SkBlitRow::kDither_Flag; 833 } 834 // used when we know our global alpha is 0xFF 835 fOpaqueProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); 836 // used when we know our global alpha is < 0xFF 837 fAlphaProc = SkBlitRow::Factory(flags | SkBlitRow::kGlobalAlpha_Flag, 838 SkBitmap::kRGB_565_Config); 839 } 840 841 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { 842 sk_free(fBuffer); 843 } 844 845 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { 846 SkASSERT(x + width <= fDevice.width()); 847 848 fShader->shadeSpan(x, y, fBuffer, width); 849 // shaders take care of global alpha, so we pass 0xFF (should be ignored) 850 fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); 851 } 852 853 void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { 854 SkShader* shader = fShader; 855 SkBlitRow::Proc proc = fOpaqueProc; 856 SkPMColor* buffer = fBuffer; 857 uint16_t* dst = fDevice.getAddr16(x, y); 858 size_t dstRB = fDevice.rowBytes(); 859 860 if (fShaderFlags & SkShader::kConstInY32_Flag) { 861 shader->shadeSpan(x, y, buffer, width); 862 do { 863 proc(dst, buffer, width, 0xFF, x, y); 864 y += 1; 865 dst = (uint16_t*)((char*)dst + dstRB); 866 } while (--height); 867 } else { 868 do { 869 shader->shadeSpan(x, y, buffer, width); 870 proc(dst, buffer, width, 0xFF, x, y); 871 y += 1; 872 dst = (uint16_t*)((char*)dst + dstRB); 873 } while (--height); 874 } 875 } 876 877 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { 878 int count = 0; 879 for (;;) { 880 int n = *runs; 881 if (n == 0 || *aa == 0) { 882 break; 883 } 884 runs += n; 885 aa += n; 886 count += n; 887 } 888 return count; 889 } 890 891 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, 892 const SkAlpha* SK_RESTRICT antialias, 893 const int16_t* SK_RESTRICT runs) { 894 SkShader* shader = fShader; 895 SkPMColor* SK_RESTRICT span = fBuffer; 896 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 897 898 for (;;) { 899 int count = *runs; 900 if (count <= 0) { 901 break; 902 } 903 int aa = *antialias; 904 if (0 == aa) { 905 device += count; 906 runs += count; 907 antialias += count; 908 x += count; 909 continue; 910 } 911 912 int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); 913 914 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 915 shader->shadeSpan(x, y, span, nonZeroCount); 916 917 SkPMColor* localSpan = span; 918 for (;;) { 919 SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; 920 proc(device, localSpan, count, aa, x, y); 921 922 x += count; 923 device += count; 924 runs += count; 925 antialias += count; 926 nonZeroCount -= count; 927 if (nonZeroCount == 0) { 928 break; 929 } 930 localSpan += count; 931 SkASSERT(nonZeroCount > 0); 932 count = *runs; 933 SkASSERT(count > 0); 934 aa = *antialias; 935 } 936 } 937 } 938 939 /////////////////////////////////////////////////////////////////////// 940 941 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( 942 const SkBitmap& device, const SkPaint& paint) 943 : INHERITED(device, paint) { 944 fXfermode = paint.getXfermode(); 945 SkASSERT(fXfermode); 946 fXfermode->ref(); 947 948 int width = device.width(); 949 fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor)); 950 fAAExpand = (uint8_t*)(fBuffer + width); 951 } 952 953 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { 954 fXfermode->unref(); 955 sk_free(fBuffer); 956 } 957 958 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { 959 SkASSERT(x + width <= fDevice.width()); 960 961 uint16_t* device = fDevice.getAddr16(x, y); 962 SkPMColor* span = fBuffer; 963 964 fShader->shadeSpan(x, y, span, width); 965 fXfermode->xfer16(device, span, width, NULL); 966 } 967 968 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, 969 const SkAlpha* SK_RESTRICT antialias, 970 const int16_t* SK_RESTRICT runs) { 971 SkShader* shader = fShader; 972 SkXfermode* mode = fXfermode; 973 SkPMColor* SK_RESTRICT span = fBuffer; 974 uint8_t* SK_RESTRICT aaExpand = fAAExpand; 975 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 976 977 for (;;) { 978 int count = *runs; 979 if (count <= 0) { 980 break; 981 } 982 int aa = *antialias; 983 if (0 == aa) { 984 device += count; 985 runs += count; 986 antialias += count; 987 x += count; 988 continue; 989 } 990 991 int nonZeroCount = count + count_nonzero_span(runs + count, 992 antialias + count); 993 994 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 995 shader->shadeSpan(x, y, span, nonZeroCount); 996 997 x += nonZeroCount; 998 SkPMColor* localSpan = span; 999 for (;;) { 1000 if (aa == 0xFF) { 1001 mode->xfer16(device, localSpan, count, NULL); 1002 } else { 1003 SkASSERT(aa); 1004 memset(aaExpand, aa, count); 1005 mode->xfer16(device, localSpan, count, aaExpand); 1006 } 1007 device += count; 1008 runs += count; 1009 antialias += count; 1010 nonZeroCount -= count; 1011 if (nonZeroCount == 0) { 1012 break; 1013 } 1014 localSpan += count; 1015 SkASSERT(nonZeroCount > 0); 1016 count = *runs; 1017 SkASSERT(count > 0); 1018 aa = *antialias; 1019 } 1020 } 1021 } 1022 1023 /////////////////////////////////////////////////////////////////////////////// 1024 1025 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, 1026 void* storage, size_t storageSize) { 1027 SkBlitter* blitter; 1028 SkShader* shader = paint.getShader(); 1029 SkXfermode* mode = paint.getXfermode(); 1030 1031 // we require a shader if there is an xfermode, handled by our caller 1032 SkASSERT(NULL == mode || NULL != shader); 1033 1034 if (shader) { 1035 if (mode) { 1036 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, 1037 storage, storageSize, (device, paint)); 1038 } else if (shader->canCallShadeSpan16()) { 1039 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, 1040 storage, storageSize, (device, paint)); 1041 } else { 1042 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, 1043 storage, storageSize, (device, paint)); 1044 } 1045 } else { 1046 // no shader, no xfermode, (and we always ignore colorfilter) 1047 SkColor color = paint.getColor(); 1048 if (0 == SkColorGetA(color)) { 1049 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 1050 #ifdef USE_BLACK_BLITTER 1051 } else if (SK_ColorBLACK == color) { 1052 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, 1053 storageSize, (device, paint)); 1054 #endif 1055 } else if (0xFF == SkColorGetA(color)) { 1056 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage, 1057 storageSize, (device, paint)); 1058 } else { 1059 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, 1060 storageSize, (device, paint)); 1061 } 1062 } 1063 1064 return blitter; 1065 } 1066