1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkBlitter.h" 11 #include "SkAntiRun.h" 12 #include "SkColor.h" 13 #include "SkColorFilter.h" 14 #include "SkMask.h" 15 #include "SkMaskFilter.h" 16 #include "SkTemplatesPriv.h" 17 #include "SkUtils.h" 18 #include "SkXfermode.h" 19 20 SkBlitter::~SkBlitter() {} 21 22 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { 23 return NULL; 24 } 25 26 void SkBlitter::blitH(int x, int y, int width) { 27 SkDEBUGFAIL("unimplemented"); 28 } 29 30 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 31 const int16_t runs[]) { 32 SkDEBUGFAIL("unimplemented"); 33 } 34 35 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 36 if (alpha == 255) { 37 this->blitRect(x, y, 1, height); 38 } else { 39 int16_t runs[2]; 40 runs[0] = 1; 41 runs[1] = 0; 42 43 while (--height >= 0) { 44 this->blitAntiH(x, y++, &alpha, runs); 45 } 46 } 47 } 48 49 void SkBlitter::blitRect(int x, int y, int width, int height) { 50 SkASSERT(width > 0); 51 while (--height >= 0) { 52 this->blitH(x, y++, width); 53 } 54 } 55 56 /// Default implementation doesn't check for any easy optimizations 57 /// such as alpha == 0 or 255; also uses blitV(), which some subclasses 58 /// may not support. 59 void SkBlitter::blitAntiRect(int x, int y, int width, int height, 60 SkAlpha leftAlpha, SkAlpha rightAlpha) { 61 this->blitV(x++, y, height, leftAlpha); 62 if (width > 0) { 63 this->blitRect(x, y, width, height); 64 x += width; 65 } 66 this->blitV(x, y, height, rightAlpha); 67 } 68 69 ////////////////////////////////////////////////////////////////////////////// 70 71 static inline void bits_to_runs(SkBlitter* blitter, int x, int y, 72 const uint8_t bits[], 73 U8CPU left_mask, int rowBytes, 74 U8CPU right_mask) { 75 int inFill = 0; 76 int pos = 0; 77 78 while (--rowBytes >= 0) { 79 unsigned b = *bits++ & left_mask; 80 if (rowBytes == 0) { 81 b &= right_mask; 82 } 83 84 for (unsigned test = 0x80; test != 0; test >>= 1) { 85 if (b & test) { 86 if (!inFill) { 87 pos = x; 88 inFill = true; 89 } 90 } else { 91 if (inFill) { 92 blitter->blitH(pos, y, x - pos); 93 inFill = false; 94 } 95 } 96 x += 1; 97 } 98 left_mask = 0xFF; 99 } 100 101 // final cleanup 102 if (inFill) { 103 blitter->blitH(pos, y, x - pos); 104 } 105 } 106 107 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 108 SkASSERT(mask.fBounds.contains(clip)); 109 110 if (mask.fFormat == SkMask::kBW_Format) { 111 int cx = clip.fLeft; 112 int cy = clip.fTop; 113 int maskLeft = mask.fBounds.fLeft; 114 int mask_rowBytes = mask.fRowBytes; 115 int height = clip.height(); 116 117 const uint8_t* bits = mask.getAddr1(cx, cy); 118 119 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) { 120 while (--height >= 0) { 121 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF); 122 bits += mask_rowBytes; 123 cy += 1; 124 } 125 } else { 126 int left_edge = cx - maskLeft; 127 SkASSERT(left_edge >= 0); 128 int rite_edge = clip.fRight - maskLeft; 129 SkASSERT(rite_edge > left_edge); 130 131 int left_mask = 0xFF >> (left_edge & 7); 132 int rite_mask = 0xFF << (8 - (rite_edge & 7)); 133 int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3); 134 135 // check for empty right mask, so we don't read off the end (or go slower than we need to) 136 if (rite_mask == 0) { 137 SkASSERT(full_runs >= 0); 138 full_runs -= 1; 139 rite_mask = 0xFF; 140 } 141 if (left_mask == 0xFF) { 142 full_runs -= 1; 143 } 144 145 // back up manually so we can keep in sync with our byte-aligned src 146 // have cx reflect our actual starting x-coord 147 cx -= left_edge & 7; 148 149 if (full_runs < 0) { 150 SkASSERT((left_mask & rite_mask) != 0); 151 while (--height >= 0) { 152 bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask); 153 bits += mask_rowBytes; 154 cy += 1; 155 } 156 } else { 157 while (--height >= 0) { 158 bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask); 159 bits += mask_rowBytes; 160 cy += 1; 161 } 162 } 163 } 164 } else { 165 int width = clip.width(); 166 SkAutoSTMalloc<64, int16_t> runStorage(width + 1); 167 int16_t* runs = runStorage.get(); 168 const uint8_t* aa = mask.getAddr8(clip.fLeft, clip.fTop); 169 170 sk_memset16((uint16_t*)runs, 1, width); 171 runs[width] = 0; 172 173 int height = clip.height(); 174 int y = clip.fTop; 175 while (--height >= 0) { 176 this->blitAntiH(clip.fLeft, y, aa, runs); 177 aa += mask.fRowBytes; 178 y += 1; 179 } 180 } 181 } 182 183 /////////////////////// these guys are not virtual, just a helpers 184 185 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) { 186 if (clip.quickReject(mask.fBounds)) { 187 return; 188 } 189 190 SkRegion::Cliperator clipper(clip, mask.fBounds); 191 192 while (!clipper.done()) { 193 const SkIRect& cr = clipper.rect(); 194 this->blitMask(mask, cr); 195 clipper.next(); 196 } 197 } 198 199 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) { 200 SkRegion::Cliperator clipper(clip, rect); 201 202 while (!clipper.done()) { 203 const SkIRect& cr = clipper.rect(); 204 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 205 clipper.next(); 206 } 207 } 208 209 void SkBlitter::blitRegion(const SkRegion& clip) { 210 SkRegion::Iterator iter(clip); 211 212 while (!iter.done()) { 213 const SkIRect& cr = iter.rect(); 214 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height()); 215 iter.next(); 216 } 217 } 218 219 /////////////////////////////////////////////////////////////////////////////// 220 221 void SkNullBlitter::blitH(int x, int y, int width) {} 222 223 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], 224 const int16_t runs[]) {} 225 226 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} 227 228 void SkNullBlitter::blitRect(int x, int y, int width, int height) {} 229 230 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} 231 232 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { 233 return NULL; 234 } 235 236 /////////////////////////////////////////////////////////////////////////////// 237 238 static int compute_anti_width(const int16_t runs[]) { 239 int width = 0; 240 241 for (;;) { 242 int count = runs[0]; 243 244 SkASSERT(count >= 0); 245 if (count == 0) { 246 break; 247 } 248 width += count; 249 runs += count; 250 } 251 return width; 252 } 253 254 static inline bool y_in_rect(int y, const SkIRect& rect) { 255 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 256 } 257 258 static inline bool x_in_rect(int x, const SkIRect& rect) { 259 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 260 } 261 262 void SkRectClipBlitter::blitH(int left, int y, int width) { 263 SkASSERT(width > 0); 264 265 if (!y_in_rect(y, fClipRect)) { 266 return; 267 } 268 269 int right = left + width; 270 271 if (left < fClipRect.fLeft) { 272 left = fClipRect.fLeft; 273 } 274 if (right > fClipRect.fRight) { 275 right = fClipRect.fRight; 276 } 277 278 width = right - left; 279 if (width > 0) { 280 fBlitter->blitH(left, y, width); 281 } 282 } 283 284 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], 285 const int16_t runs[]) { 286 if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) { 287 return; 288 } 289 290 int x0 = left; 291 int x1 = left + compute_anti_width(runs); 292 293 if (x1 <= fClipRect.fLeft) { 294 return; 295 } 296 297 SkASSERT(x0 < x1); 298 if (x0 < fClipRect.fLeft) { 299 int dx = fClipRect.fLeft - x0; 300 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx); 301 runs += dx; 302 aa += dx; 303 x0 = fClipRect.fLeft; 304 } 305 306 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 307 if (x1 > fClipRect.fRight) { 308 x1 = fClipRect.fRight; 309 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0); 310 ((int16_t*)runs)[x1 - x0] = 0; 311 } 312 313 SkASSERT(x0 < x1 && runs[x1 - x0] == 0); 314 SkASSERT(compute_anti_width(runs) == x1 - x0); 315 316 fBlitter->blitAntiH(x0, y, aa, runs); 317 } 318 319 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 320 SkASSERT(height > 0); 321 322 if (!x_in_rect(x, fClipRect)) { 323 return; 324 } 325 326 int y0 = y; 327 int y1 = y + height; 328 329 if (y0 < fClipRect.fTop) { 330 y0 = fClipRect.fTop; 331 } 332 if (y1 > fClipRect.fBottom) { 333 y1 = fClipRect.fBottom; 334 } 335 336 if (y0 < y1) { 337 fBlitter->blitV(x, y0, y1 - y0, alpha); 338 } 339 } 340 341 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) { 342 SkIRect r; 343 344 r.set(left, y, left + width, y + height); 345 if (r.intersect(fClipRect)) { 346 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 347 } 348 } 349 350 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height, 351 SkAlpha leftAlpha, SkAlpha rightAlpha) { 352 SkIRect r; 353 354 // The *true* width of the rectangle blitted is width+2: 355 r.set(left, y, left + width + 2, y + height); 356 if (r.intersect(fClipRect)) { 357 if (r.fLeft != left) { 358 SkASSERT(r.fLeft > left); 359 leftAlpha = 255; 360 } 361 if (r.fRight != left + width + 2) { 362 SkASSERT(r.fRight < left + width + 2); 363 rightAlpha = 255; 364 } 365 if (255 == leftAlpha && 255 == rightAlpha) { 366 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 367 } else if (1 == r.width()) { 368 if (r.fLeft == left) { 369 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha); 370 } else { 371 SkASSERT(r.fLeft == left + width + 1); 372 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha); 373 } 374 } else { 375 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 376 leftAlpha, rightAlpha); 377 } 378 } 379 } 380 381 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 382 SkASSERT(mask.fBounds.contains(clip)); 383 384 SkIRect r = clip; 385 386 if (r.intersect(fClipRect)) { 387 fBlitter->blitMask(mask, r); 388 } 389 } 390 391 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) { 392 return fBlitter->justAnOpaqueColor(value); 393 } 394 395 /////////////////////////////////////////////////////////////////////////////// 396 397 void SkRgnClipBlitter::blitH(int x, int y, int width) { 398 SkRegion::Spanerator span(*fRgn, y, x, x + width); 399 int left, right; 400 401 while (span.next(&left, &right)) { 402 SkASSERT(left < right); 403 fBlitter->blitH(left, y, right - left); 404 } 405 } 406 407 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 408 const int16_t runs[]) { 409 int width = compute_anti_width(runs); 410 SkRegion::Spanerator span(*fRgn, y, x, x + width); 411 int left, right; 412 SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();) 413 414 int prevRite = x; 415 while (span.next(&left, &right)) { 416 SkASSERT(x <= left); 417 SkASSERT(left < right); 418 SkASSERT(left >= bounds.fLeft && right <= bounds.fRight); 419 420 SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left); 421 422 // now zero before left 423 if (left > prevRite) { 424 int index = prevRite - x; 425 ((uint8_t*)aa)[index] = 0; // skip runs after right 426 ((int16_t*)runs)[index] = SkToS16(left - prevRite); 427 } 428 429 prevRite = right; 430 } 431 432 if (prevRite > x) { 433 ((int16_t*)runs)[prevRite - x] = 0; 434 435 if (x < 0) { 436 int skip = runs[0]; 437 SkASSERT(skip >= -x); 438 aa += skip; 439 runs += skip; 440 x += skip; 441 } 442 fBlitter->blitAntiH(x, y, aa, runs); 443 } 444 } 445 446 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 447 SkIRect bounds; 448 bounds.set(x, y, x + 1, y + height); 449 450 SkRegion::Cliperator iter(*fRgn, bounds); 451 452 while (!iter.done()) { 453 const SkIRect& r = iter.rect(); 454 SkASSERT(bounds.contains(r)); 455 456 fBlitter->blitV(x, r.fTop, r.height(), alpha); 457 iter.next(); 458 } 459 } 460 461 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) { 462 SkIRect bounds; 463 bounds.set(x, y, x + width, y + height); 464 465 SkRegion::Cliperator iter(*fRgn, bounds); 466 467 while (!iter.done()) { 468 const SkIRect& r = iter.rect(); 469 SkASSERT(bounds.contains(r)); 470 471 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 472 iter.next(); 473 } 474 } 475 476 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height, 477 SkAlpha leftAlpha, SkAlpha rightAlpha) { 478 // The *true* width of the rectangle to blit is width + 2 479 SkIRect bounds; 480 bounds.set(x, y, x + width + 2, y + height); 481 482 SkRegion::Cliperator iter(*fRgn, bounds); 483 484 while (!iter.done()) { 485 const SkIRect& r = iter.rect(); 486 SkASSERT(bounds.contains(r)); 487 SkASSERT(r.fLeft >= x); 488 SkASSERT(r.fRight <= x + width + 2); 489 490 SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255; 491 SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ? 492 rightAlpha : 255; 493 494 if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) { 495 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height()); 496 } else if (1 == r.width()) { 497 if (r.fLeft == x) { 498 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 499 effectiveLeftAlpha); 500 } else { 501 SkASSERT(r.fLeft == x + width + 1); 502 fBlitter->blitV(r.fLeft, r.fTop, r.height(), 503 effectiveRightAlpha); 504 } 505 } else { 506 fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(), 507 effectiveLeftAlpha, effectiveRightAlpha); 508 } 509 iter.next(); 510 } 511 } 512 513 514 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) { 515 SkASSERT(mask.fBounds.contains(clip)); 516 517 SkRegion::Cliperator iter(*fRgn, clip); 518 const SkIRect& r = iter.rect(); 519 SkBlitter* blitter = fBlitter; 520 521 while (!iter.done()) { 522 blitter->blitMask(mask, r); 523 iter.next(); 524 } 525 } 526 527 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) { 528 return fBlitter->justAnOpaqueColor(value); 529 } 530 531 /////////////////////////////////////////////////////////////////////////////// 532 533 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, 534 const SkIRect* ir) { 535 if (clip) { 536 const SkIRect& clipR = clip->getBounds(); 537 538 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { 539 blitter = &fNullBlitter; 540 } else if (clip->isRect()) { 541 if (ir == NULL || !clipR.contains(*ir)) { 542 fRectBlitter.init(blitter, clipR); 543 blitter = &fRectBlitter; 544 } 545 } else { 546 fRgnBlitter.init(blitter, clip); 547 blitter = &fRgnBlitter; 548 } 549 } 550 return blitter; 551 } 552 553 /////////////////////////////////////////////////////////////////////////////// 554 555 #include "SkColorShader.h" 556 #include "SkColorPriv.h" 557 558 class Sk3DShader : public SkShader { 559 public: 560 Sk3DShader(SkShader* proxy) : fProxy(proxy) { 561 SkSafeRef(proxy); 562 fMask = NULL; 563 } 564 565 virtual ~Sk3DShader() { 566 SkSafeUnref(fProxy); 567 } 568 569 void setMask(const SkMask* mask) { fMask = mask; } 570 571 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 572 const SkMatrix& matrix) { 573 if (fProxy) { 574 return fProxy->setContext(device, paint, matrix); 575 } else { 576 fPMColor = SkPreMultiplyColor(paint.getColor()); 577 return this->INHERITED::setContext(device, paint, matrix); 578 } 579 } 580 581 virtual void shadeSpan(int x, int y, SkPMColor span[], int count) { 582 if (fProxy) { 583 fProxy->shadeSpan(x, y, span, count); 584 } 585 586 if (fMask == NULL) { 587 if (fProxy == NULL) { 588 sk_memset32(span, fPMColor, count); 589 } 590 return; 591 } 592 593 SkASSERT(fMask->fBounds.contains(x, y)); 594 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); 595 596 size_t size = fMask->computeImageSize(); 597 const uint8_t* alpha = fMask->getAddr8(x, y); 598 const uint8_t* mulp = alpha + size; 599 const uint8_t* addp = mulp + size; 600 601 if (fProxy) { 602 for (int i = 0; i < count; i++) { 603 if (alpha[i]) { 604 SkPMColor c = span[i]; 605 if (c) { 606 unsigned a = SkGetPackedA32(c); 607 unsigned r = SkGetPackedR32(c); 608 unsigned g = SkGetPackedG32(c); 609 unsigned b = SkGetPackedB32(c); 610 611 unsigned mul = SkAlpha255To256(mulp[i]); 612 unsigned add = addp[i]; 613 614 r = SkFastMin32(SkAlphaMul(r, mul) + add, a); 615 g = SkFastMin32(SkAlphaMul(g, mul) + add, a); 616 b = SkFastMin32(SkAlphaMul(b, mul) + add, a); 617 618 span[i] = SkPackARGB32(a, r, g, b); 619 } 620 } else { 621 span[i] = 0; 622 } 623 } 624 } else { // color 625 unsigned a = SkGetPackedA32(fPMColor); 626 unsigned r = SkGetPackedR32(fPMColor); 627 unsigned g = SkGetPackedG32(fPMColor); 628 unsigned b = SkGetPackedB32(fPMColor); 629 for (int i = 0; i < count; i++) { 630 if (alpha[i]) { 631 unsigned mul = SkAlpha255To256(mulp[i]); 632 unsigned add = addp[i]; 633 634 span[i] = SkPackARGB32( a, 635 SkFastMin32(SkAlphaMul(r, mul) + add, a), 636 SkFastMin32(SkAlphaMul(g, mul) + add, a), 637 SkFastMin32(SkAlphaMul(b, mul) + add, a)); 638 } else { 639 span[i] = 0; 640 } 641 } 642 } 643 } 644 645 virtual void beginSession() { 646 this->INHERITED::beginSession(); 647 if (fProxy) { 648 fProxy->beginSession(); 649 } 650 } 651 652 virtual void endSession() { 653 if (fProxy) { 654 fProxy->endSession(); 655 } 656 this->INHERITED::endSession(); 657 } 658 659 protected: 660 Sk3DShader(SkFlattenableReadBuffer& buffer) : 661 INHERITED(buffer) { 662 fProxy = static_cast<SkShader*>(buffer.readFlattenable()); 663 fPMColor = buffer.readU32(); 664 fMask = NULL; 665 } 666 667 virtual void flatten(SkFlattenableWriteBuffer& buffer) { 668 this->INHERITED::flatten(buffer); 669 buffer.writeFlattenable(fProxy); 670 buffer.write32(fPMColor); 671 } 672 673 virtual Factory getFactory() { 674 return CreateProc; 675 } 676 677 private: 678 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 679 return SkNEW_ARGS(Sk3DShader, (buffer)); 680 } 681 682 SkShader* fProxy; 683 SkPMColor fPMColor; 684 const SkMask* fMask; 685 686 typedef SkShader INHERITED; 687 }; 688 689 class Sk3DBlitter : public SkBlitter { 690 public: 691 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*)) 692 : fProxy(proxy), f3DShader(shader), fKillProc(killProc) { 693 shader->ref(); 694 } 695 696 virtual ~Sk3DBlitter() { 697 f3DShader->unref(); 698 fKillProc(fProxy); 699 } 700 701 virtual void blitH(int x, int y, int width) { 702 fProxy->blitH(x, y, width); 703 } 704 705 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 706 const int16_t runs[]) { 707 fProxy->blitAntiH(x, y, antialias, runs); 708 } 709 710 virtual void blitV(int x, int y, int height, SkAlpha alpha) { 711 fProxy->blitV(x, y, height, alpha); 712 } 713 714 virtual void blitRect(int x, int y, int width, int height) { 715 fProxy->blitRect(x, y, width, height); 716 } 717 718 virtual void blitMask(const SkMask& mask, const SkIRect& clip) { 719 if (mask.fFormat == SkMask::k3D_Format) { 720 f3DShader->setMask(&mask); 721 722 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; 723 fProxy->blitMask(mask, clip); 724 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; 725 726 f3DShader->setMask(NULL); 727 } else { 728 fProxy->blitMask(mask, clip); 729 } 730 } 731 732 private: 733 SkBlitter* fProxy; 734 Sk3DShader* f3DShader; 735 void (*fKillProc)(void*); 736 }; 737 738 /////////////////////////////////////////////////////////////////////////////// 739 740 #include "SkCoreBlitters.h" 741 742 class SkAutoCallProc { 743 public: 744 typedef void (*Proc)(void*); 745 746 SkAutoCallProc(void* obj, Proc proc) 747 : fObj(obj), fProc(proc) {} 748 749 ~SkAutoCallProc() { 750 if (fObj && fProc) { 751 fProc(fObj); 752 } 753 } 754 755 void* get() const { return fObj; } 756 757 void* detach() { 758 void* obj = fObj; 759 fObj = NULL; 760 return obj; 761 } 762 763 private: 764 void* fObj; 765 Proc fProc; 766 }; 767 768 static void destroy_blitter(void* blitter) { 769 ((SkBlitter*)blitter)->~SkBlitter(); 770 } 771 772 static void delete_blitter(void* blitter) { 773 SkDELETE((SkBlitter*)blitter); 774 } 775 776 static bool just_solid_color(const SkPaint& paint) { 777 if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { 778 SkShader* shader = paint.getShader(); 779 if (NULL == shader || 780 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag)) { 781 return true; 782 } 783 } 784 return false; 785 } 786 787 /** By analyzing the paint (with an xfermode), we may decide we can take 788 special action. This enum lists our possible actions 789 */ 790 enum XferInterp { 791 kNormal_XferInterp, // no special interpretation, draw normally 792 kSrcOver_XferInterp, // draw as if in srcover mode 793 kSkipDrawing_XferInterp // draw nothing 794 }; 795 796 static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, 797 SkBitmap::Config deviceConfig) { 798 SkXfermode::Mode mode; 799 800 if (SkXfermode::AsMode(xfer, &mode)) { 801 switch (mode) { 802 case SkXfermode::kSrc_Mode: 803 if (just_solid_color(paint)) { 804 return kSrcOver_XferInterp; 805 } 806 break; 807 case SkXfermode::kDst_Mode: 808 return kSkipDrawing_XferInterp; 809 case SkXfermode::kSrcOver_Mode: 810 return kSrcOver_XferInterp; 811 case SkXfermode::kDstOver_Mode: 812 if (SkBitmap::kRGB_565_Config == deviceConfig) { 813 return kSkipDrawing_XferInterp; 814 } 815 break; 816 case SkXfermode::kSrcIn_Mode: 817 if (SkBitmap::kRGB_565_Config == deviceConfig && 818 just_solid_color(paint)) { 819 return kSrcOver_XferInterp; 820 } 821 break; 822 case SkXfermode::kDstIn_Mode: 823 if (just_solid_color(paint)) { 824 return kSkipDrawing_XferInterp; 825 } 826 break; 827 default: 828 break; 829 } 830 } 831 return kNormal_XferInterp; 832 } 833 834 SkBlitter* SkBlitter::Choose(const SkBitmap& device, 835 const SkMatrix& matrix, 836 const SkPaint& origPaint, 837 void* storage, size_t storageSize) { 838 SkASSERT(storageSize == 0 || storage != NULL); 839 840 SkBlitter* blitter = NULL; 841 842 // which check, in case we're being called by a client with a dummy device 843 // (e.g. they have a bounder that always aborts the draw) 844 if (SkBitmap::kNo_Config == device.getConfig()) { 845 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 846 return blitter; 847 } 848 849 SkPaint paint(origPaint); 850 SkShader* shader = paint.getShader(); 851 SkColorFilter* cf = paint.getColorFilter(); 852 SkXfermode* mode = paint.getXfermode(); 853 854 Sk3DShader* shader3D = NULL; 855 if (paint.getMaskFilter() != NULL && 856 paint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { 857 shader3D = SkNEW_ARGS(Sk3DShader, (shader)); 858 paint.setShader(shader3D)->unref(); 859 shader = shader3D; 860 } 861 862 if (NULL != mode) { 863 switch (interpret_xfermode(paint, mode, device.config())) { 864 case kSrcOver_XferInterp: 865 mode = NULL; 866 paint.setXfermode(NULL); 867 break; 868 case kSkipDrawing_XferInterp: 869 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 870 return blitter; 871 default: 872 break; 873 } 874 } 875 876 if (NULL == shader) { 877 #ifdef SK_IGNORE_CF_OPTIMIZATION 878 if (mode || cf) { 879 #else 880 if (mode) { 881 #endif 882 // xfermodes (and filters) require shaders for our current blitters 883 shader = SkNEW(SkColorShader); 884 paint.setShader(shader)->unref(); 885 } else if (cf) { 886 // if no shader && no xfermode, we just apply the colorfilter to 887 // our color and move on. 888 paint.setColor(cf->filterColor(paint.getColor())); 889 paint.setColorFilter(NULL); 890 cf = NULL; 891 } 892 } 893 894 if (cf) { 895 SkASSERT(shader); 896 shader = SkNEW_ARGS(SkFilterShader, (shader, cf)); 897 paint.setShader(shader)->unref(); 898 // blitters should ignore the presence/absence of a filter, since 899 // if there is one, the shader will take care of it. 900 } 901 902 if (shader && !shader->setContext(device, paint, matrix)) { 903 return SkNEW(SkNullBlitter); 904 } 905 906 switch (device.getConfig()) { 907 case SkBitmap::kA1_Config: 908 SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, 909 storage, storageSize, (device, paint)); 910 break; 911 912 case SkBitmap::kA8_Config: 913 if (shader) { 914 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, 915 storage, storageSize, (device, paint)); 916 } else { 917 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, 918 storage, storageSize, (device, paint)); 919 } 920 break; 921 922 case SkBitmap::kARGB_4444_Config: 923 blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize); 924 break; 925 926 case SkBitmap::kRGB_565_Config: 927 blitter = SkBlitter_ChooseD565(device, paint, storage, storageSize); 928 break; 929 930 case SkBitmap::kARGB_8888_Config: 931 if (shader) { 932 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, 933 storage, storageSize, (device, paint)); 934 } else if (paint.getColor() == SK_ColorBLACK) { 935 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, 936 storage, storageSize, (device, paint)); 937 } else if (paint.getAlpha() == 0xFF) { 938 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, 939 storage, storageSize, (device, paint)); 940 } else { 941 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, 942 storage, storageSize, (device, paint)); 943 } 944 break; 945 946 default: 947 SkDEBUGFAIL("unsupported device config"); 948 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); 949 break; 950 } 951 952 if (shader3D) { 953 void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter; 954 SkAutoCallProc tmp(blitter, proc); 955 956 blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc)); 957 (void)tmp.detach(); 958 } 959 return blitter; 960 } 961 962 /////////////////////////////////////////////////////////////////////////////// 963 964 const uint16_t gMask_0F0F = 0xF0F; 965 const uint32_t gMask_00FF00FF = 0xFF00FF; 966 967 /////////////////////////////////////////////////////////////////////////////// 968 969 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint) 970 : INHERITED(device) { 971 fShader = paint.getShader(); 972 SkASSERT(fShader); 973 974 fShader->ref(); 975 fShader->beginSession(); 976 fShaderFlags = fShader->getFlags(); 977 } 978 979 SkShaderBlitter::~SkShaderBlitter() { 980 fShader->endSession(); 981 fShader->unref(); 982 } 983 984