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 size_t 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 size_t 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, dev_lo, dev_hi; 394 uint32x4_t wn1, wn2, tmp; 395 uint32x4_t vmask_g16, vmask_ng16; 396 uint16x8_t valpha, vdev; 397 uint16x4_t odev_lo, odev_hi, valpha_lo, valpha_hi; 398 399 // prepare constants 400 vmask_g16 = vdupq_n_u32(SK_G16_MASK_IN_PLACE); 401 vmask_ng16 = vdupq_n_u32(~SK_G16_MASK_IN_PLACE); 402 color = vdupq_n_u32(expanded32); 403 404 do { 405 // alpha is 8x8, widen and split to get a pair of 16x4 406 valpha = vaddw_u8(vdupq_n_u16(1), vld1_u8(alpha)); 407 valpha = vshrq_n_u16(valpha, 3); 408 valpha_lo = vget_low_u16(valpha); 409 valpha_hi = vget_high_u16(valpha); 410 411 // load pixels 412 vdev = vld1q_u16(device); 413 dev_lo = vmovl_u16(vget_low_u16(vdev)); 414 dev_hi = vmovl_u16(vget_high_u16(vdev)); 415 416 // unpack them in 32 bits 417 dev_lo = (dev_lo & vmask_ng16) | vshlq_n_u32(dev_lo & vmask_g16, 16); 418 dev_hi = (dev_hi & vmask_ng16) | vshlq_n_u32(dev_hi & vmask_g16, 16); 419 420 // blend with color 421 tmp = (color - dev_lo) * vmovl_u16(valpha_lo); 422 tmp = vshrq_n_u32(tmp, 5); 423 dev_lo += tmp; 424 425 tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi)); 426 tmp = vshrq_n_u32(tmp, 5); 427 dev_hi += tmp; 428 429 // re-compact 430 wn1 = dev_lo & vmask_ng16; 431 wn2 = vshrq_n_u32(dev_lo, 16) & vmask_g16; 432 odev_lo = vmovn_u32(wn1 | wn2); 433 434 wn1 = dev_hi & vmask_ng16; 435 wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16; 436 odev_hi = vmovn_u32(wn1 | wn2); 437 438 // store 439 vst1q_u16(device, vcombine_u16(odev_lo, odev_hi)); 440 441 device += UNROLL; 442 alpha += UNROLL; 443 w -= UNROLL; 444 } while (w >= UNROLL); 445 } 446 447 // residuals 448 while (w > 0) { 449 *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 450 SkAlpha255To256(*alpha++) >> 3); 451 device += 1; 452 --w; 453 } 454 device = (uint16_t*)((char*)device + deviceRB); 455 alpha += maskRB; 456 } while (--height != 0); 457 #undef UNROLL 458 #else // non-neon code 459 do { 460 int w = width; 461 do { 462 *device = blend_compact(expanded32, SkExpand_rgb_16(*device), 463 SkAlpha255To256(*alpha++) >> 3); 464 device += 1; 465 } while (--w != 0); 466 device = (uint16_t*)((char*)device + deviceRB); 467 alpha += maskRB; 468 } while (--height != 0); 469 #endif 470 } 471 472 void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 473 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 474 size_t deviceRB = fDevice.rowBytes(); 475 476 // TODO: respect fDoDither 477 unsigned scale5 = SkAlpha255To256(alpha) >> 3; 478 uint32_t src32 = fExpandedRaw16 * scale5; 479 scale5 = 32 - scale5; 480 do { 481 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 482 *device = SkCompact_rgb_16((src32 + dst32) >> 5); 483 device = (uint16_t*)((char*)device + deviceRB); 484 } while (--height != 0); 485 } 486 487 void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) { 488 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 489 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 490 size_t deviceRB = fDevice.rowBytes(); 491 uint16_t color16 = fColor16; 492 493 if (fDoDither) { 494 uint16_t ditherColor = fRawDither16; 495 if ((x ^ y) & 1) { 496 SkTSwap(ditherColor, color16); 497 } 498 while (--height >= 0) { 499 sk_dither_memset16(device, color16, ditherColor, width); 500 SkTSwap(ditherColor, color16); 501 device = (uint16_t*)((char*)device + deviceRB); 502 } 503 } else { // no dither 504 while (--height >= 0) { 505 sk_memset16(device, color16, width); 506 device = (uint16_t*)((char*)device + deviceRB); 507 } 508 } 509 } 510 511 /////////////////////////////////////////////////////////////////////////////// 512 513 SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint) 514 : INHERITED(device) { 515 SkColor color = paint.getColor(); 516 517 fSrcColor32 = SkPreMultiplyColor(color); 518 fScale = SkAlpha255To256(SkColorGetA(color)); 519 520 int r = SkColorGetR(color); 521 int g = SkColorGetG(color); 522 int b = SkColorGetB(color); 523 524 fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b); 525 // if we're dithered, use fRawDither16 to hold that. 526 if ((fDoDither = paint.isDither()) != false) { 527 fRawDither16 = SkDitherPack888ToRGB16(r, g, b); 528 } 529 530 fExpandedRaw16 = SkExpand_rgb_16(fRawColor16); 531 532 fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS), 533 SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS), 534 SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS)); 535 } 536 537 const SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) { 538 if (!fDoDither && 256 == fScale) { 539 *value = fRawColor16; 540 return &fDevice; 541 } 542 return NULL; 543 } 544 545 static uint32_t pmcolor_to_expand16(SkPMColor c) { 546 unsigned r = SkGetPackedR32(c); 547 unsigned g = SkGetPackedG32(c); 548 unsigned b = SkGetPackedB32(c); 549 return (g << 24) | (r << 13) | (b << 2); 550 } 551 552 static inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) { 553 SkASSERT(count > 0); 554 uint32_t src_expand = pmcolor_to_expand16(src); 555 unsigned scale = SkAlpha255To256(0xFF - SkGetPackedA32(src)) >> 3; 556 do { 557 uint32_t dst_expand = SkExpand_rgb_16(*dst) * scale; 558 *dst = SkCompact_rgb_16((src_expand + dst_expand) >> 5); 559 dst += 1; 560 } while (--count != 0); 561 } 562 563 void SkRGB16_Blitter::blitH(int x, int y, int width) { 564 SkASSERT(width > 0); 565 SkASSERT(x + width <= fDevice.width()); 566 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 567 568 // TODO: respect fDoDither 569 blend32_16_row(fSrcColor32, device, width); 570 } 571 572 void SkRGB16_Blitter::blitAntiH(int x, int y, 573 const SkAlpha* SK_RESTRICT antialias, 574 const int16_t* SK_RESTRICT runs) { 575 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 576 uint32_t srcExpanded = fExpandedRaw16; 577 unsigned scale = fScale; 578 579 // TODO: respect fDoDither 580 for (;;) { 581 int count = runs[0]; 582 SkASSERT(count >= 0); 583 if (count <= 0) { 584 return; 585 } 586 runs += count; 587 588 unsigned aa = antialias[0]; 589 antialias += count; 590 if (aa) { 591 unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3); 592 uint32_t src32 = srcExpanded * scale5; 593 scale5 = 32 - scale5; 594 do { 595 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 596 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 597 } while (--count != 0); 598 continue; 599 } 600 device += count; 601 } 602 } 603 604 static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale, 605 U16CPU srcColor) { 606 if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale); 607 if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale); 608 if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale); 609 if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale); 610 if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale); 611 if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale); 612 if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale); 613 if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale); 614 } 615 616 #define SK_BLITBWMASK_NAME SkRGB16_BlendBW 617 #define SK_BLITBWMASK_ARGS , unsigned dst_scale, U16CPU src_color 618 #define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, dst_scale, src_color) 619 #define SK_BLITBWMASK_GETADDR getAddr16 620 #define SK_BLITBWMASK_DEVTYPE uint16_t 621 #include "SkBlitBWMaskTemplate.h" 622 623 void SkRGB16_Blitter::blitMask(const SkMask& mask, 624 const SkIRect& clip) { 625 if (mask.fFormat == SkMask::kBW_Format) { 626 SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16); 627 return; 628 } 629 630 uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop); 631 const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop); 632 int width = clip.width(); 633 int height = clip.height(); 634 size_t deviceRB = fDevice.rowBytes() - (width << 1); 635 unsigned maskRB = mask.fRowBytes - width; 636 uint32_t color32 = fExpandedRaw16; 637 638 unsigned scale256 = fScale; 639 do { 640 int w = width; 641 do { 642 unsigned aa = *alpha++; 643 unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3); 644 uint32_t src32 = color32 * scale; 645 uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale); 646 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5); 647 } while (--w != 0); 648 device = (uint16_t*)((char*)device + deviceRB); 649 alpha += maskRB; 650 } while (--height != 0); 651 } 652 653 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { 654 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 655 size_t deviceRB = fDevice.rowBytes(); 656 657 // TODO: respect fDoDither 658 unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3); 659 uint32_t src32 = fExpandedRaw16 * scale5; 660 scale5 = 32 - scale5; 661 do { 662 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5; 663 *device = SkCompact_rgb_16((src32 + dst32) >> 5); 664 device = (uint16_t*)((char*)device + deviceRB); 665 } while (--height != 0); 666 } 667 668 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { 669 SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height()); 670 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 671 size_t deviceRB = fDevice.rowBytes(); 672 SkPMColor src32 = fSrcColor32; 673 674 while (--height >= 0) { 675 blend32_16_row(src32, device, width); 676 device = (uint16_t*)((char*)device + deviceRB); 677 } 678 } 679 680 /////////////////////////////////////////////////////////////////////////////// 681 682 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device, 683 const SkPaint& paint) 684 : SkRGB16_Shader_Blitter(device, paint) { 685 SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags)); 686 } 687 688 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) { 689 SkASSERT(x + width <= fDevice.width()); 690 691 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 692 SkShader* shader = fShader; 693 694 int alpha = shader->getSpan16Alpha(); 695 if (0xFF == alpha) { 696 shader->shadeSpan16(x, y, device, width); 697 } else { 698 uint16_t* span16 = (uint16_t*)fBuffer; 699 shader->shadeSpan16(x, y, span16, width); 700 SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width); 701 } 702 } 703 704 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) { 705 SkShader* shader = fShader; 706 uint16_t* dst = fDevice.getAddr16(x, y); 707 size_t dstRB = fDevice.rowBytes(); 708 int alpha = shader->getSpan16Alpha(); 709 710 if (0xFF == alpha) { 711 if (fShaderFlags & SkShader::kConstInY16_Flag) { 712 // have the shader blit directly into the device the first time 713 shader->shadeSpan16(x, y, dst, width); 714 // and now just memcpy that line on the subsequent lines 715 if (--height > 0) { 716 const uint16_t* orig = dst; 717 do { 718 dst = (uint16_t*)((char*)dst + dstRB); 719 memcpy(dst, orig, width << 1); 720 } while (--height); 721 } 722 } else { // need to call shadeSpan16 for every line 723 do { 724 shader->shadeSpan16(x, y, dst, width); 725 y += 1; 726 dst = (uint16_t*)((char*)dst + dstRB); 727 } while (--height); 728 } 729 } else { 730 int scale = SkAlpha255To256(alpha); 731 uint16_t* span16 = (uint16_t*)fBuffer; 732 if (fShaderFlags & SkShader::kConstInY16_Flag) { 733 shader->shadeSpan16(x, y, span16, width); 734 do { 735 SkBlendRGB16(span16, dst, scale, width); 736 dst = (uint16_t*)((char*)dst + dstRB); 737 } while (--height); 738 } else { 739 do { 740 shader->shadeSpan16(x, y, span16, width); 741 SkBlendRGB16(span16, dst, scale, width); 742 y += 1; 743 dst = (uint16_t*)((char*)dst + dstRB); 744 } while (--height); 745 } 746 } 747 } 748 749 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y, 750 const SkAlpha* SK_RESTRICT antialias, 751 const int16_t* SK_RESTRICT runs) { 752 SkShader* shader = fShader; 753 SkPMColor* SK_RESTRICT span = fBuffer; 754 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 755 756 int alpha = shader->getSpan16Alpha(); 757 uint16_t* span16 = (uint16_t*)span; 758 759 if (0xFF == alpha) { 760 for (;;) { 761 int count = *runs; 762 if (count <= 0) { 763 break; 764 } 765 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 766 767 int aa = *antialias; 768 if (aa == 255) { 769 // go direct to the device! 770 shader->shadeSpan16(x, y, device, count); 771 } else if (aa) { 772 shader->shadeSpan16(x, y, span16, count); 773 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 774 } 775 device += count; 776 runs += count; 777 antialias += count; 778 x += count; 779 } 780 } else { // span alpha is < 255 781 alpha = SkAlpha255To256(alpha); 782 for (;;) { 783 int count = *runs; 784 if (count <= 0) { 785 break; 786 } 787 SkASSERT(count <= fDevice.width()); // don't overrun fBuffer 788 789 int aa = SkAlphaMul(*antialias, alpha); 790 if (aa) { 791 shader->shadeSpan16(x, y, span16, count); 792 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count); 793 } 794 795 device += count; 796 runs += count; 797 antialias += count; 798 x += count; 799 } 800 } 801 } 802 803 /////////////////////////////////////////////////////////////////////////////// 804 805 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device, 806 const SkPaint& paint) 807 : INHERITED(device, paint) { 808 SkASSERT(paint.getXfermode() == NULL); 809 810 fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor)); 811 812 // compute SkBlitRow::Procs 813 unsigned flags = 0; 814 815 uint32_t shaderFlags = fShaderFlags; 816 // shaders take care of global alpha, so we never set it in SkBlitRow 817 if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { 818 flags |= SkBlitRow::kSrcPixelAlpha_Flag; 819 } 820 // don't dither if the shader is really 16bit 821 if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) { 822 flags |= SkBlitRow::kDither_Flag; 823 } 824 // used when we know our global alpha is 0xFF 825 fOpaqueProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config); 826 // used when we know our global alpha is < 0xFF 827 fAlphaProc = SkBlitRow::Factory(flags | SkBlitRow::kGlobalAlpha_Flag, 828 SkBitmap::kRGB_565_Config); 829 } 830 831 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() { 832 sk_free(fBuffer); 833 } 834 835 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { 836 SkASSERT(x + width <= fDevice.width()); 837 838 fShader->shadeSpan(x, y, fBuffer, width); 839 // shaders take care of global alpha, so we pass 0xFF (should be ignored) 840 fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y); 841 } 842 843 void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { 844 SkShader* shader = fShader; 845 SkBlitRow::Proc proc = fOpaqueProc; 846 SkPMColor* buffer = fBuffer; 847 uint16_t* dst = fDevice.getAddr16(x, y); 848 size_t dstRB = fDevice.rowBytes(); 849 850 if (fShaderFlags & SkShader::kConstInY32_Flag) { 851 shader->shadeSpan(x, y, buffer, width); 852 do { 853 proc(dst, buffer, width, 0xFF, x, y); 854 y += 1; 855 dst = (uint16_t*)((char*)dst + dstRB); 856 } while (--height); 857 } else { 858 do { 859 shader->shadeSpan(x, y, buffer, width); 860 proc(dst, buffer, width, 0xFF, x, y); 861 y += 1; 862 dst = (uint16_t*)((char*)dst + dstRB); 863 } while (--height); 864 } 865 } 866 867 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { 868 int count = 0; 869 for (;;) { 870 int n = *runs; 871 if (n == 0 || *aa == 0) { 872 break; 873 } 874 runs += n; 875 aa += n; 876 count += n; 877 } 878 return count; 879 } 880 881 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, 882 const SkAlpha* SK_RESTRICT antialias, 883 const int16_t* SK_RESTRICT runs) { 884 SkShader* shader = fShader; 885 SkPMColor* SK_RESTRICT span = fBuffer; 886 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 887 888 for (;;) { 889 int count = *runs; 890 if (count <= 0) { 891 break; 892 } 893 int aa = *antialias; 894 if (0 == aa) { 895 device += count; 896 runs += count; 897 antialias += count; 898 x += count; 899 continue; 900 } 901 902 int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count); 903 904 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 905 shader->shadeSpan(x, y, span, nonZeroCount); 906 907 SkPMColor* localSpan = span; 908 for (;;) { 909 SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc; 910 proc(device, localSpan, count, aa, x, y); 911 912 x += count; 913 device += count; 914 runs += count; 915 antialias += count; 916 nonZeroCount -= count; 917 if (nonZeroCount == 0) { 918 break; 919 } 920 localSpan += count; 921 SkASSERT(nonZeroCount > 0); 922 count = *runs; 923 SkASSERT(count > 0); 924 aa = *antialias; 925 } 926 } 927 } 928 929 /////////////////////////////////////////////////////////////////////// 930 931 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( 932 const SkBitmap& device, const SkPaint& paint) 933 : INHERITED(device, paint) { 934 fXfermode = paint.getXfermode(); 935 SkASSERT(fXfermode); 936 fXfermode->ref(); 937 938 int width = device.width(); 939 fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor)); 940 fAAExpand = (uint8_t*)(fBuffer + width); 941 } 942 943 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() { 944 fXfermode->unref(); 945 sk_free(fBuffer); 946 } 947 948 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { 949 SkASSERT(x + width <= fDevice.width()); 950 951 uint16_t* device = fDevice.getAddr16(x, y); 952 SkPMColor* span = fBuffer; 953 954 fShader->shadeSpan(x, y, span, width); 955 fXfermode->xfer16(device, span, width, NULL); 956 } 957 958 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, 959 const SkAlpha* SK_RESTRICT antialias, 960 const int16_t* SK_RESTRICT runs) { 961 SkShader* shader = fShader; 962 SkXfermode* mode = fXfermode; 963 SkPMColor* SK_RESTRICT span = fBuffer; 964 uint8_t* SK_RESTRICT aaExpand = fAAExpand; 965 uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y); 966 967 for (;;) { 968 int count = *runs; 969 if (count <= 0) { 970 break; 971 } 972 int aa = *antialias; 973 if (0 == aa) { 974 device += count; 975 runs += count; 976 antialias += count; 977 x += count; 978 continue; 979 } 980 981 int nonZeroCount = count + count_nonzero_span(runs + count, 982 antialias + count); 983 984 SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer 985 shader->shadeSpan(x, y, span, nonZeroCount); 986 987 x += nonZeroCount; 988 SkPMColor* localSpan = span; 989 for (;;) { 990 if (aa == 0xFF) { 991 mode->xfer16(device, localSpan, count, NULL); 992 } else { 993 SkASSERT(aa); 994 memset(aaExpand, aa, count); 995 mode->xfer16(device, localSpan, count, aaExpand); 996 } 997 device += count; 998 runs += count; 999 antialias += count; 1000 nonZeroCount -= count; 1001 if (nonZeroCount == 0) { 1002 break; 1003 } 1004 localSpan += count; 1005 SkASSERT(nonZeroCount > 0); 1006 count = *runs; 1007 SkASSERT(count > 0); 1008 aa = *antialias; 1009 } 1010 } 1011 } 1012 1013 /////////////////////////////////////////////////////////////////////////////// 1014 1015 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, 1016 void* storage, size_t storageSize) { 1017 SkBlitter* blitter; 1018 SkShader* shader = paint.getShader(); 1019 SkXfermode* mode = paint.getXfermode(); 1020 1021 // we require a shader if there is an xfermode, handled by our caller 1022 SkASSERT(NULL == mode || NULL != shader); 1023 1024 if (shader) { 1025 if (mode) { 1026 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, 1027 storage, storageSize, (device, paint)); 1028 } else if (shader->canCallShadeSpan16()) { 1029 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, 1030 storage, storageSize, (device, paint)); 1031 } else { 1032 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, 1033 storage, storageSize, (device, paint)); 1034 } 1035 } else { 1036 // no shader, no xfermode, (and we always ignore colorfilter) 1037 SkColor color = paint.getColor(); 1038 if (0 == SkColorGetA(color)) { 1039 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 1040 #ifdef USE_BLACK_BLITTER 1041 } else if (SK_ColorBLACK == color) { 1042 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, 1043 storageSize, (device, paint)); 1044 #endif 1045 } else if (0xFF == SkColorGetA(color)) { 1046 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage, 1047 storageSize, (device, paint)); 1048 } else { 1049 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, 1050 storageSize, (device, paint)); 1051 } 1052 } 1053 1054 return blitter; 1055 } 1056