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