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