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