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 "SkBlitter.h" 9 #include "SkAntiRun.h" 10 #include "SkColor.h" 11 #include "SkColorFilter.h" 12 #include "SkReadBuffer.h" 13 #include "SkWriteBuffer.h" 14 #include "SkMask.h" 15 #include "SkMaskFilter.h" 16 #include "SkString.h" 17 #include "SkTLazy.h" 18 #include "SkUtils.h" 19 #include "SkXfermode.h" 20 #include "SkXfermodeInterpretation.h" 21 22 // define this for testing srgb blits 23 //#define SK_FORCE_PM4f_FOR_L32_BLITS 24 25 SkBlitter::~SkBlitter() {} 26 27 bool SkBlitter::isNullBlitter() const { return false; } 28 29 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { 30 return true; 31 } 32 33 SkShader::Context* SkBlitter::getShaderContext() const { 34 return nullptr; 35 } 36 37 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 38 return nullptr; 39 } 40 41 void SkBlitter::blitH(int x, int y, int width) { 42 SkDEBUGFAIL("unimplemented"); 43 } 44 45 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 46 const int16_t runs[]) { 47 SkDEBUGFAIL("unimplemented"); 48 } 49 50 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 51 if (alpha == 255) { 52 this->blitRect(x, y, 1, height); 53 } else { 54 int16_t runs[2]; 55 runs[0] = 1; 56 runs[1] = 0; 57 58 while (--height >= 0) { 59 this->blitAntiH(x, y++, &alpha, runs); 60 } 61 } 62 } 63 64 void SkBlitter::blitRect(int x, int y, int width, int height) { 65 SkASSERT(width > 0); 66 while (--height >= 0) { 67 this->blitH(x, y++, width); 68 } 69 } 70 71 /// Default implementation doesn't check for any easy optimizations 72 /// such as alpha == 0 or 255; also uses blitV(), which some subclasses 73 /// may not support. 74 void SkBlitter::blitAntiRect(int x, int y, int width, int height, 75 SkAlpha leftAlpha, SkAlpha rightAlpha) { 76 this->blitV(x++, y, height, leftAlpha); 77 if (width > 0) { 78 this->blitRect(x, y, width, height); 79 x += width; 80 } 81 this->blitV(x, y, height, rightAlpha); 82 } 83 84 ////////////////////////////////////////////////////////////////////////////// 85 86 static inline void bits_to_runs(SkBlitter* blitter, int x, int y, 87 const uint8_t bits[], 88 uint8_t left_mask, ptrdiff_t rowBytes, 89 uint8_t right_mask) { 90 int inFill = 0; 91 int pos = 0; 92 93 while (--rowBytes >= 0) { 94 uint8_t b = *bits++ & left_mask; 95 if (rowBytes == 0) { 96 b &= right_mask; 97 } 98 99 for (uint8_t test = 0x80U; test != 0; test >>= 1) { 100 if (b & test) { 101 if (!inFill) { 102 pos = x; 103 inFill = true; 104 } 105 } else { 106 if (inFill) { 107 blitter->blitH(pos, y, x - pos); 108 inFill = false; 109 } 110 } 111 x += 1; 112 } 113 left_mask = 0xFFU; 114 } 115 116 // final cleanup 117 if (inFill) { 118 blitter->blitH(pos, y, x - pos); 119 } 120 } 121 122 // maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8. 123 static uint8_t generate_right_mask(int maskBitCount) { 124 return static_cast<uint8_t>(0xFF00U >> maskBitCount); 125 } 126 127 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 128 SkASSERT(mask.fBounds.contains(clip)); 129 130 if (mask.fFormat == SkMask::kLCD16_Format) { 131 return; // needs to be handled by subclass 132 } 133 134 if (mask.fFormat == SkMask::kBW_Format) { 135 int cx = clip.fLeft; 136 int cy = clip.fTop; 137 int maskLeft = mask.fBounds.fLeft; 138 int maskRowBytes = mask.fRowBytes; 139 int height = clip.height(); 140 141 const uint8_t* bits = mask.getAddr1(cx, cy); 142 143 SkDEBUGCODE(const uint8_t* endOfImage = 144 mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes 145 + ((mask.fBounds.width() + 7) >> 3)); 146 147 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 148 while (--height >= 0) { 149 int affectedRightBit = mask.fBounds.width() - 1; 150 ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1; 151 SkASSERT(bits + rowBytes <= endOfImage); 152 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 153 bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask); 154 bits += maskRowBytes; 155 cy += 1; 156 } 157 } else { 158 // Bits is calculated as the offset into the mask at the point {cx, cy} therfore, all 159 // addressing into the bit mask is relative to that point. Since this is an address 160 // calculated from a arbitrary bit in that byte, calculate the left most bit. 161 int bitsLeft = cx - ((cx - maskLeft) & 7); 162 163 // Everything is relative to the bitsLeft. 164 int leftEdge = cx - bitsLeft; 165 SkASSERT(leftEdge >= 0); 166 int rightEdge = clip.fRight - bitsLeft; 167 SkASSERT(rightEdge > leftEdge); 168 169 // Calculate left byte and mask 170 const uint8_t* leftByte = bits; 171 U8CPU leftMask = 0xFFU >> (leftEdge & 7); 172 173 // Calculate right byte and mask 174 int affectedRightBit = rightEdge - 1; 175 const uint8_t* rightByte = bits + (affectedRightBit >> 3); 176 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 177 178 // leftByte and rightByte are byte locations therefore, to get a count of bytes the 179 // code must add one. 180 ptrdiff_t rowBytes = rightByte - leftByte + 1; 181 182 while (--height >= 0) { 183 SkASSERT(bits + rowBytes <= endOfImage); 184 bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask); 185 bits += maskRowBytes; 186 cy += 1; 187 } 188 } 189 } else { 190 int width = clip.width(); 191 SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 192 int16_t* runs = runStorage.get(); 193 const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 194 195 sk_memset16((uint16_t*)runs, 1, width); 196 runs[width] = 0; 197 198 int height = clip.height(); 199 int y = clip.fTop; 200 while (--height >= 0) { 201 this->blitAntiH(clip.fLeft, y, aa, runs); 202 aa += mask.fRowBytes; 203 y += 1; 204 } 205 } 206 } 207 208 /////////////////////// these guys are not virtual, just a helpers 209 210 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 211 if (clip.quickReject(mask.fBounds)) { 212 return; 213 } 214 215 SkRegion::Cliperator clipper(clip, mask.fBounds); 216 217 while (!clipper.done()) { 218 const SkIRect& cr = clipper.rect(); 219 this->blitMask(mask, cr); 220 clipper.next(); 221 } 222 } 223 224 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 225 SkRegion::Cliperator clipper(clip, rect); 226 227 while (!clipper.done()) { 228 const SkIRect& cr = clipper.rect(); 229 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 230 clipper.next(); 231 } 232 } 233 234 void SkBlitter::blitRegion(const SkRegion& clip) { 235 SkRegion::Iterator iter(clip); 236 237 while (!iter.done()) { 238 const SkIRect& cr = iter.rect(); 239 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 240 iter.next(); 241 } 242 } 243 244 /////////////////////////////////////////////////////////////////////////////// 245 246 void SkNullBlitter::blitH(int x, int y, int width) {} 247 248 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 249 const int16_t runs[]) {} 250 251 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 252 253 void SkNullBlitter::blitRect(int x, int y, int width, int height) {} 254 255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 256 257 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 258 return nullptr; 259 } 260 261 bool SkNullBlitter::isNullBlitter() const { return true; } 262 263 /////////////////////////////////////////////////////////////////////////////// 264 265 static int compute_anti_width(const int16_t runs[]) { 266 int width = 0; 267 268 for (;;) { 269 int count = runs[0]; 270 271 SkASSERT(count >= 0); 272 if (count == 0) { 273 break; 274 } 275 width += count; 276 runs += count; 277 } 278 return width; 279 } 280 281 static inline bool y_in_rect(int y, const SkIRect& rect) { 282 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 283 } 284 285 static inline bool x_in_rect(int x, const SkIRect& rect) { 286 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 287 } 288 289 void SkRectClipBlitter::blitH(int left, int y, int width) { 290 SkASSERT(width > 0); 291 292 if (!y_in_rect(y, fClipRect)) { 293 return; 294 } 295 296 int right = left + width; 297 298 if (left < fClipRect.fLeft) { 299 left = fClipRect.fLeft; 300 } 301 if (right > fClipRect.fRight) { 302 right = fClipRect.fRight; 303 } 304 305 width = right - left; 306 if (width > 0) { 307 fBlitter->blitH(left, y, width); 308 } 309 } 310 311 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 312 const int16_t runs[]) { 313 if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 314 return; 315 } 316 317 int x0 = left; 318 int x1 = left + compute_anti_width(runs); 319 320 if (x1 <= fClipRect.fLeft) { 321 return; 322 } 323 324 SkASSERT(x0 < x1); 325 if (x0 < fClipRect.fLeft) { 326 int dx = fClipRect.fLeft - x0; 327 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 328 runs += dx; 329 aa += dx; 330 x0 = fClipRect.fLeft; 331 } 332 333 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 334 if (x1 > fClipRect.fRight) { 335 x1 = fClipRect.fRight; 336 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 337 ((int16_t*)runs)[x1 - x0] = 0; 338 } 339 340 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 341 SkASSERT(compute_anti_width(runs) == x1 - x0); 342 343 fBlitter->blitAntiH(x0, y, aa, runs); 344 } 345 346 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 347 SkASSERT(height > 0); 348 349 if (!x_in_rect(x, fClipRect)) { 350 return; 351 } 352 353 int y0 = y; 354 int y1 = y + height; 355 356 if (y0 < fClipRect.fTop) { 357 y0 = fClipRect.fTop; 358 } 359 if (y1 > fClipRect.fBottom) { 360 y1 = fClipRect.fBottom; 361 } 362 363 if (y0 < y1) { 364 fBlitter->blitV(x, y0, y1 - y0, alpha); 365 } 366 } 367 368 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 369 SkIRect r; 370 371 r.set(left, y, left + width, y + height); 372 if (r.intersect(fClipRect)) { 373 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 374 } 375 } 376 377 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 378 SkAlpha leftAlpha, SkAlpha rightAlpha) { 379 SkIRect r; 380 381 // The *true* width of the rectangle blitted is width+2: 382 r.set(left, y, left + width + 2, y + height); 383 if (r.intersect(fClipRect)) { 384 if (r.fLeft != left) { 385 SkASSERT(r.fLeft > left); 386 leftAlpha = 255; 387 } 388 if (r.fRight != left + width + 2) { 389 SkASSERT(r.fRight < left + width + 2); 390 rightAlpha = 255; 391 } 392 if (255 == leftAlpha && 255 == rightAlpha) { 393 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 394 } else if (1 == r.width()) { 395 if (r.fLeft == left) { 396 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 397 } else { 398 SkASSERT(r.fLeft == left + width + 1); 399 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 400 } 401 } else { 402 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 403 leftAlpha, rightAlpha); 404 } 405 } 406 } 407 408 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 409 SkASSERT(mask.fBounds.contains(clip)); 410 411 SkIRect r = clip; 412 413 if (r.intersect(fClipRect)) { 414 fBlitter->blitMask(mask, r); 415 } 416 } 417 418 const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 419 return fBlitter->justAnOpaqueColor(value); 420 } 421 422 /////////////////////////////////////////////////////////////////////////////// 423 424 void SkRgnClipBlitter::blitH(int x, int y, int width) { 425 SkRegion::Spanerator span(*fRgn, y, x, x + width); 426 int left, right; 427 428 while (span.next(&left, &right)) { 429 SkASSERT(left < right); 430 fBlitter->blitH(left, y, right - left); 431 } 432 } 433 434 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 435 const int16_t runs[]) { 436 int width = compute_anti_width(runs); 437 SkRegion::Spanerator span(*fRgn, y, x, x + width); 438 int left, right; 439 SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 440 441 int prevRite = x; 442 while (span.next(&left, &right)) { 443 SkASSERT(x <= left); 444 SkASSERT(left < right); 445 SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 446 447 SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 448 449 // now zero before left 450 if (left > prevRite) { 451 int index = prevRite - x; 452 ((uint8_t*)aa)[index] = 0; // skip runs after right 453 ((int16_t*)runs)[index] = SkToS16(left - prevRite); 454 } 455 456 prevRite = right; 457 } 458 459 if (prevRite > x) { 460 ((int16_t*)runs)[prevRite - x] = 0; 461 462 if (x < 0) { 463 int skip = runs[0]; 464 SkASSERT(skip >= -x); 465 aa += skip; 466 runs += skip; 467 x += skip; 468 } 469 fBlitter->blitAntiH(x, y, aa, runs); 470 } 471 } 472 473 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 474 SkIRect bounds; 475 bounds.set(x, y, x + 1, y + height); 476 477 SkRegion::Cliperator iter(*fRgn, bounds); 478 479 while (!iter.done()) { 480 const SkIRect& r = iter.rect(); 481 SkASSERT(bounds.contains(r)); 482 483 fBlitter->blitV(x, r.fTop, r.height(), alpha); 484 iter.next(); 485 } 486 } 487 488 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 489 SkIRect bounds; 490 bounds.set(x, y, x + width, y + height); 491 492 SkRegion::Cliperator iter(*fRgn, bounds); 493 494 while (!iter.done()) { 495 const SkIRect& r = iter.rect(); 496 SkASSERT(bounds.contains(r)); 497 498 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 499 iter.next(); 500 } 501 } 502 503 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 504 SkAlpha leftAlpha, SkAlpha rightAlpha) { 505 // The *true* width of the rectangle to blit is width + 2 506 SkIRect bounds; 507 bounds.set(x, y, x + width + 2, y + height); 508 509 SkRegion::Cliperator iter(*fRgn, bounds); 510 511 while (!iter.done()) { 512 const SkIRect& r = iter.rect(); 513 SkASSERT(bounds.contains(r)); 514 SkASSERT(r.fLeft >= x); 515 SkASSERT(r.fRight <= x + width + 2); 516 517 SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 518 SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 519 rightAlpha : 255; 520 521 if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 522 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 523 } else if (1 == r.width()) { 524 if (r.fLeft == x) { 525 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 526 effectiveLeftAlpha); 527 } else { 528 SkASSERT(r.fLeft == x + width + 1); 529 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 530 effectiveRightAlpha); 531 } 532 } else { 533 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 534 effectiveLeftAlpha, effectiveRightAlpha); 535 } 536 iter.next(); 537 } 538 } 539 540 541 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 542 SkASSERT(mask.fBounds.contains(clip)); 543 544 SkRegion::Cliperator iter(*fRgn, clip); 545 const SkIRect& r = iter.rect(); 546 SkBlitter* blitter = fBlitter; 547 548 while (!iter.done()) { 549 blitter->blitMask(mask, r); 550 iter.next(); 551 } 552 } 553 554 const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 555 return fBlitter->justAnOpaqueColor(value); 556 } 557 558 /////////////////////////////////////////////////////////////////////////////// 559 560 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 561 const SkIRect* ir) { 562 if (clip) { 563 const SkIRect& clipR = clip->getBounds(); 564 565 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 566 blitter = &fNullBlitter; 567 } else if (clip->isRect()) { 568 if (ir == nullptr || !clipR.contains(*ir)) { 569 fRectBlitter.init(blitter, clipR); 570 blitter = &fRectBlitter; 571 } 572 } else { 573 fRgnBlitter.init(blitter, clip); 574 blitter = &fRgnBlitter; 575 } 576 } 577 return blitter; 578 } 579 580 /////////////////////////////////////////////////////////////////////////////// 581 582 #include "SkColorShader.h" 583 #include "SkColorPriv.h" 584 585 class Sk3DShader : public SkShader { 586 public: 587 Sk3DShader(SkShader* proxy) : fProxy(proxy) { 588 SkSafeRef(proxy); 589 } 590 591 virtual ~Sk3DShader() { 592 SkSafeUnref(fProxy); 593 } 594 595 size_t contextSize(const ContextRec& rec) const override { 596 size_t size = sizeof(Sk3DShaderContext); 597 if (fProxy) { 598 size += fProxy->contextSize(rec); 599 } 600 return size; 601 } 602 603 Context* onCreateContext(const ContextRec& rec, void* storage) const override { 604 SkShader::Context* proxyContext = nullptr; 605 if (fProxy) { 606 char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext); 607 proxyContext = fProxy->createContext(rec, proxyContextStorage); 608 if (!proxyContext) { 609 return nullptr; 610 } 611 } 612 return new (storage) Sk3DShaderContext(*this, rec, proxyContext); 613 } 614 615 class Sk3DShaderContext : public SkShader::Context { 616 public: 617 // Calls proxyContext's destructor but will NOT free its memory. 618 Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, 619 SkShader::Context* proxyContext) 620 : INHERITED(shader, rec) 621 , fMask(nullptr) 622 , fProxyContext(proxyContext) 623 { 624 if (!fProxyContext) { 625 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); 626 } 627 } 628 629 virtual ~Sk3DShaderContext() { 630 if (fProxyContext) { 631 fProxyContext->~Context(); 632 } 633 } 634 635 void set3DMask(const SkMask* mask) override { fMask = mask; } 636 637 void shadeSpan(int x, int y, SkPMColor span[], int count) override { 638 if (fProxyContext) { 639 fProxyContext->shadeSpan(x, y, span, count); 640 } 641 642 if (fMask == nullptr) { 643 if (fProxyContext == nullptr) { 644 sk_memset32(span, fPMColor, count); 645 } 646 return; 647 } 648 649 SkASSERT(fMask->fBounds.contains(x, y)); 650 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 651 652 size_t size = fMask->computeImageSize(); 653 const uint8_t* alpha = fMask->getAddr8(x, y); 654 const uint8_t* mulp = alpha + size; 655 const uint8_t* addp = mulp + size; 656 657 if (fProxyContext) { 658 for (int i = 0; i < count; i++) { 659 if (alpha[i]) { 660 SkPMColor c = span[i]; 661 if (c) { 662 unsigned a = SkGetPackedA32(c); 663 unsigned r = SkGetPackedR32(c); 664 unsigned g = SkGetPackedG32(c); 665 unsigned b = SkGetPackedB32(c); 666 667 unsigned mul = SkAlpha255To256(mulp[i]); 668 unsigned add = addp[i]; 669 670 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 671 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 672 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 673 674 span[i] = SkPackARGB32(a, r, g, b); 675 } 676 } else { 677 span[i] = 0; 678 } 679 } 680 } else { // color 681 unsigned a = SkGetPackedA32(fPMColor); 682 unsigned r = SkGetPackedR32(fPMColor); 683 unsigned g = SkGetPackedG32(fPMColor); 684 unsigned b = SkGetPackedB32(fPMColor); 685 for (int i = 0; i < count; i++) { 686 if (alpha[i]) { 687 unsigned mul = SkAlpha255To256(mulp[i]); 688 unsigned add = addp[i]; 689 690 span[i] = SkPackARGB32( a, 691 SkFastMin32(SkAlphaMul(r, mul) + add, a), 692 SkFastMin32(SkAlphaMul(g, mul) + add, a), 693 SkFastMin32(SkAlphaMul(b, mul) + add, a)); 694 } else { 695 span[i] = 0; 696 } 697 } 698 } 699 } 700 701 private: 702 // Unowned. 703 const SkMask* fMask; 704 // Memory is unowned, but we need to call the destructor. 705 SkShader::Context* fProxyContext; 706 SkPMColor fPMColor; 707 708 typedef SkShader::Context INHERITED; 709 }; 710 711 #ifndef SK_IGNORE_TO_STRING 712 void toString(SkString* str) const override { 713 str->append("Sk3DShader: ("); 714 715 if (fProxy) { 716 str->append("Proxy: "); 717 fProxy->toString(str); 718 } 719 720 this->INHERITED::toString(str); 721 722 str->append(")"); 723 } 724 #endif 725 726 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 727 728 protected: 729 void flatten(SkWriteBuffer& buffer) const override { 730 buffer.writeFlattenable(fProxy); 731 } 732 733 private: 734 SkShader* fProxy; 735 736 typedef SkShader INHERITED; 737 }; 738 739 SkFlattenable* Sk3DShader::CreateProc(SkReadBuffer& buffer) { 740 SkAutoTUnref<SkShader> shader(buffer.readShader()); 741 return new Sk3DShader(shader); 742 } 743 744 class Sk3DBlitter : public SkBlitter { 745 public: 746 Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext) 747 : fProxy(proxy) 748 , fShaderContext(shaderContext) 749 {} 750 751 void blitH(int x, int y, int width) override { 752 fProxy->blitH(x, y, width); 753 } 754 755 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 756 const int16_t runs[]) override { 757 fProxy->blitAntiH(x, y, antialias, runs); 758 } 759 760 void blitV(int x, int y, int height, SkAlpha alpha) override { 761 fProxy->blitV(x, y, height, alpha); 762 } 763 764 void blitRect(int x, int y, int width, int height) override { 765 fProxy->blitRect(x, y, width, height); 766 } 767 768 void blitMask(const SkMask& mask, const SkIRect& clip) override { 769 if (mask.fFormat == SkMask::k3D_Format) { 770 fShaderContext->set3DMask(&mask); 771 772 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 773 fProxy->blitMask(mask, clip); 774 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 775 776 fShaderContext->set3DMask(nullptr); 777 } else { 778 fProxy->blitMask(mask, clip); 779 } 780 } 781 782 private: 783 // Both pointers are unowned. They will be deleted by SkSmallAllocator. 784 SkBlitter* fProxy; 785 SkShader::Context* fShaderContext; 786 }; 787 788 /////////////////////////////////////////////////////////////////////////////// 789 790 #include "SkCoreBlitters.h" 791 792 SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { 793 #ifdef SK_FORCE_PM4f_FOR_L32_BLITS 794 return SkShader::ContextRec::kPM4f_DstType; 795 #else 796 return (dstInfo.isSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) 797 ? SkShader::ContextRec::kPM4f_DstType 798 : SkShader::ContextRec::kPMColor_DstType; 799 #endif 800 } 801 802 SkBlitter* SkBlitter::Choose(const SkPixmap& device, 803 const SkMatrix& matrix, 804 const SkPaint& origPaint, 805 SkTBlitterAllocator* allocator, 806 bool drawCoverage) { 807 SkASSERT(allocator != nullptr); 808 809 // which check, in case we're being called by a client with a dummy device 810 // (e.g. they have a bounder that always aborts the draw) 811 if (kUnknown_SkColorType == device.colorType() || 812 (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { 813 return allocator->createT<SkNullBlitter>(); 814 } 815 816 SkShader* shader = origPaint.getShader(); 817 SkColorFilter* cf = origPaint.getColorFilter(); 818 SkXfermode* mode = origPaint.getXfermode(); 819 Sk3DShader* shader3D = nullptr; 820 821 SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 822 823 if (origPaint.getMaskFilter() != nullptr && 824 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 825 shader3D = new Sk3DShader(shader); 826 // we know we haven't initialized lazyPaint yet, so just do it 827 paint.writable()->setShader(shader3D)->unref(); 828 shader = shader3D; 829 } 830 831 if (mode) { 832 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); 833 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { 834 case kSrcOver_SkXfermodeInterpretation: 835 mode = nullptr; 836 paint.writable()->setXfermode(nullptr); 837 break; 838 case kSkipDrawing_SkXfermodeInterpretation:{ 839 return allocator->createT<SkNullBlitter>(); 840 } 841 default: 842 break; 843 } 844 } 845 846 /* 847 * If the xfermode is CLEAR, then we can completely ignore the installed 848 * color/shader/colorfilter, and just pretend we're SRC + color==0. This 849 * will fall into our optimizations for SRC mode. 850 */ 851 if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) { 852 SkPaint* p = paint.writable(); 853 shader = p->setShader(nullptr); 854 cf = p->setColorFilter(nullptr); 855 mode = p->setXfermodeMode(SkXfermode::kSrc_Mode); 856 p->setColor(0); 857 } 858 859 if (nullptr == shader) { 860 if (mode) { 861 // xfermodes (and filters) require shaders for our current blitters 862 shader = new SkColorShader(paint->getColor()); 863 paint.writable()->setShader(shader)->unref(); 864 paint.writable()->setAlpha(0xFF); 865 } else if (cf) { 866 // if no shader && no xfermode, we just apply the colorfilter to 867 // our color and move on. 868 SkPaint* writablePaint = paint.writable(); 869 writablePaint->setColor(cf->filterColor(paint->getColor())); 870 writablePaint->setColorFilter(nullptr); 871 cf = nullptr; 872 } 873 } 874 875 if (cf) { 876 SkASSERT(shader); 877 shader = shader->newWithColorFilter(cf); 878 paint.writable()->setShader(shader)->unref(); 879 // blitters should ignore the presence/absence of a filter, since 880 // if there is one, the shader will take care of it. 881 } 882 883 /* 884 * We create a SkShader::Context object, and store it on the blitter. 885 */ 886 SkShader::Context* shaderContext = nullptr; 887 if (shader) { 888 const SkShader::ContextRec rec(*paint, matrix, nullptr, 889 PreferredShaderDest(device.info())); 890 size_t contextSize = shader->contextSize(rec); 891 if (contextSize) { 892 // Try to create the ShaderContext 893 void* storage = allocator->reserveT<SkShader::Context>(contextSize); 894 shaderContext = shader->createContext(rec, storage); 895 if (!shaderContext) { 896 allocator->freeLast(); 897 return allocator->createT<SkNullBlitter>(); 898 } 899 SkASSERT(shaderContext); 900 SkASSERT((void*) shaderContext == storage); 901 } else { 902 return allocator->createT<SkNullBlitter>(); 903 } 904 } 905 906 SkBlitter* blitter = nullptr; 907 switch (device.colorType()) { 908 case kAlpha_8_SkColorType: 909 if (drawCoverage) { 910 SkASSERT(nullptr == shader); 911 SkASSERT(nullptr == paint->getXfermode()); 912 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *paint); 913 } else if (shader) { 914 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext); 915 } else { 916 blitter = allocator->createT<SkA8_Blitter>(device, *paint); 917 } 918 break; 919 920 case kRGB_565_SkColorType: 921 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, allocator); 922 break; 923 924 case kN32_SkColorType: 925 #ifdef SK_FORCE_PM4f_FOR_L32_BLITS 926 if (true) 927 #else 928 if (device.info().isSRGB()) 929 #endif 930 { 931 blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, allocator); 932 } else { 933 if (shader) { 934 blitter = allocator->createT<SkARGB32_Shader_Blitter>( 935 device, *paint, shaderContext); 936 } else if (paint->getColor() == SK_ColorBLACK) { 937 blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint); 938 } else if (paint->getAlpha() == 0xFF) { 939 blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint); 940 } else { 941 blitter = allocator->createT<SkARGB32_Blitter>(device, *paint); 942 } 943 } 944 break; 945 946 case kRGBA_F16_SkColorType: 947 // kU16_SkColorType: 948 blitter = SkBlitter_ARGB64_Create(device, *paint, shaderContext, allocator); 949 break; 950 951 default: 952 break; 953 } 954 955 if (!blitter) { 956 blitter = allocator->createT<SkNullBlitter>(); 957 } 958 959 if (shader3D) { 960 SkBlitter* innerBlitter = blitter; 961 // innerBlitter was allocated by allocator, which will delete it. 962 // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to 963 // wrapper the blitter to notify it when we see an emboss mask. 964 blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext); 965 } 966 return blitter; 967 } 968 969 /////////////////////////////////////////////////////////////////////////////// 970 971 class SkZeroShaderContext : public SkShader::Context { 972 public: 973 SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) 974 // Override rec with the identity matrix, so it is guaranteed to be invertible. 975 : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr, 976 rec.fPreferredDstType)) {} 977 978 void shadeSpan(int x, int y, SkPMColor colors[], int count) override { 979 sk_bzero(colors, count * sizeof(SkPMColor)); 980 } 981 982 private: 983 typedef SkShader::Context INHERITED; 984 }; 985 986 SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, 987 SkShader::Context* shaderContext) 988 : INHERITED(device) 989 , fShader(paint.getShader()) 990 , fShaderContext(shaderContext) { 991 SkASSERT(fShader); 992 SkASSERT(fShaderContext); 993 994 fShader->ref(); 995 fShaderFlags = fShaderContext->getFlags(); 996 fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag); 997 } 998 999 SkShaderBlitter::~SkShaderBlitter() { 1000 fShader->unref(); 1001 } 1002 1003 bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) { 1004 // Only destroy the old context if we have a new one. We need to ensure to have a 1005 // live context in fShaderContext because the storage is owned by an SkSmallAllocator 1006 // outside of this class. 1007 // The new context will be of the same size as the old one because we use the same 1008 // shader to create it. It is therefore safe to re-use the storage. 1009 fShaderContext->~Context(); 1010 SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); 1011 if (nullptr == ctx) { 1012 // Need a valid context in fShaderContext's storage, so we can later (or our caller) call 1013 // the in-place destructor. 1014 new (fShaderContext) SkZeroShaderContext(*fShader, rec); 1015 return false; 1016 } 1017 return true; 1018 } 1019