Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkScanPriv.h" | 10 #include "SkScanPriv.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 //#define FORCE_SUPERMASK | 38 //#define FORCE_SUPERMASK |
| 39 //#define FORCE_RLE | 39 //#define FORCE_RLE |
| 40 //#define SK_USE_LEGACY_AA_COVERAGE | 40 //#define SK_USE_LEGACY_AA_COVERAGE |
| 41 | 41 |
| 42 /////////////////////////////////////////////////////////////////////////////// | 42 /////////////////////////////////////////////////////////////////////////////// |
| 43 | 43 |
| 44 /// Base class for a single-pass supersampled blitter. | 44 /// Base class for a single-pass supersampled blitter. |
| 45 class BaseSuperBlitter : public SkBlitter { | 45 class BaseSuperBlitter : public SkBlitter { |
| 46 public: | 46 public: |
| 47 BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 47 BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, |
| 48 const SkRegion& clip); | 48 const SkRegion& clip, bool isInverse); |
| 49 | 49 |
| 50 /// Must be explicitly defined on subclasses. | 50 /// Must be explicitly defined on subclasses. |
| 51 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], | 51 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], |
| 52 const int16_t runs[]) SK_OVERRIDE { | 52 const int16_t runs[]) SK_OVERRIDE { |
| 53 SkDEBUGFAIL("How did I get here?"); | 53 SkDEBUGFAIL("How did I get here?"); |
| 54 } | 54 } |
| 55 /// May not be called on BaseSuperBlitter because it blits out of order. | 55 /// May not be called on BaseSuperBlitter because it blits out of order. |
| 56 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE { | 56 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE { |
| 57 SkDEBUGFAIL("How did I get here?"); | 57 SkDEBUGFAIL("How did I get here?"); |
| 58 } | 58 } |
| 59 | 59 |
| 60 protected: | 60 protected: |
| 61 SkBlitter* fRealBlitter; | 61 SkBlitter* fRealBlitter; |
| 62 /// Current y coordinate, in destination coordinates. | 62 /// Current y coordinate, in destination coordinates. |
| 63 int fCurrIY; | 63 int fCurrIY; |
| 64 /// Widest row of region to be blitted, in destination coordinates. | 64 /// Widest row of region to be blitted, in destination coordinates. |
| 65 int fWidth; | 65 int fWidth; |
| 66 /// Leftmost x coordinate in any row, in destination coordinates. | 66 /// Leftmost x coordinate in any row, in destination coordinates. |
| 67 int fLeft; | 67 int fLeft; |
| 68 /// Leftmost x coordinate in any row, in supersampled coordinates. | 68 /// Leftmost x coordinate in any row, in supersampled coordinates. |
| 69 int fSuperLeft; | 69 int fSuperLeft; |
| 70 | 70 |
| 71 SkDEBUGCODE(int fCurrX;) | 71 SkDEBUGCODE(int fCurrX;) |
| 72 /// Current y coordinate in supersampled coordinates. | 72 /// Current y coordinate in supersampled coordinates. |
| 73 int fCurrY; | 73 int fCurrY; |
| 74 /// Initial y coordinate (top of bounds). | 74 /// Initial y coordinate (top of bounds). |
| 75 int fTop; | 75 int fTop; |
| 76 | |
| 77 SkIRect fSectBounds; | |
| 76 }; | 78 }; |
| 77 | 79 |
| 78 BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 80 BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir, const SkRegion& clip, |
| 79 const SkRegion& clip) { | 81 bool isInverse) { |
| 80 fRealBlitter = realBlitter; | 82 fRealBlitter = realBlit; |
| 83 | |
| 84 SkIRect sectBounds; | |
| 85 if (isInverse) { | |
| 86 sectBounds = clip.getBounds(); | |
| 87 } else { | |
| 88 if (!sectBounds.intersect(ir, clip.getBounds())) { | |
| 89 sectBounds.setEmpty(); | |
| 90 } | |
| 91 } | |
| 81 | 92 |
| 82 /* | 93 /* |
| 83 * We use the clip bounds instead of the ir, since we may be asked to | 94 * We use the clip bounds instead of the ir, since we may be asked to |
| 84 * draw outside of the rect if we're a inverse filltype | 95 * draw outside of the rect if we're a inverse filltype |
|
caryclark
2014/10/15 15:51:31
comment no longer accurate?
| |
| 85 */ | 96 */ |
| 86 const int left = clip.getBounds().fLeft; | 97 const int left = sectBounds.left(); |
| 87 const int right = clip.getBounds().fRight; | 98 const int right = sectBounds.right(); |
| 88 | 99 |
| 89 fLeft = left; | 100 fLeft = left; |
| 90 fSuperLeft = left << SHIFT; | 101 fSuperLeft = left << SHIFT; |
| 91 fWidth = right - left; | 102 fWidth = right - left; |
| 92 #if 0 | 103 fTop = sectBounds.top(); |
| 93 fCurrIY = -1; | 104 fCurrIY = fTop - 1; |
| 94 fCurrY = -1; | 105 fCurrY = (fTop << SHIFT) - 1; |
| 95 #else | 106 |
| 96 fTop = ir.fTop; | |
| 97 fCurrIY = ir.fTop - 1; | |
| 98 fCurrY = (ir.fTop << SHIFT) - 1; | |
| 99 #endif | |
| 100 SkDEBUGCODE(fCurrX = -1;) | 107 SkDEBUGCODE(fCurrX = -1;) |
| 101 } | 108 } |
| 102 | 109 |
| 103 /// Run-length-encoded supersampling antialiased blitter. | 110 /// Run-length-encoded supersampling antialiased blitter. |
| 104 class SuperBlitter : public BaseSuperBlitter { | 111 class SuperBlitter : public BaseSuperBlitter { |
| 105 public: | 112 public: |
| 106 SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 113 SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip , bool isInverse); |
| 107 const SkRegion& clip); | |
| 108 | 114 |
| 109 virtual ~SuperBlitter() { | 115 virtual ~SuperBlitter() { |
| 110 this->flush(); | 116 this->flush(); |
| 111 } | 117 } |
| 112 | 118 |
| 113 /// Once fRuns contains a complete supersampled row, flush() blits | 119 /// Once fRuns contains a complete supersampled row, flush() blits |
| 114 /// it out through the wrapped blitter. | 120 /// it out through the wrapped blitter. |
| 115 void flush(); | 121 void flush(); |
| 116 | 122 |
| 117 /// Blits a row of pixels, with location and width specified | 123 /// Blits a row of pixels, with location and width specified |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 142 fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer; | 148 fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer; |
| 143 fRuns.fRuns = reinterpret_cast<int16_t*>( | 149 fRuns.fRuns = reinterpret_cast<int16_t*>( |
| 144 reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz); | 150 reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz); |
| 145 fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1); | 151 fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1); |
| 146 fRuns.reset(fWidth); | 152 fRuns.reset(fWidth); |
| 147 } | 153 } |
| 148 | 154 |
| 149 int fOffsetX; | 155 int fOffsetX; |
| 150 }; | 156 }; |
| 151 | 157 |
| 152 SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 158 SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRe gion& clip, |
| 153 const SkRegion& clip) | 159 bool isInverse) |
| 154 : BaseSuperBlitter(realBlitter, ir, clip) { | 160 : BaseSuperBlitter(realBlitter, ir, clip, isInverse) |
| 161 { | |
| 155 fRunsToBuffer = realBlitter->requestRowsPreserved(); | 162 fRunsToBuffer = realBlitter->requestRowsPreserved(); |
| 156 fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz() ); | 163 fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz() ); |
| 157 fCurrentRun = -1; | 164 fCurrentRun = -1; |
| 158 | 165 |
| 159 this->advanceRuns(); | 166 this->advanceRuns(); |
| 160 | 167 |
| 161 fOffsetX = 0; | 168 fOffsetX = 0; |
| 162 } | 169 } |
| 163 | 170 |
| 164 void SuperBlitter::flush() { | 171 void SuperBlitter::flush() { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 while (--height >= 0) { | 398 while (--height >= 0) { |
| 392 this->blitH(x, y++, width); | 399 this->blitH(x, y++, width); |
| 393 } | 400 } |
| 394 } | 401 } |
| 395 | 402 |
| 396 /////////////////////////////////////////////////////////////////////////////// | 403 /////////////////////////////////////////////////////////////////////////////// |
| 397 | 404 |
| 398 /// Masked supersampling antialiased blitter. | 405 /// Masked supersampling antialiased blitter. |
| 399 class MaskSuperBlitter : public BaseSuperBlitter { | 406 class MaskSuperBlitter : public BaseSuperBlitter { |
| 400 public: | 407 public: |
| 401 MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 408 MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion&, bool isInverse); |
| 402 const SkRegion& clip); | |
| 403 virtual ~MaskSuperBlitter() { | 409 virtual ~MaskSuperBlitter() { |
| 404 fRealBlitter->blitMask(fMask, fClipRect); | 410 fRealBlitter->blitMask(fMask, fClipRect); |
| 405 } | 411 } |
| 406 | 412 |
| 407 virtual void blitH(int x, int y, int width) SK_OVERRIDE; | 413 virtual void blitH(int x, int y, int width) SK_OVERRIDE; |
| 408 | 414 |
| 409 static bool CanHandleRect(const SkIRect& bounds) { | 415 static bool CanHandleRect(const SkIRect& bounds) { |
| 410 #ifdef FORCE_RLE | 416 #ifdef FORCE_RLE |
| 411 return false; | 417 return false; |
| 412 #endif | 418 #endif |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 430 #endif | 436 #endif |
| 431 }; | 437 }; |
| 432 | 438 |
| 433 SkMask fMask; | 439 SkMask fMask; |
| 434 SkIRect fClipRect; | 440 SkIRect fClipRect; |
| 435 // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the en d, rather than | 441 // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the en d, rather than |
| 436 // perform a test to see if stopAlpha != 0 | 442 // perform a test to see if stopAlpha != 0 |
| 437 uint32_t fStorage[(kMAX_STORAGE >> 2) + 1]; | 443 uint32_t fStorage[(kMAX_STORAGE >> 2) + 1]; |
| 438 }; | 444 }; |
| 439 | 445 |
| 440 MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, | 446 MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, co nst SkRegion& clip, |
| 441 const SkRegion& clip) | 447 bool isInverse) |
| 442 : BaseSuperBlitter(realBlitter, ir, clip) { | 448 : BaseSuperBlitter(realBlitter, ir, clip, isInverse) |
| 449 { | |
| 443 SkASSERT(CanHandleRect(ir)); | 450 SkASSERT(CanHandleRect(ir)); |
| 451 SkASSERT(!isInverse); | |
| 444 | 452 |
| 445 fMask.fImage = (uint8_t*)fStorage; | 453 fMask.fImage = (uint8_t*)fStorage; |
| 446 fMask.fBounds = ir; | 454 fMask.fBounds = ir; |
| 447 fMask.fRowBytes = ir.width(); | 455 fMask.fRowBytes = ir.width(); |
| 448 fMask.fFormat = SkMask::kA8_Format; | 456 fMask.fFormat = SkMask::kA8_Format; |
| 449 | 457 |
| 450 fClipRect = ir; | 458 fClipRect = ir; |
| 451 fClipRect.intersect(clip.getBounds()); | 459 fClipRect.intersect(clip.getBounds()); |
| 452 | 460 |
| 453 // For valgrind, write 1 extra byte at the end so we don't read | 461 // For valgrind, write 1 extra byte at the end so we don't read |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 } | 629 } |
| 622 return false; | 630 return false; |
| 623 } | 631 } |
| 624 | 632 |
| 625 void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, | 633 void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, |
| 626 SkBlitter* blitter, bool forceRLE) { | 634 SkBlitter* blitter, bool forceRLE) { |
| 627 if (origClip.isEmpty()) { | 635 if (origClip.isEmpty()) { |
| 628 return; | 636 return; |
| 629 } | 637 } |
| 630 | 638 |
| 639 const bool isInverse = path.isInverseFillType(); | |
| 631 SkIRect ir; | 640 SkIRect ir; |
| 632 | 641 |
| 633 if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) { | 642 if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) { |
| 634 #if 0 | 643 #if 0 |
| 635 const SkRect& r = path.getBounds(); | 644 const SkRect& r = path.getBounds(); |
| 636 SkDebugf("--- bounds can't fit in SkIRect\n", r.fLeft, r.fTop, r.fRight, r.fBottom); | 645 SkDebugf("--- bounds can't fit in SkIRect\n", r.fLeft, r.fTop, r.fRight, r.fBottom); |
| 637 #endif | 646 #endif |
| 638 return; | 647 return; |
| 639 } | 648 } |
| 640 if (ir.isEmpty()) { | 649 if (ir.isEmpty()) { |
| 641 if (path.isInverseFillType()) { | 650 if (isInverse) { |
| 642 blitter->blitRegion(origClip); | 651 blitter->blitRegion(origClip); |
| 643 } | 652 } |
| 644 return; | 653 return; |
| 645 } | 654 } |
| 646 | 655 |
| 647 // If the intersection of the path bounds and the clip bounds | 656 // If the intersection of the path bounds and the clip bounds |
| 648 // will overflow 32767 when << by SHIFT, we can't supersample, | 657 // will overflow 32767 when << by SHIFT, we can't supersample, |
| 649 // so draw without antialiasing. | 658 // so draw without antialiasing. |
| 650 SkIRect clippedIR; | 659 SkIRect clippedIR; |
| 651 if (path.isInverseFillType()) { | 660 if (isInverse) { |
| 652 // If the path is an inverse fill, it's going to fill the entire | 661 // If the path is an inverse fill, it's going to fill the entire |
| 653 // clip, and we care whether the entire clip exceeds our limits. | 662 // clip, and we care whether the entire clip exceeds our limits. |
| 654 clippedIR = origClip.getBounds(); | 663 clippedIR = origClip.getBounds(); |
| 655 } else { | 664 } else { |
| 656 if (!clippedIR.intersect(ir, origClip.getBounds())) { | 665 if (!clippedIR.intersect(ir, origClip.getBounds())) { |
| 657 return; | 666 return; |
| 658 } | 667 } |
| 659 } | 668 } |
| 660 if (rect_overflows_short_shift(clippedIR, SHIFT)) { | 669 if (rect_overflows_short_shift(clippedIR, SHIFT)) { |
| 661 SkScan::FillPath(path, origClip, blitter); | 670 SkScan::FillPath(path, origClip, blitter); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 678 tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op); | 687 tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op); |
| 679 clipRgn = &tmpClipStorage; | 688 clipRgn = &tmpClipStorage; |
| 680 } | 689 } |
| 681 } | 690 } |
| 682 // for here down, use clipRgn, not origClip | 691 // for here down, use clipRgn, not origClip |
| 683 | 692 |
| 684 SkScanClipper clipper(blitter, clipRgn, ir); | 693 SkScanClipper clipper(blitter, clipRgn, ir); |
| 685 const SkIRect* clipRect = clipper.getClipRect(); | 694 const SkIRect* clipRect = clipper.getClipRect(); |
| 686 | 695 |
| 687 if (clipper.getBlitter() == NULL) { // clipped out | 696 if (clipper.getBlitter() == NULL) { // clipped out |
| 688 if (path.isInverseFillType()) { | 697 if (isInverse) { |
| 689 blitter->blitRegion(*clipRgn); | 698 blitter->blitRegion(*clipRgn); |
| 690 } | 699 } |
| 691 return; | 700 return; |
| 692 } | 701 } |
| 693 | 702 |
| 694 // now use the (possibly wrapped) blitter | 703 // now use the (possibly wrapped) blitter |
| 695 blitter = clipper.getBlitter(); | 704 blitter = clipper.getBlitter(); |
| 696 | 705 |
| 697 if (path.isInverseFillType()) { | 706 if (isInverse) { |
| 698 sk_blit_above(blitter, ir, *clipRgn); | 707 sk_blit_above(blitter, ir, *clipRgn); |
| 699 } | 708 } |
| 700 | 709 |
| 701 SkIRect superRect, *superClipRect = NULL; | 710 SkIRect superRect, *superClipRect = NULL; |
| 702 | 711 |
| 703 if (clipRect) { | 712 if (clipRect) { |
| 704 superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT, | 713 superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT, |
| 705 clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT); | 714 clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT); |
| 706 superClipRect = &superRect; | 715 superClipRect = &superRect; |
| 707 } | 716 } |
| 708 | 717 |
| 709 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); | 718 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); |
| 710 | 719 |
| 711 // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it | 720 // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it |
| 712 // if we're an inverse filltype | 721 // if we're an inverse filltype |
| 713 if (!path.isInverseFillType() && MaskSuperBlitter::CanHandleRect(ir) && !for ceRLE) { | 722 if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) { |
| 714 MaskSuperBlitter superBlit(blitter, ir, *clipRgn); | 723 MaskSuperBlitter superBlit(blitter, ir, *clipRgn, isInverse); |
| 715 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); | 724 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); |
| 716 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT , *clipRgn); | 725 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT , *clipRgn); |
| 717 } else { | 726 } else { |
| 718 SuperBlitter superBlit(blitter, ir, *clipRgn); | 727 SuperBlitter superBlit(blitter, ir, *clipRgn, isInverse); |
| 719 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT , *clipRgn); | 728 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT , *clipRgn); |
| 720 } | 729 } |
| 721 | 730 |
| 722 if (path.isInverseFillType()) { | 731 if (isInverse) { |
| 723 sk_blit_below(blitter, ir, *clipRgn); | 732 sk_blit_below(blitter, ir, *clipRgn); |
| 724 } | 733 } |
| 725 } | 734 } |
| 726 | 735 |
| 727 /////////////////////////////////////////////////////////////////////////////// | 736 /////////////////////////////////////////////////////////////////////////////// |
| 728 | 737 |
| 729 #include "SkRasterClip.h" | 738 #include "SkRasterClip.h" |
| 730 | 739 |
| 731 void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip, | 740 void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip, |
| 732 SkBlitter* blitter) { | 741 SkBlitter* blitter) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 756 AntiFillPath(path, clip.bwRgn(), blitter); | 765 AntiFillPath(path, clip.bwRgn(), blitter); |
| 757 } else { | 766 } else { |
| 758 SkRegion tmp; | 767 SkRegion tmp; |
| 759 SkAAClipBlitter aaBlitter; | 768 SkAAClipBlitter aaBlitter; |
| 760 | 769 |
| 761 tmp.setRect(clip.getBounds()); | 770 tmp.setRect(clip.getBounds()); |
| 762 aaBlitter.init(blitter, &clip.aaRgn()); | 771 aaBlitter.init(blitter, &clip.aaRgn()); |
| 763 SkScan::AntiFillPath(path, tmp, &aaBlitter, true); | 772 SkScan::AntiFillPath(path, tmp, &aaBlitter, true); |
| 764 } | 773 } |
| 765 } | 774 } |
| OLD | NEW |