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 |