Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: src/core/SkScan_AntiPath.cpp

Issue 656473004: interesct path bounds with clip bounds before initializing supersampler (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: enable test Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/AAClipTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/AAClipTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698