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 "SkMaskFilterBase.h" 17 #include "SkPaintPriv.h" 18 #include "SkRegionPriv.h" 19 #include "SkShaderBase.h" 20 #include "SkString.h" 21 #include "SkTLazy.h" 22 #include "SkUtils.h" 23 #include "SkXfermodeInterpretation.h" 24 25 SkBlitter::~SkBlitter() {} 26 27 bool SkBlitter::isNullBlitter() const { return false; } 28 29 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 30 return nullptr; 31 } 32 33 /* 34 void SkBlitter::blitH(int x, int y, int width) { 35 SkDEBUGFAIL("unimplemented"); 36 } 37 38 39 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 40 const int16_t runs[]) { 41 SkDEBUGFAIL("unimplemented"); 42 } 43 */ 44 45 inline static SkAlpha ScalarToAlpha(SkScalar a) { 46 SkAlpha alpha = (SkAlpha)(a * 255); 47 return alpha > 247 ? 0xFF : alpha < 8 ? 0 : alpha; 48 } 49 50 void SkBlitter::blitFatAntiRect(const SkRect& rect) { 51 SkIRect bounds = rect.roundOut(); 52 SkASSERT(bounds.width() >= 3 && bounds.height() >= 3); 53 54 int runSize = bounds.width() + 1; // +1 so we can set runs[bounds.width()] = 0 55 void* storage = this->allocBlitMemory(runSize * (sizeof(int16_t) + sizeof(SkAlpha))); 56 int16_t* runs = reinterpret_cast<int16_t*>(storage); 57 SkAlpha* alphas = reinterpret_cast<SkAlpha*>(runs + runSize); 58 59 runs[0] = 1; 60 runs[1] = bounds.width() - 2; 61 runs[bounds.width() - 1] = 1; 62 runs[bounds.width()] = 0; 63 64 SkScalar partialL = bounds.fLeft + 1 - rect.fLeft; 65 SkScalar partialR = rect.fRight - (bounds.fRight - 1); 66 SkScalar partialT = bounds.fTop + 1 - rect.fTop; 67 SkScalar partialB = rect.fBottom - (bounds.fBottom - 1); 68 69 alphas[0] = ScalarToAlpha(partialL * partialT); 70 alphas[1] = ScalarToAlpha(partialT); 71 alphas[bounds.width() - 1] = ScalarToAlpha(partialR * partialT); 72 this->blitAntiH(bounds.fLeft, bounds.fTop, alphas, runs); 73 74 this->blitAntiRect(bounds.fLeft, bounds.fTop + 1, bounds.width() - 2, bounds.height() - 2, 75 ScalarToAlpha(partialL), ScalarToAlpha(partialR)); 76 77 alphas[0] = ScalarToAlpha(partialL * partialB); 78 alphas[1] = ScalarToAlpha(partialB); 79 alphas[bounds.width() - 1] = ScalarToAlpha(partialR * partialB); 80 this->blitAntiH(bounds.fLeft, bounds.fBottom - 1, alphas, runs); 81 } 82 83 void SkBlitter::blitCoverageDeltas(SkCoverageDeltaList* deltas, const SkIRect& clip, 84 bool isEvenOdd, bool isInverse, bool isConvex, 85 SkArenaAlloc* alloc) { 86 // We cannot use blitter to allocate the storage because the same blitter might be used across 87 // many threads. 88 int runSize = clip.width() + 1; // +1 so we can set runs[clip.width()] = 0 89 int16_t* runs = alloc->makeArrayDefault<int16_t>(runSize); 90 SkAlpha* alphas = alloc->makeArrayDefault<SkAlpha>(runSize); 91 runs[clip.width()] = 0; // we must set the last run to 0 so blitAntiH can stop there 92 93 bool canUseMask = !deltas->forceRLE() && 94 SkCoverageDeltaMask::CanHandle(SkIRect::MakeLTRB(0, 0, clip.width(), 1)); 95 const SkAntiRect& antiRect = deltas->getAntiRect(); 96 97 // Only access rows within our clip. Otherwise, we'll have data race in the threaded backend. 98 int top = SkTMax(deltas->top(), clip.fTop); 99 int bottom = SkTMin(deltas->bottom(), clip.fBottom); 100 for(int y = top; y < bottom; ++y) { 101 // If antiRect is non-empty and we're at its top row, blit it and skip to the bottom 102 if (antiRect.fHeight && y == antiRect.fY) { 103 this->blitAntiRect(antiRect.fX, antiRect.fY, antiRect.fWidth, antiRect.fHeight, 104 antiRect.fLeftAlpha, antiRect.fRightAlpha); 105 y += antiRect.fHeight - 1; // -1 because ++y in the for loop 106 continue; 107 } 108 109 // If there are too many deltas, sorting will be slow. Using a mask is much faster. 110 // This is such an important optimization that will bring ~2x speedup for benches like 111 // path_fill_small_long_line and path_stroke_small_sawtooth. 112 if (canUseMask && !deltas->sorted(y) && deltas->count(y) << 3 >= clip.width()) { 113 SkIRect rowIR = SkIRect::MakeLTRB(clip.fLeft, y, clip.fRight, y + 1); 114 SkSTArenaAlloc<SkCoverageDeltaMask::MAX_SIZE> alloc; 115 SkCoverageDeltaMask mask(&alloc, rowIR); 116 for(int i = 0; i < deltas->count(y); ++i) { 117 const SkCoverageDelta& delta = deltas->getDelta(y, i); 118 mask.addDelta(delta.fX, y, delta.fDelta); 119 } 120 mask.convertCoverageToAlpha(isEvenOdd, isInverse, isConvex); 121 this->blitMask(mask.prepareSkMask(), rowIR); 122 continue; 123 } 124 125 // The normal flow of blitting deltas starts from here. First sort deltas. 126 deltas->sort(y); 127 128 int i = 0; // init delta index to 0 129 int lastX = clip.fLeft; // init x to clip.fLeft 130 SkFixed coverage = 0; // init coverage to 0 131 132 // skip deltas with x less than clip.fLeft; they must be precision errors 133 for(; i < deltas->count(y) && deltas->getDelta(y, i).fX < clip.fLeft; ++i); 134 for(; i < deltas->count(y) && deltas->getDelta(y, i).fX < clip.fRight; ++i) { 135 const SkCoverageDelta& delta = deltas->getDelta(y, i); 136 SkASSERT(delta.fX >= lastX); // delta must be x sorted 137 if (delta.fX > lastX) { // we have proceeded to a new x (different from lastX) 138 SkAlpha alpha = isConvex ? ConvexCoverageToAlpha(coverage, isInverse) 139 : CoverageToAlpha(coverage, isEvenOdd, isInverse); 140 alphas[lastX - clip.fLeft] = alpha; // set alpha at lastX 141 runs[lastX - clip.fLeft] = delta.fX - lastX; // set the run length 142 lastX = delta.fX; // now set lastX to current x 143 } 144 coverage += delta.fDelta; // cumulate coverage with the current delta 145 } 146 147 // Set the alpha and run length from the right-most delta to the right clip boundary 148 SkAlpha alpha = isConvex ? ConvexCoverageToAlpha(coverage, isInverse) 149 : CoverageToAlpha(coverage, isEvenOdd, isInverse); 150 alphas[lastX - clip.fLeft] = alpha; 151 runs[lastX - clip.fLeft] = clip.fRight - lastX; 152 153 this->blitAntiH(clip.fLeft, y, alphas, runs); // finally blit the current row 154 } 155 } 156 157 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 158 if (alpha == 255) { 159 this->blitRect(x, y, 1, height); 160 } else { 161 int16_t runs[2]; 162 runs[0] = 1; 163 runs[1] = 0; 164 165 while (--height >= 0) { 166 this->blitAntiH(x, y++, &alpha, runs); 167 } 168 } 169 } 170 171 void SkBlitter::blitRect(int x, int y, int width, int height) { 172 SkASSERT(width > 0); 173 while (--height >= 0) { 174 this->blitH(x, y++, width); 175 } 176 } 177 178 /// Default implementation doesn't check for easy optimizations 179 /// such as alpha == 255; also uses blitV(), which some subclasses 180 /// may not support. 181 void SkBlitter::blitAntiRect(int x, int y, int width, int height, 182 SkAlpha leftAlpha, SkAlpha rightAlpha) { 183 if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0 184 this->blitV(x, y, height, leftAlpha); 185 } 186 x++; 187 if (width > 0) { 188 this->blitRect(x, y, width, height); 189 x += width; 190 } 191 if (rightAlpha > 0) { 192 this->blitV(x, y, height, rightAlpha); 193 } 194 } 195 196 ////////////////////////////////////////////////////////////////////////////// 197 198 static inline void bits_to_runs(SkBlitter* blitter, int x, int y, 199 const uint8_t bits[], 200 uint8_t left_mask, ptrdiff_t rowBytes, 201 uint8_t right_mask) { 202 int inFill = 0; 203 int pos = 0; 204 205 while (--rowBytes >= 0) { 206 uint8_t b = *bits++ & left_mask; 207 if (rowBytes == 0) { 208 b &= right_mask; 209 } 210 211 for (uint8_t test = 0x80U; test != 0; test >>= 1) { 212 if (b & test) { 213 if (!inFill) { 214 pos = x; 215 inFill = true; 216 } 217 } else { 218 if (inFill) { 219 blitter->blitH(pos, y, x - pos); 220 inFill = false; 221 } 222 } 223 x += 1; 224 } 225 left_mask = 0xFFU; 226 } 227 228 // final cleanup 229 if (inFill) { 230 blitter->blitH(pos, y, x - pos); 231 } 232 } 233 234 // maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8. 235 static uint8_t generate_right_mask(int maskBitCount) { 236 return static_cast<uint8_t>(0xFF00U >> maskBitCount); 237 } 238 239 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 240 SkASSERT(mask.fBounds.contains(clip)); 241 242 if (mask.fFormat == SkMask::kLCD16_Format) { 243 return; // needs to be handled by subclass 244 } 245 246 if (mask.fFormat == SkMask::kBW_Format) { 247 int cx = clip.fLeft; 248 int cy = clip.fTop; 249 int maskLeft = mask.fBounds.fLeft; 250 int maskRowBytes = mask.fRowBytes; 251 int height = clip.height(); 252 253 const uint8_t* bits = mask.getAddr1(cx, cy); 254 255 SkDEBUGCODE(const uint8_t* endOfImage = 256 mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes 257 + ((mask.fBounds.width() + 7) >> 3)); 258 259 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 260 while (--height >= 0) { 261 int affectedRightBit = mask.fBounds.width() - 1; 262 ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1; 263 SkASSERT(bits + rowBytes <= endOfImage); 264 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 265 bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask); 266 bits += maskRowBytes; 267 cy += 1; 268 } 269 } else { 270 // Bits is calculated as the offset into the mask at the point {cx, cy} therefore, all 271 // addressing into the bit mask is relative to that point. Since this is an address 272 // calculated from a arbitrary bit in that byte, calculate the left most bit. 273 int bitsLeft = cx - ((cx - maskLeft) & 7); 274 275 // Everything is relative to the bitsLeft. 276 int leftEdge = cx - bitsLeft; 277 SkASSERT(leftEdge >= 0); 278 int rightEdge = clip.fRight - bitsLeft; 279 SkASSERT(rightEdge > leftEdge); 280 281 // Calculate left byte and mask 282 const uint8_t* leftByte = bits; 283 U8CPU leftMask = 0xFFU >> (leftEdge & 7); 284 285 // Calculate right byte and mask 286 int affectedRightBit = rightEdge - 1; 287 const uint8_t* rightByte = bits + (affectedRightBit >> 3); 288 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1); 289 290 // leftByte and rightByte are byte locations therefore, to get a count of bytes the 291 // code must add one. 292 ptrdiff_t rowBytes = rightByte - leftByte + 1; 293 294 while (--height >= 0) { 295 SkASSERT(bits + rowBytes <= endOfImage); 296 bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask); 297 bits += maskRowBytes; 298 cy += 1; 299 } 300 } 301 } else { 302 int width = clip.width(); 303 SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 304 int16_t* runs = runStorage.get(); 305 const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 306 307 sk_memset16((uint16_t*)runs, 1, width); 308 runs[width] = 0; 309 310 int height = clip.height(); 311 int y = clip.fTop; 312 while (--height >= 0) { 313 this->blitAntiH(clip.fLeft, y, aa, runs); 314 aa += mask.fRowBytes; 315 y += 1; 316 } 317 } 318 } 319 320 /////////////////////// these guys are not virtual, just a helpers 321 322 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 323 if (clip.quickReject(mask.fBounds)) { 324 return; 325 } 326 327 SkRegion::Cliperator clipper(clip, mask.fBounds); 328 329 while (!clipper.done()) { 330 const SkIRect& cr = clipper.rect(); 331 this->blitMask(mask, cr); 332 clipper.next(); 333 } 334 } 335 336 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 337 SkRegion::Cliperator clipper(clip, rect); 338 339 while (!clipper.done()) { 340 const SkIRect& cr = clipper.rect(); 341 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 342 clipper.next(); 343 } 344 } 345 346 void SkBlitter::blitRegion(const SkRegion& clip) { 347 SkRegionPriv::VisitSpans(clip, [this](const SkIRect& r) { 348 this->blitRect(r.left(), r.top(), r.width(), r.height()); 349 }); 350 } 351 352 /////////////////////////////////////////////////////////////////////////////// 353 354 void SkNullBlitter::blitH(int x, int y, int width) {} 355 356 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 357 const int16_t runs[]) {} 358 359 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 360 361 void SkNullBlitter::blitRect(int x, int y, int width, int height) {} 362 363 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 364 365 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 366 return nullptr; 367 } 368 369 bool SkNullBlitter::isNullBlitter() const { return true; } 370 371 /////////////////////////////////////////////////////////////////////////////// 372 373 static int compute_anti_width(const int16_t runs[]) { 374 int width = 0; 375 376 for (;;) { 377 int count = runs[0]; 378 379 SkASSERT(count >= 0); 380 if (count == 0) { 381 break; 382 } 383 width += count; 384 runs += count; 385 } 386 return width; 387 } 388 389 static inline bool y_in_rect(int y, const SkIRect& rect) { 390 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 391 } 392 393 static inline bool x_in_rect(int x, const SkIRect& rect) { 394 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 395 } 396 397 void SkRectClipBlitter::blitH(int left, int y, int width) { 398 SkASSERT(width > 0); 399 400 if (!y_in_rect(y, fClipRect)) { 401 return; 402 } 403 404 int right = left + width; 405 406 if (left < fClipRect.fLeft) { 407 left = fClipRect.fLeft; 408 } 409 if (right > fClipRect.fRight) { 410 right = fClipRect.fRight; 411 } 412 413 width = right - left; 414 if (width > 0) { 415 fBlitter->blitH(left, y, width); 416 } 417 } 418 419 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 420 const int16_t runs[]) { 421 if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 422 return; 423 } 424 425 int x0 = left; 426 int x1 = left + compute_anti_width(runs); 427 428 if (x1 <= fClipRect.fLeft) { 429 return; 430 } 431 432 SkASSERT(x0 < x1); 433 if (x0 < fClipRect.fLeft) { 434 int dx = fClipRect.fLeft - x0; 435 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 436 runs += dx; 437 aa += dx; 438 x0 = fClipRect.fLeft; 439 } 440 441 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 442 if (x1 > fClipRect.fRight) { 443 x1 = fClipRect.fRight; 444 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 445 ((int16_t*)runs)[x1 - x0] = 0; 446 } 447 448 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 449 SkASSERT(compute_anti_width(runs) == x1 - x0); 450 451 fBlitter->blitAntiH(x0, y, aa, runs); 452 } 453 454 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 455 SkASSERT(height > 0); 456 457 if (!x_in_rect(x, fClipRect)) { 458 return; 459 } 460 461 int y0 = y; 462 int y1 = y + height; 463 464 if (y0 < fClipRect.fTop) { 465 y0 = fClipRect.fTop; 466 } 467 if (y1 > fClipRect.fBottom) { 468 y1 = fClipRect.fBottom; 469 } 470 471 if (y0 < y1) { 472 fBlitter->blitV(x, y0, y1 - y0, alpha); 473 } 474 } 475 476 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 477 SkIRect r; 478 479 r.set(left, y, left + width, y + height); 480 if (r.intersect(fClipRect)) { 481 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 482 } 483 } 484 485 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 486 SkAlpha leftAlpha, SkAlpha rightAlpha) { 487 SkIRect r; 488 489 // The *true* width of the rectangle blitted is width+2: 490 r.set(left, y, left + width + 2, y + height); 491 if (r.intersect(fClipRect)) { 492 if (r.fLeft != left) { 493 SkASSERT(r.fLeft > left); 494 leftAlpha = 255; 495 } 496 if (r.fRight != left + width + 2) { 497 SkASSERT(r.fRight < left + width + 2); 498 rightAlpha = 255; 499 } 500 if (255 == leftAlpha && 255 == rightAlpha) { 501 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 502 } else if (1 == r.width()) { 503 if (r.fLeft == left) { 504 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 505 } else { 506 SkASSERT(r.fLeft == left + width + 1); 507 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 508 } 509 } else { 510 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 511 leftAlpha, rightAlpha); 512 } 513 } 514 } 515 516 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 517 SkASSERT(mask.fBounds.contains(clip)); 518 519 SkIRect r = clip; 520 521 if (r.intersect(fClipRect)) { 522 fBlitter->blitMask(mask, r); 523 } 524 } 525 526 const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 527 return fBlitter->justAnOpaqueColor(value); 528 } 529 530 /////////////////////////////////////////////////////////////////////////////// 531 532 void SkRgnClipBlitter::blitH(int x, int y, int width) { 533 SkRegion::Spanerator span(*fRgn, y, x, x + width); 534 int left, right; 535 536 while (span.next(&left, &right)) { 537 SkASSERT(left < right); 538 fBlitter->blitH(left, y, right - left); 539 } 540 } 541 542 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 543 const int16_t runs[]) { 544 int width = compute_anti_width(runs); 545 SkRegion::Spanerator span(*fRgn, y, x, x + width); 546 int left, right; 547 SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 548 549 int prevRite = x; 550 while (span.next(&left, &right)) { 551 SkASSERT(x <= left); 552 SkASSERT(left < right); 553 SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 554 555 SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 556 557 // now zero before left 558 if (left > prevRite) { 559 int index = prevRite - x; 560 ((uint8_t*)aa)[index] = 0; // skip runs after right 561 ((int16_t*)runs)[index] = SkToS16(left - prevRite); 562 } 563 564 prevRite = right; 565 } 566 567 if (prevRite > x) { 568 ((int16_t*)runs)[prevRite - x] = 0; 569 570 if (x < 0) { 571 int skip = runs[0]; 572 SkASSERT(skip >= -x); 573 aa += skip; 574 runs += skip; 575 x += skip; 576 } 577 fBlitter->blitAntiH(x, y, aa, runs); 578 } 579 } 580 581 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 582 SkIRect bounds; 583 bounds.set(x, y, x + 1, y + height); 584 585 SkRegion::Cliperator iter(*fRgn, bounds); 586 587 while (!iter.done()) { 588 const SkIRect& r = iter.rect(); 589 SkASSERT(bounds.contains(r)); 590 591 fBlitter->blitV(x, r.fTop, r.height(), alpha); 592 iter.next(); 593 } 594 } 595 596 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 597 SkIRect bounds; 598 bounds.set(x, y, x + width, y + height); 599 600 SkRegion::Cliperator iter(*fRgn, bounds); 601 602 while (!iter.done()) { 603 const SkIRect& r = iter.rect(); 604 SkASSERT(bounds.contains(r)); 605 606 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 607 iter.next(); 608 } 609 } 610 611 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 612 SkAlpha leftAlpha, SkAlpha rightAlpha) { 613 // The *true* width of the rectangle to blit is width + 2 614 SkIRect bounds; 615 bounds.set(x, y, x + width + 2, y + height); 616 617 SkRegion::Cliperator iter(*fRgn, bounds); 618 619 while (!iter.done()) { 620 const SkIRect& r = iter.rect(); 621 SkASSERT(bounds.contains(r)); 622 SkASSERT(r.fLeft >= x); 623 SkASSERT(r.fRight <= x + width + 2); 624 625 SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 626 SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 627 rightAlpha : 255; 628 629 if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 630 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 631 } else if (1 == r.width()) { 632 if (r.fLeft == x) { 633 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 634 effectiveLeftAlpha); 635 } else { 636 SkASSERT(r.fLeft == x + width + 1); 637 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 638 effectiveRightAlpha); 639 } 640 } else { 641 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 642 effectiveLeftAlpha, effectiveRightAlpha); 643 } 644 iter.next(); 645 } 646 } 647 648 649 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 650 SkASSERT(mask.fBounds.contains(clip)); 651 652 SkRegion::Cliperator iter(*fRgn, clip); 653 const SkIRect& r = iter.rect(); 654 SkBlitter* blitter = fBlitter; 655 656 while (!iter.done()) { 657 blitter->blitMask(mask, r); 658 iter.next(); 659 } 660 } 661 662 const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 663 return fBlitter->justAnOpaqueColor(value); 664 } 665 666 /////////////////////////////////////////////////////////////////////////////// 667 668 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 669 const SkIRect* ir) { 670 if (clip) { 671 const SkIRect& clipR = clip->getBounds(); 672 673 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 674 blitter = &fNullBlitter; 675 } else if (clip->isRect()) { 676 if (ir == nullptr || !clipR.contains(*ir)) { 677 fRectBlitter.init(blitter, clipR); 678 blitter = &fRectBlitter; 679 } 680 } else { 681 fRgnBlitter.init(blitter, clip); 682 blitter = &fRgnBlitter; 683 } 684 } 685 return blitter; 686 } 687 688 /////////////////////////////////////////////////////////////////////////////// 689 690 #include "SkColorShader.h" 691 #include "SkColorData.h" 692 693 class Sk3DShader : public SkShaderBase { 694 public: 695 Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {} 696 697 Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override { 698 SkShaderBase::Context* proxyContext = nullptr; 699 if (fProxy) { 700 proxyContext = as_SB(fProxy)->makeContext(rec, alloc); 701 if (!proxyContext) { 702 return nullptr; 703 } 704 } 705 return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext); 706 } 707 708 class Sk3DShaderContext : public Context { 709 public: 710 // Calls proxyContext's destructor but will NOT free its memory. 711 Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, 712 Context* proxyContext) 713 : INHERITED(shader, rec) 714 , fMask(nullptr) 715 , fProxyContext(proxyContext) 716 { 717 if (!fProxyContext) { 718 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); 719 } 720 } 721 722 ~Sk3DShaderContext() override = default; 723 724 void set3DMask(const SkMask* mask) override { fMask = mask; } 725 726 void shadeSpan(int x, int y, SkPMColor span[], int count) override { 727 if (fProxyContext) { 728 fProxyContext->shadeSpan(x, y, span, count); 729 } 730 731 if (fMask == nullptr) { 732 if (fProxyContext == nullptr) { 733 sk_memset32(span, fPMColor, count); 734 } 735 return; 736 } 737 738 SkASSERT(fMask->fBounds.contains(x, y)); 739 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 740 741 size_t size = fMask->computeImageSize(); 742 const uint8_t* alpha = fMask->getAddr8(x, y); 743 const uint8_t* mulp = alpha + size; 744 const uint8_t* addp = mulp + size; 745 746 if (fProxyContext) { 747 for (int i = 0; i < count; i++) { 748 if (alpha[i]) { 749 SkPMColor c = span[i]; 750 if (c) { 751 unsigned a = SkGetPackedA32(c); 752 unsigned r = SkGetPackedR32(c); 753 unsigned g = SkGetPackedG32(c); 754 unsigned b = SkGetPackedB32(c); 755 756 unsigned mul = SkAlpha255To256(mulp[i]); 757 unsigned add = addp[i]; 758 759 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 760 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 761 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 762 763 span[i] = SkPackARGB32(a, r, g, b); 764 } 765 } else { 766 span[i] = 0; 767 } 768 } 769 } else { // color 770 unsigned a = SkGetPackedA32(fPMColor); 771 unsigned r = SkGetPackedR32(fPMColor); 772 unsigned g = SkGetPackedG32(fPMColor); 773 unsigned b = SkGetPackedB32(fPMColor); 774 for (int i = 0; i < count; i++) { 775 if (alpha[i]) { 776 unsigned mul = SkAlpha255To256(mulp[i]); 777 unsigned add = addp[i]; 778 779 span[i] = SkPackARGB32( a, 780 SkFastMin32(SkAlphaMul(r, mul) + add, a), 781 SkFastMin32(SkAlphaMul(g, mul) + add, a), 782 SkFastMin32(SkAlphaMul(b, mul) + add, a)); 783 } else { 784 span[i] = 0; 785 } 786 } 787 } 788 } 789 790 private: 791 // Unowned. 792 const SkMask* fMask; 793 // Memory is unowned. 794 Context* fProxyContext; 795 SkPMColor fPMColor; 796 797 typedef Context INHERITED; 798 }; 799 800 #ifndef SK_IGNORE_TO_STRING 801 void toString(SkString* str) const override { 802 str->append("Sk3DShader: ("); 803 804 if (fProxy) { 805 str->append("Proxy: "); 806 as_SB(fProxy)->toString(str); 807 } 808 809 this->INHERITED::toString(str); 810 811 str->append(")"); 812 } 813 #endif 814 815 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader) 816 817 protected: 818 void flatten(SkWriteBuffer& buffer) const override { 819 buffer.writeFlattenable(fProxy.get()); 820 } 821 822 private: 823 sk_sp<SkShader> fProxy; 824 825 typedef SkShaderBase INHERITED; 826 }; 827 828 sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) { 829 return sk_make_sp<Sk3DShader>(buffer.readShader()); 830 } 831 832 class Sk3DBlitter : public SkBlitter { 833 public: 834 Sk3DBlitter(SkBlitter* proxy, SkShaderBase::Context* shaderContext) 835 : fProxy(proxy) 836 , fShaderContext(shaderContext) 837 {} 838 839 void blitH(int x, int y, int width) override { 840 fProxy->blitH(x, y, width); 841 } 842 843 void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override { 844 fProxy->blitAntiH(x, y, antialias, runs); 845 } 846 847 void blitV(int x, int y, int height, SkAlpha alpha) override { 848 fProxy->blitV(x, y, height, alpha); 849 } 850 851 void blitRect(int x, int y, int width, int height) override { 852 fProxy->blitRect(x, y, width, height); 853 } 854 855 void blitMask(const SkMask& mask, const SkIRect& clip) override { 856 if (mask.fFormat == SkMask::k3D_Format) { 857 fShaderContext->set3DMask(&mask); 858 859 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 860 fProxy->blitMask(mask, clip); 861 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 862 863 fShaderContext->set3DMask(nullptr); 864 } else { 865 fProxy->blitMask(mask, clip); 866 } 867 } 868 869 private: 870 // Both pointers are unowned. They will be deleted by SkSmallAllocator. 871 SkBlitter* fProxy; 872 SkShaderBase::Context* fShaderContext; 873 }; 874 875 /////////////////////////////////////////////////////////////////////////////// 876 877 #include "SkCoreBlitters.h" 878 879 SkShaderBase::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { 880 return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) 881 ? SkShaderBase::ContextRec::kPM4f_DstType 882 : SkShaderBase::ContextRec::kPMColor_DstType; 883 } 884 885 // hack for testing, not to be exposed to clients 886 bool gSkForceRasterPipelineBlitter; 887 888 bool SkBlitter::UseRasterPipelineBlitter(const SkPixmap& device, const SkPaint& paint, 889 const SkMatrix& matrix) { 890 if (gSkForceRasterPipelineBlitter) { 891 return true; 892 } 893 if (device.info().alphaType() == kUnpremul_SkAlphaType) { 894 return true; 895 } 896 #if 0 || defined(SK_FORCE_RASTER_PIPELINE_BLITTER) 897 return true; 898 #else 899 // By policy we choose not to handle legacy 8888 with SkRasterPipelineBlitter. 900 if (device.colorSpace()) { 901 return true; 902 } 903 if (paint.getColorFilter()) { 904 return true; 905 } 906 if (paint.getFilterQuality() == kHigh_SkFilterQuality) { 907 return true; 908 } 909 // ... unless the blend mode is complicated enough. 910 if (paint.getBlendMode() > SkBlendMode::kLastSeparableMode) { 911 return true; 912 } 913 if (matrix.hasPerspective()) { 914 return true; 915 } 916 // ... or unless the shader is raster pipeline-only. 917 if (paint.getShader() && as_SB(paint.getShader())->isRasterPipelineOnly(matrix)) { 918 return true; 919 } 920 921 // Added support only for shaders (and other constraints) for android 922 if (device.colorType() == kRGB_565_SkColorType) { 923 return false; 924 } 925 926 return device.colorType() != kN32_SkColorType; 927 #endif 928 } 929 930 SkBlitter* SkBlitter::Choose(const SkPixmap& device, 931 const SkMatrix& matrix, 932 const SkPaint& origPaint, 933 SkArenaAlloc* alloc, 934 bool drawCoverage) { 935 SkASSERT(alloc != nullptr); 936 937 // which check, in case we're being called by a client with a dummy device 938 // (e.g. they have a bounder that always aborts the draw) 939 if (kUnknown_SkColorType == device.colorType() || 940 (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { 941 return alloc->make<SkNullBlitter>(); 942 } 943 944 auto* shader = as_SB(origPaint.getShader()); 945 SkColorFilter* cf = origPaint.getColorFilter(); 946 SkBlendMode mode = origPaint.getBlendMode(); 947 sk_sp<Sk3DShader> shader3D; 948 949 SkTCopyOnFirstWrite<SkPaint> paint(origPaint); 950 951 if (origPaint.getMaskFilter() != nullptr && 952 as_MFB(origPaint.getMaskFilter())->getFormat() == SkMask::k3D_Format) { 953 shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader)); 954 // we know we haven't initialized lazyPaint yet, so just do it 955 paint.writable()->setShader(shader3D); 956 shader = as_SB(shader3D.get()); 957 } 958 959 if (mode != SkBlendMode::kSrcOver) { 960 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); 961 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { 962 case kSrcOver_SkXfermodeInterpretation: 963 mode = SkBlendMode::kSrcOver; 964 paint.writable()->setBlendMode(mode); 965 break; 966 case kSkipDrawing_SkXfermodeInterpretation:{ 967 return alloc->make<SkNullBlitter>(); 968 } 969 default: 970 break; 971 } 972 } 973 974 /* 975 * If the xfermode is CLEAR, then we can completely ignore the installed 976 * color/shader/colorfilter, and just pretend we're SRC + color==0. This 977 * will fall into our optimizations for SRC mode. 978 */ 979 if (mode == SkBlendMode::kClear) { 980 SkPaint* p = paint.writable(); 981 p->setShader(nullptr); 982 shader = nullptr; 983 p->setColorFilter(nullptr); 984 cf = nullptr; 985 p->setBlendMode(mode = SkBlendMode::kSrc); 986 p->setColor(0); 987 } 988 989 if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) { 990 SkASSERT(nullptr == shader); 991 SkASSERT(paint->isSrcOver()); 992 return alloc->make<SkA8_Coverage_Blitter>(device, *paint); 993 } 994 995 if (paint->isDither() && !SkPaintPriv::ShouldDither(*paint, device.colorType())) { 996 // Disable dithering when not needed. 997 paint.writable()->setDither(false); 998 } 999 1000 if (UseRasterPipelineBlitter(device, *paint, matrix)) { 1001 auto blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc); 1002 SkASSERT(blitter); 1003 return blitter; 1004 } 1005 1006 if (nullptr == shader) { 1007 if (mode != SkBlendMode::kSrcOver) { 1008 // xfermodes (and filters) require shaders for our current blitters 1009 paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor())); 1010 paint.writable()->setAlpha(0xFF); 1011 shader = as_SB(paint->getShader()); 1012 } else if (cf) { 1013 // if no shader && no xfermode, we just apply the colorfilter to 1014 // our color and move on. 1015 SkPaint* writablePaint = paint.writable(); 1016 writablePaint->setColor(cf->filterColor(paint->getColor())); 1017 writablePaint->setColorFilter(nullptr); 1018 cf = nullptr; 1019 } 1020 } 1021 1022 if (cf) { 1023 SkASSERT(shader); 1024 paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf))); 1025 shader = as_SB(paint->getShader()); 1026 // blitters should ignore the presence/absence of a filter, since 1027 // if there is one, the shader will take care of it. 1028 } 1029 1030 /* 1031 * We create a SkShader::Context object, and store it on the blitter. 1032 */ 1033 SkShaderBase::Context* shaderContext = nullptr; 1034 if (shader) { 1035 const SkShaderBase::ContextRec rec(*paint, matrix, nullptr, 1036 PreferredShaderDest(device.info()), 1037 device.colorSpace()); 1038 // Try to create the ShaderContext 1039 shaderContext = shader->makeContext(rec, alloc); 1040 if (!shaderContext) { 1041 return alloc->make<SkNullBlitter>(); 1042 } 1043 SkASSERT(shaderContext); 1044 } 1045 1046 SkBlitter* blitter = nullptr; 1047 switch (device.colorType()) { 1048 case kN32_SkColorType: 1049 // sRGB and general color spaces are handled via raster pipeline. 1050 SkASSERT(!device.colorSpace()); 1051 1052 if (shader) { 1053 blitter = alloc->make<SkARGB32_Shader_Blitter>(device, *paint, shaderContext); 1054 } else if (paint->getColor() == SK_ColorBLACK) { 1055 blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint); 1056 } else if (paint->getAlpha() == 0xFF) { 1057 blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint); 1058 } else { 1059 blitter = alloc->make<SkARGB32_Blitter>(device, *paint); 1060 } 1061 break; 1062 case kRGB_565_SkColorType: 1063 if (shader && SkRGB565_Shader_Blitter::Supports(device, *paint)) { 1064 blitter = alloc->make<SkRGB565_Shader_Blitter>(device, *paint, shaderContext); 1065 } else { 1066 blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc); 1067 } 1068 break; 1069 1070 default: 1071 // should have been handled via raster pipeline. 1072 SkASSERT(false); 1073 break; 1074 } 1075 1076 if (!blitter) { 1077 blitter = alloc->make<SkNullBlitter>(); 1078 } 1079 1080 if (shader3D) { 1081 SkBlitter* innerBlitter = blitter; 1082 // FIXME - comment about allocator 1083 // innerBlitter was allocated by allocator, which will delete it. 1084 // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to 1085 // wrapper the blitter to notify it when we see an emboss mask. 1086 blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext); 1087 } 1088 return blitter; 1089 } 1090 1091 /////////////////////////////////////////////////////////////////////////////// 1092 1093 SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, 1094 SkShaderBase::Context* shaderContext) 1095 : INHERITED(device) 1096 , fShader(paint.getShader()) 1097 , fShaderContext(shaderContext) { 1098 SkASSERT(fShader); 1099 SkASSERT(fShaderContext); 1100 1101 fShader->ref(); 1102 fShaderFlags = fShaderContext->getFlags(); 1103 fConstInY = SkToBool(fShaderFlags & SkShaderBase::kConstInY32_Flag); 1104 } 1105 1106 SkShaderBlitter::~SkShaderBlitter() { 1107 fShader->unref(); 1108 } 1109 1110 /////////////////////////////////////////////////////////////////////////////////////////////////// 1111 1112 #ifdef SK_DEBUG 1113 1114 void SkRectClipCheckBlitter::blitH(int x, int y, int width) { 1115 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 1116 fBlitter->blitH(x, y, width); 1117 } 1118 1119 void SkRectClipCheckBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) { 1120 const int16_t* iter = runs; 1121 for (; *iter; iter += *iter) 1122 ; 1123 int width = iter - runs; 1124 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1))); 1125 fBlitter->blitAntiH(x, y, aa, runs); 1126 } 1127 1128 void SkRectClipCheckBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1129 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, height))); 1130 fBlitter->blitV(x, y, height, alpha); 1131 } 1132 1133 void SkRectClipCheckBlitter::blitRect(int x, int y, int width, int height) { 1134 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, height))); 1135 fBlitter->blitRect(x, y, width, height); 1136 } 1137 1138 void SkRectClipCheckBlitter::blitAntiRect(int x, int y, int width, int height, 1139 SkAlpha leftAlpha, SkAlpha rightAlpha) { 1140 bool skipLeft = !leftAlpha; 1141 bool skipRight = !rightAlpha; 1142 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x + skipLeft, y, 1143 width + 2 - skipRight - skipLeft, height))); 1144 fBlitter->blitAntiRect(x, y, width, height, leftAlpha, rightAlpha); 1145 } 1146 1147 void SkRectClipCheckBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 1148 SkASSERT(mask.fBounds.contains(clip)); 1149 SkASSERT(fClipRect.contains(clip)); 1150 fBlitter->blitMask(mask, clip); 1151 } 1152 1153 const SkPixmap* SkRectClipCheckBlitter::justAnOpaqueColor(uint32_t* value) { 1154 return fBlitter->justAnOpaqueColor(value); 1155 } 1156 1157 void SkRectClipCheckBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) { 1158 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 2, 1))); 1159 fBlitter->blitAntiH2(x, y, a0, a1); 1160 } 1161 1162 void SkRectClipCheckBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) { 1163 SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, 2))); 1164 fBlitter->blitAntiV2(x, y, a0, a1); 1165 } 1166 1167 #endif 1168