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