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