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