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 "SkArenaAlloc.h" 9#include "SkBlitter.h" 10#include "SkAntiRun.h" 11#include "SkColor.h" 12#include "SkColorFilter.h" 13#include "SkReadBuffer.h" 14#include "SkWriteBuffer.h" 15#include "SkMask.h" 16#include "SkMaskFilter.h" 17#include "SkString.h" 18#include "SkTLazy.h" 19#include "SkUtils.h" 20#include "SkXfermodeInterpretation.h" 21 22// define this for testing srgb blits 23//#define SK_FORCE_PM4f_FOR_L32_BLITS 24 25SkBlitter::~SkBlitter() {} 26 27bool SkBlitter::isNullBlitter() const { return false; } 28 29const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 30 return nullptr; 31} 32 33/* 34void SkBlitter::blitH(int x, int y, int width) { 35 SkDEBUGFAIL("unimplemented"); 36} 37 38 39void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 40 const int16_t runs[]) { 41 SkDEBUGFAIL("unimplemented"); 42} 43 */ 44 45void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 46 if (alpha == 255) { 47 this->blitRect(x, y, 1, height); 48 } else { 49 int16_t runs[2]; 50 runs[0] = 1; 51 runs[1] = 0; 52 53 while (--height >= 0) { 54 this->blitAntiH(x, y++, &alpha, runs); 55 } 56 } 57} 58 59void SkBlitter::blitRect(int x, int y, int width, int height) { 60 SkASSERT(width > 0); 61 while (--height >= 0) { 62 this->blitH(x, y++, width); 63 } 64} 65 66/// Default implementation doesn't check for easy optimizations 67/// such as alpha == 255; also uses blitV(), which some subclasses 68/// may not support. 69void SkBlitter::blitAntiRect(int x, int y, int width, int height, 70 SkAlpha leftAlpha, SkAlpha rightAlpha) { 71 if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0 72 this->blitV(x, y, height, leftAlpha); 73 } 74 x++; 75 if (width > 0) { 76 this->blitRect(x, y, width, height); 77 x += width; 78 } 79 if (rightAlpha > 0) { 80 this->blitV(x, y, height, rightAlpha); 81 } 82} 83 84////////////////////////////////////////////////////////////////////////////// 85 86static 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. 123static uint8_t generate_right_mask(int maskBitCount) { 124 return static_cast<uint8_t>(0xFF00U >> maskBitCount); 125} 126 127void 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} therefore, 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 210void 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 224void 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 234void 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 246void SkNullBlitter::blitH(int x, int y, int width) {} 247 248void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 249 const int16_t runs[]) {} 250 251void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 252 253void SkNullBlitter::blitRect(int x, int y, int width, int height) {} 254 255void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 256 257const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 258 return nullptr; 259} 260 261bool SkNullBlitter::isNullBlitter() const { return true; } 262 263/////////////////////////////////////////////////////////////////////////////// 264 265static 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 281static inline bool y_in_rect(int y, const SkIRect& rect) { 282 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 283} 284 285static inline bool x_in_rect(int x, const SkIRect& rect) { 286 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 287} 288 289void 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 311void 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 346void 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 368void 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 377void 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 408void 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 418const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 419 return fBlitter->justAnOpaqueColor(value); 420} 421 422/////////////////////////////////////////////////////////////////////////////// 423 424void 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 434void 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 473void 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 488void 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 503void 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 541void 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 554const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 555 return fBlitter->justAnOpaqueColor(value); 556} 557 558/////////////////////////////////////////////////////////////////////////////// 559 560SkBlitter* 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 585class Sk3DShader : public SkShader { 586public: 587 Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {} 588 589 Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override { 590 SkShader::Context* proxyContext = nullptr; 591 if (fProxy) { 592 proxyContext = fProxy->makeContext(rec, alloc); 593 if (!proxyContext) { 594 return nullptr; 595 } 596 } 597 return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext); 598 } 599 600 class Sk3DShaderContext : public SkShader::Context { 601 public: 602 // Calls proxyContext's destructor but will NOT free its memory. 603 Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, 604 SkShader::Context* proxyContext) 605 : INHERITED(shader, rec) 606 , fMask(nullptr) 607 , fProxyContext(proxyContext) 608 { 609 if (!fProxyContext) { 610 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); 611 } 612 } 613 614 ~Sk3DShaderContext() override { 615 if (fProxyContext) { 616 fProxyContext->~Context(); 617 } 618 } 619 620 void set3DMask(const SkMask* mask) override { fMask = mask; } 621 622 void shadeSpan(int x, int y, SkPMColor span[], int count) override { 623 if (fProxyContext) { 624 fProxyContext->shadeSpan(x, y, span, count); 625 } 626 627 if (fMask == nullptr) { 628 if (fProxyContext == nullptr) { 629 sk_memset32(span, fPMColor, count); 630 } 631 return; 632 } 633 634 SkASSERT(fMask->fBounds.contains(x, y)); 635 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 636 637 size_t size = fMask->computeImageSize(); 638 const uint8_t* alpha = fMask->getAddr8(x, y); 639 const uint8_t* mulp = alpha + size; 640 const uint8_t* addp = mulp + size; 641 642 if (fProxyContext) { 643 for (int i = 0; i < count; i++) { 644 if (alpha[i]) { 645 SkPMColor c = span[i]; 646 if (c) { 647 unsigned a = SkGetPackedA32(c); 648 unsigned r = SkGetPackedR32(c); 649 unsigned g = SkGetPackedG32(c); 650 unsigned b = SkGetPackedB32(c); 651 652 unsigned mul = SkAlpha255To256(mulp[i]); 653 unsigned add = addp[i]; 654 655 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 656 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 657 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 658 659 span[i] = SkPackARGB32(a, r, g, b); 660 } 661 } else { 662 span[i] = 0; 663 } 664 } 665 } else { // color 666 unsigned a = SkGetPackedA32(fPMColor); 667 unsigned r = SkGetPackedR32(fPMColor); 668 unsigned g = SkGetPackedG32(fPMColor); 669 unsigned b = SkGetPackedB32(fPMColor); 670 for (int i = 0; i < count; i++) { 671 if (alpha[i]) { 672 unsigned mul = SkAlpha255To256(mulp[i]); 673 unsigned add = addp[i]; 674 675 span[i] = SkPackARGB32( a, 676 SkFastMin32(SkAlphaMul(r, mul) + add, a), 677 SkFastMin32(SkAlphaMul(g, mul) + add, a), 678 SkFastMin32(SkAlphaMul(b, mul) + add, a)); 679 } else { 680 span[i] = 0; 681 } 682 } 683 } 684 } 685 686 private: 687 // Unowned. 688 const SkMask* fMask; 689 // Memory is unowned, but we need to call the destructor. 690 SkShader::Context* fProxyContext; 691 SkPMColor fPMColor; 692 693 typedef SkShader::Context INHERITED; 694 }; 695 696#ifndef SK_IGNORE_TO_STRING 697 void toString(SkString* str) const override { 698 str->append("Sk3DShader: ("); 699 700 if (fProxy) { 701 str->append("Proxy: "); 702 fProxy->toString(str); 703 } 704 705 this->INHERITED::toString(str); 706 707 str->append(")"); 708 } 709#endif 710 711 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 712 713protected: 714 void flatten(SkWriteBuffer& buffer) const override { 715 buffer.writeFlattenable(fProxy.get()); 716 } 717 718private: 719 sk_sp<SkShader> fProxy; 720 721 typedef SkShader INHERITED; 722}; 723 724sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) { 725 return sk_make_sp<Sk3DShader>(buffer.readShader()); 726} 727 728class Sk3DBlitter : public SkBlitter { 729public: 730 Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext) 731 : fProxy(proxy) 732 , fShaderContext(shaderContext) 733 {} 734 735 void blitH(int x, int y, int width) override { 736 fProxy->blitH(x, y, width); 737 } 738 739 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override { 740 fProxy->blitAntiH(x, y, antialias, runs); 741 } 742 743 void blitV(int x, int y, int height, SkAlpha alpha) override { 744 fProxy->blitV(x, y, height, alpha); 745 } 746 747 void blitRect(int x, int y, int width, int height) override { 748 fProxy->blitRect(x, y, width, height); 749 } 750 751 void blitMask(const SkMask& mask, const SkIRect& clip) override { 752 if (mask.fFormat == SkMask::k3D_Format) { 753 fShaderContext->set3DMask(&mask); 754 755 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 756 fProxy->blitMask(mask, clip); 757 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 758 759 fShaderContext->set3DMask(nullptr); 760 } else { 761 fProxy->blitMask(mask, clip); 762 } 763 } 764 765private: 766 // Both pointers are unowned. They will be deleted by SkSmallAllocator. 767 SkBlitter* fProxy; 768 SkShader::Context* fShaderContext; 769}; 770 771/////////////////////////////////////////////////////////////////////////////// 772 773#include "SkCoreBlitters.h" 774 775SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { 776#ifdef SK_FORCE_PM4f_FOR_L32_BLITS 777 return SkShader::ContextRec::kPM4f_DstType; 778#else 779 return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) 780 ? SkShader::ContextRec::kPM4f_DstType 781 : SkShader::ContextRec::kPMColor_DstType; 782#endif 783} 784 785SkBlitter* SkBlitter::Choose(const SkPixmap& device, 786 const SkMatrix& matrix, 787 const SkPaint& origPaint, 788 SkArenaAlloc* alloc, 789 bool drawCoverage) { 790 SkASSERT(alloc != nullptr); 791 792 // which check, in case we're being called by a client with a dummy device 793 // (e.g. they have a bounder that always aborts the draw) 794 if (kUnknown_SkColorType == device.colorType() || 795 (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { 796 return alloc->make<SkNullBlitter>(); 797 } 798 799 SkShader* shader = origPaint.getShader(); 800 SkColorFilter* cf = origPaint.getColorFilter(); 801 SkBlendMode mode = origPaint.getBlendMode(); 802 sk_sp<Sk3DShader> shader3D; 803 804 SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 805 806 if (origPaint.getMaskFilter() != nullptr && 807 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 808 shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader)); 809 // we know we haven't initialized lazyPaint yet, so just do it 810 paint.writable()->setShader(shader3D); 811 shader = shader3D.get(); 812 } 813 814 if (mode != SkBlendMode::kSrcOver) { 815 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); 816 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { 817 case kSrcOver_SkXfermodeInterpretation: 818 mode = SkBlendMode::kSrcOver; 819 paint.writable()->setBlendMode(mode); 820 break; 821 case kSkipDrawing_SkXfermodeInterpretation:{ 822 return alloc->make<SkNullBlitter>(); 823 } 824 default: 825 break; 826 } 827 } 828 829 /* 830 * If the xfermode is CLEAR, then we can completely ignore the installed 831 * color/shader/colorfilter, and just pretend we're SRC + color==0. This 832 * will fall into our optimizations for SRC mode. 833 */ 834 if (mode == SkBlendMode::kClear) { 835 SkPaint* p = paint.writable(); 836 p->setShader(nullptr); 837 shader = nullptr; 838 p->setColorFilter(nullptr); 839 cf = nullptr; 840 p->setBlendMode(mode = SkBlendMode::kSrc); 841 p->setColor(0); 842 } 843 844 if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) { 845 SkASSERT(nullptr == shader); 846 SkASSERT(paint->isSrcOver()); 847 return alloc->make<SkA8_Coverage_Blitter>(device, *paint); 848 } 849 850 if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) { 851 return blitter; 852 } 853 854 if (nullptr == shader) { 855 if (mode != SkBlendMode::kSrcOver) { 856 // xfermodes (and filters) require shaders for our current blitters 857 paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor())); 858 paint.writable()->setAlpha(0xFF); 859 shader = paint->getShader(); 860 } else if (cf) { 861 // if no shader && no xfermode, we just apply the colorfilter to 862 // our color and move on. 863 SkPaint* writablePaint = paint.writable(); 864 writablePaint->setColor(cf->filterColor(paint->getColor())); 865 writablePaint->setColorFilter(nullptr); 866 cf = nullptr; 867 } 868 } 869 870 if (cf) { 871 SkASSERT(shader); 872 paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf))); 873 shader = paint->getShader(); 874 // blitters should ignore the presence/absence of a filter, since 875 // if there is one, the shader will take care of it. 876 } 877 878 /* 879 * We create a SkShader::Context object, and store it on the blitter. 880 */ 881 SkShader::Context* shaderContext = nullptr; 882 if (shader) { 883 const SkShader::ContextRec rec(*paint, matrix, nullptr, 884 PreferredShaderDest(device.info()), 885 device.colorSpace()); 886 // Try to create the ShaderContext 887 shaderContext = shader->makeContext(rec, alloc); 888 if (!shaderContext) { 889 return alloc->make<SkNullBlitter>(); 890 } 891 SkASSERT(shaderContext); 892 } 893 894 SkBlitter* blitter = nullptr; 895 switch (device.colorType()) { 896 case kAlpha_8_SkColorType: 897 SkASSERT(!drawCoverage); // Handled above. 898 if (shader) { 899 blitter = alloc->make<SkA8_Shader_Blitter>(device, *paint, shaderContext); 900 } else { 901 blitter = alloc->make<SkA8_Blitter>(device, *paint); 902 } 903 break; 904 905 case kRGB_565_SkColorType: 906 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloc); 907 break; 908 909 case kN32_SkColorType: 910#ifdef SK_FORCE_PM4f_FOR_L32_BLITS 911 if (true) 912#else 913 if (device.info().gammaCloseToSRGB()) 914#endif 915 { 916 blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, alloc); 917 } else { 918 if (shader) { 919 blitter = alloc->make<SkARGB32_Shader_Blitter>( 920 device, *paint, shaderContext); 921 } else if (paint->getColor() == SK_ColorBLACK) { 922 blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint); 923 } else if (paint->getAlpha() == 0xFF) { 924 blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint); 925 } else { 926 blitter = alloc->make<SkARGB32_Blitter>(device, *paint); 927 } 928 } 929 break; 930 931 case kRGBA_F16_SkColorType: 932 blitter = SkBlitter_F16_Create(device, *paint, shaderContext, alloc); 933 break; 934 935 default: 936 break; 937 } 938 939 if (!blitter) { 940 blitter = alloc->make<SkNullBlitter>(); 941 } 942 943 if (shader3D) { 944 SkBlitter* innerBlitter = blitter; 945 // FIXME - comment about allocator 946 // innerBlitter was allocated by allocator, which will delete it. 947 // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to 948 // wrapper the blitter to notify it when we see an emboss mask. 949 blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext); 950 } 951 return blitter; 952} 953 954/////////////////////////////////////////////////////////////////////////////// 955 956class SkZeroShaderContext : public SkShader::Context { 957public: 958 SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) 959 // Override rec with the identity matrix, so it is guaranteed to be invertible. 960 : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr, 961 rec.fPreferredDstType, rec.fDstColorSpace)) {} 962 963 void shadeSpan(int x, int y, SkPMColor colors[], int count) override { 964 sk_bzero(colors, count * sizeof(SkPMColor)); 965 } 966 967private: 968 typedef SkShader::Context INHERITED; 969}; 970 971SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, 972 SkShader::Context* shaderContext) 973 : INHERITED(device) 974 , fShader(paint.getShader()) 975 , fShaderContext(shaderContext) { 976 SkASSERT(fShader); 977 SkASSERT(fShaderContext); 978 979 fShader->ref(); 980 fShaderFlags = fShaderContext->getFlags(); 981 fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag); 982} 983 984SkShaderBlitter::~SkShaderBlitter() { 985 fShader->unref(); 986} 987 988/////////////////////////////////////////////////////////////////////////////////////////////////// 989 990#ifdef SK_DEBUG 991 992void SkRectClipCheckBlitter::blitH(int x, int y, int width) { 993 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 994 fBlitter->blitH(x, y, width); 995} 996 997void SkRectClipCheckBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) { 998 const int16_t* iter = runs; 999 for (; *iter; iter += *iter) 1000 ; 1001 int width = iter - runs; 1002 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 1003 fBlitter->blitAntiH(x, y, aa, runs); 1004} 1005 1006void SkRectClipCheckBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1007 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, height))); 1008 fBlitter->blitV(x, y, height, alpha); 1009} 1010 1011void SkRectClipCheckBlitter::blitRect(int x, int y, int width, int height) { 1012 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, height))); 1013 fBlitter->blitRect(x, y, width, height); 1014} 1015 1016void SkRectClipCheckBlitter::blitAntiRect(int x, int y, int width, int height, 1017 SkAlpha leftAlpha, SkAlpha rightAlpha) { 1018 bool skipLeft = !leftAlpha; 1019 bool skipRight = !rightAlpha; 1020 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x + skipLeft, y, 1021 width + 2 - skipRight - skipLeft, height))); 1022 fBlitter->blitAntiRect(x, y, width, height, leftAlpha, rightAlpha); 1023} 1024 1025void SkRectClipCheckBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1026 SkASSERT(mask.fBounds.contains(clip)); 1027 SkASSERT(fClipRect.contains(clip)); 1028 fBlitter->blitMask(mask, clip); 1029} 1030 1031const SkPixmap* SkRectClipCheckBlitter::justAnOpaqueColor(uint32_t* value) { 1032 return fBlitter->justAnOpaqueColor(value); 1033} 1034 1035void SkRectClipCheckBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 1036 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 2, 1))); 1037 fBlitter->blitAntiH2(x, y, a0, a1); 1038} 1039 1040void SkRectClipCheckBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 1041 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, 2))); 1042 fBlitter->blitAntiV2(x, y, a0, a1); 1043} 1044 1045#endif 1046