diff options
author | Mike Reed <reed@google.com> | 2017-03-04 19:43:23 +0000 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-03-04 19:43:35 +0000 |
commit | 025e2444c1f5a0c3cdc0bf60d1fa59941a0b5db4 (patch) | |
tree | c353105999aa71c22d41879e2b0beb2aba5df5d9 /src/core/SkRasterClip.cpp | |
parent | 12da890fbdafb2a2e33ced24e207ffc8cdec54c7 (diff) |
Revert "Revert "Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping.""""
This reverts commit baf06bc89a0ee2ac4033281e7310f6c727faab79.
Reason for revert: reland to diagnose possible g3 failure
Original change's description:
> Revert "Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping."""
>
> This reverts commit cfaa63237b152ae216f1351207bce3ea9808814c.
>
> Reason for revert: speculative revert to fix Google3
>
> Original change's description:
> > Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping.""
> >
> > passes new (augmented) CanvasClipType unittest
> > fixed rasterclipstack::setnewsize
> >
> > This reverts commit ea5e676a7b75600edcde3912886486004ccd7626.
> >
> > BUG=skia:
> >
> > Change-Id: I004653e0f4d01454662f8516fccab0046486f273
> > Reviewed-on: https://skia-review.googlesource.com/9185
> > Reviewed-by: Brian Salomon <bsalomon@google.com>
> > Commit-Queue: Mike Reed <reed@google.com>
> >
>
> TBR=bsalomon@google.com,reed@google.com,reviews@skia.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=skia:
>
> Change-Id: Ibd7ee6383999f008eb6ee59c1c3f1c06a86044ea
> Reviewed-on: https://skia-review.googlesource.com/9230
> Reviewed-by: Cary Clark <caryclark@google.com>
> Commit-Queue: Cary Clark <caryclark@google.com>
>
TBR=bsalomon@google.com,reviews@skia.org,caryclark@google.com,reed@google.com,mtklein@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:
Change-Id: I093fa8788056be39af01191bbf3a9e5de9f73954
Reviewed-on: https://skia-review.googlesource.com/9244
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core/SkRasterClip.cpp')
-rw-r--r-- | src/core/SkRasterClip.cpp | 226 |
1 files changed, 120 insertions, 106 deletions
diff --git a/src/core/SkRasterClip.cpp b/src/core/SkRasterClip.cpp index a9e043f84f..f43d14e483 100644 --- a/src/core/SkRasterClip.cpp +++ b/src/core/SkRasterClip.cpp @@ -8,10 +8,125 @@ #include "SkRasterClip.h" #include "SkPath.h" +enum MutateResult { + kDoNothing_MutateResult, + kReplaceClippedAgainstGlobalBounds_MutateResult, + kContinue_MutateResult, +}; + +static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) { + if (inverseFilled) { + switch (*op) { + case SkRegion::kIntersect_Op: + case SkRegion::kDifference_Op: + // These ops can only shrink the current clip. So leaving + // the clip unchanged conservatively respects the contract. + return kDoNothing_MutateResult; + case SkRegion::kUnion_Op: + case SkRegion::kReplace_Op: + case SkRegion::kReverseDifference_Op: + case SkRegion::kXOR_Op: { + // These ops can grow the current clip up to the extents of + // the input clip, which is inverse filled, so we just set + // the current clip to the device bounds. + *op = SkRegion::kReplace_Op; + return kReplaceClippedAgainstGlobalBounds_MutateResult; + } + } + } else { + // Not inverse filled + switch (*op) { + case SkRegion::kIntersect_Op: + case SkRegion::kUnion_Op: + case SkRegion::kReplace_Op: + return kContinue_MutateResult; + case SkRegion::kDifference_Op: + // Difference can only shrink the current clip. + // Leaving clip unchanged conservatively fullfills the contract. + return kDoNothing_MutateResult; + case SkRegion::kReverseDifference_Op: + // To reverse, we swap in the bounds with a replace op. + // As with difference, leave it unchanged. + *op = SkRegion::kReplace_Op; + return kContinue_MutateResult; + case SkRegion::kXOR_Op: + // Be conservative, based on (A XOR B) always included in (A union B), + // which is always included in (bounds(A) union bounds(B)) + *op = SkRegion::kUnion_Op; + return kContinue_MutateResult; + } + } + SkFAIL("should not get here"); + return kDoNothing_MutateResult; +} + +void SkConservativeClip::op(const SkRect& localRect, const SkMatrix& ctm, const SkIRect& devBounds, + SkRegion::Op op, bool doAA) { + SkRect devRect; + + SkIRect bounds(devBounds); + this->applyClipRestriction(op, &bounds); + SkIRect ir; + switch (mutate_conservative_op(&op, false)) { + case kDoNothing_MutateResult: + return; + case kReplaceClippedAgainstGlobalBounds_MutateResult: + ir = bounds; + break; + case kContinue_MutateResult: + ctm.mapRect(&devRect, localRect); + ir = doAA ? devRect.roundOut() : devRect.round(); + break; + } + this->op(ir, op); +} + +void SkConservativeClip::op(const SkRRect& rrect, const SkMatrix& ctm, const SkIRect& devBounds, + SkRegion::Op op, bool doAA) { + SkIRect bounds(devBounds); + this->applyClipRestriction(op, &bounds); + this->op(rrect.getBounds(), ctm, bounds, op, doAA); +} + +void SkConservativeClip::op(const SkPath& path, const SkMatrix& ctm, const SkIRect& devBounds, + SkRegion::Op op, bool doAA) { + SkIRect bounds(devBounds); + this->applyClipRestriction(op, &bounds); + + SkIRect ir; + switch (mutate_conservative_op(&op, path.isInverseFillType())) { + case kDoNothing_MutateResult: + return; + case kReplaceClippedAgainstGlobalBounds_MutateResult: + ir = bounds; + break; + case kContinue_MutateResult: { + SkRect bounds = path.getBounds(); + ctm.mapRect(&bounds); + ir = bounds.roundOut(); + break; + } + } + return this->op(ir, op); +} + +void SkConservativeClip::op(const SkRegion& rgn, SkRegion::Op op) { + this->op(rgn.getBounds(), op); +} + +void SkConservativeClip::op(const SkIRect& devRect, SkRegion::Op op) { + // This may still create a complex region (which we would then take the bounds + // Perhaps we should inline the op-logic directly to never create the rgn... + SkRegion result; + result.op(SkRegion(fBounds), SkRegion(devRect), op); + fBounds = result.getBounds(); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + SkRasterClip::SkRasterClip(const SkRasterClip& src) { AUTO_RASTERCLIP_VALIDATE(src); - fForceConservativeRects = src.fForceConservativeRects; fIsBW = src.fIsBW; if (fIsBW) { fBW = src.fBW; @@ -26,23 +141,20 @@ SkRasterClip::SkRasterClip(const SkRasterClip& src) { } SkRasterClip::SkRasterClip(const SkRegion& rgn) : fBW(rgn) { - fForceConservativeRects = false; fIsBW = true; fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute fIsRect = !fIsEmpty; SkDEBUGCODE(this->validate();) } -SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) { - fForceConservativeRects = forceConservativeRects; +SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) { fIsBW = true; fIsEmpty = this->computeIsEmpty(); // bounds might be empty, so compute fIsRect = !fIsEmpty; SkDEBUGCODE(this->validate();) } -SkRasterClip::SkRasterClip(bool forceConservativeRects) { - fForceConservativeRects = forceConservativeRects; +SkRasterClip::SkRasterClip() { fIsBW = true; fIsEmpty = true; fIsRect = false; @@ -54,8 +166,6 @@ SkRasterClip::~SkRasterClip() { } bool SkRasterClip::operator==(const SkRasterClip& other) const { - // This impl doesn't care if fForceConservativeRects is the same in both, only the current state - if (fIsBW != other.fIsBW) { return false; } @@ -114,65 +224,9 @@ bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bo ///////////////////////////////////////////////////////////////////////////////////// -enum MutateResult { - kDoNothing_MutateResult, - kReplaceClippedAgainstGlobalBounds_MutateResult, - kContinue_MutateResult, -}; - -static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) { - if (inverseFilled) { - switch (*op) { - case SkRegion::kIntersect_Op: - case SkRegion::kDifference_Op: - // These ops can only shrink the current clip. So leaving - // the clip unchanged conservatively respects the contract. - return kDoNothing_MutateResult; - case SkRegion::kUnion_Op: - case SkRegion::kReplace_Op: - case SkRegion::kReverseDifference_Op: - case SkRegion::kXOR_Op: { - // These ops can grow the current clip up to the extents of - // the input clip, which is inverse filled, so we just set - // the current clip to the device bounds. - *op = SkRegion::kReplace_Op; - return kReplaceClippedAgainstGlobalBounds_MutateResult; - } - } - } else { - // Not inverse filled - switch (*op) { - case SkRegion::kIntersect_Op: - case SkRegion::kUnion_Op: - case SkRegion::kReplace_Op: - return kContinue_MutateResult; - case SkRegion::kDifference_Op: - // Difference can only shrink the current clip. - // Leaving clip unchanged conservatively fullfills the contract. - return kDoNothing_MutateResult; - case SkRegion::kReverseDifference_Op: - // To reverse, we swap in the bounds with a replace op. - // As with difference, leave it unchanged. - *op = SkRegion::kReplace_Op; - return kContinue_MutateResult; - case SkRegion::kXOR_Op: - // Be conservative, based on (A XOR B) always included in (A union B), - // which is always included in (bounds(A) union bounds(B)) - *op = SkRegion::kUnion_Op; - return kContinue_MutateResult; - } - } - SkFAIL("should not get here"); - return kDoNothing_MutateResult; -} - bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) { AUTO_RASTERCLIP_VALIDATE(*this); - if (fForceConservativeRects) { - return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType()); - } - if (this->isBW() && !doAA) { (void)fBW.setPath(path, clip); } else { @@ -190,9 +244,6 @@ bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRec SkRegion::Op op, bool doAA) { SkIRect bounds(devBounds); this->applyClipRestriction(op, &bounds); - if (fForceConservativeRects) { - return this->op(rrect.getBounds(), matrix, bounds, op, doAA); - } SkPath path; path.addRRect(rrect); @@ -206,24 +257,6 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& SkIRect bounds(devBounds); this->applyClipRestriction(op, &bounds); - if (fForceConservativeRects) { - SkIRect ir; - switch (mutate_conservative_op(&op, path.isInverseFillType())) { - case kDoNothing_MutateResult: - return !this->isEmpty(); - case kReplaceClippedAgainstGlobalBounds_MutateResult: - ir = bounds; - break; - case kContinue_MutateResult: { - SkRect bounds = path.getBounds(); - matrix.mapRect(&bounds); - ir = bounds.roundOut(); - break; - } - } - return this->op(ir, op); - } - // base is used to limit the size (and therefore memory allocation) of the // region that results from scan converting devPath. SkRegion base; @@ -246,7 +279,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& return this->setPath(devPath, this->bwRgn(), doAA); } else { base.setRect(this->getBounds()); - SkRasterClip clip(fForceConservativeRects); + SkRasterClip clip; clip.setPath(devPath, base, doAA); return this->op(clip, op); } @@ -256,7 +289,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect& if (SkRegion::kReplace_Op == op) { return this->setPath(devPath, base, doAA); } else { - SkRasterClip clip(fForceConservativeRects); + SkRasterClip clip; clip.setPath(devPath, base, doAA); return this->op(clip, op); } @@ -331,23 +364,6 @@ bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkI AUTO_RASTERCLIP_VALIDATE(*this); SkRect devRect; - if (fForceConservativeRects) { - SkIRect bounds(devBounds); - this->applyClipRestriction(op, &bounds); - SkIRect ir; - switch (mutate_conservative_op(&op, false)) { - case kDoNothing_MutateResult: - return !this->isEmpty(); - case kReplaceClippedAgainstGlobalBounds_MutateResult: - ir = bounds; - break; - case kContinue_MutateResult: - matrix.mapRect(&devRect, localRect); - ir = devRect.roundOut(); - break; - } - return this->op(ir, op); - } const bool isScaleTrans = matrix.isScaleTranslate(); if (!isScaleTrans) { SkPath path; @@ -427,8 +443,6 @@ const SkRegion& SkRasterClip::forceGetBW() { void SkRasterClip::convertToAA() { AUTO_RASTERCLIP_VALIDATE(*this); - SkASSERT(!fForceConservativeRects); - SkASSERT(fIsBW); fAA.setRegion(fBW); fIsBW = false; |