diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkClipStack.cpp | 25 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.h | 1 | ||||
-rw-r--r-- | src/gpu/GrDrawContext.cpp | 22 |
4 files changed, 51 insertions, 5 deletions
diff --git a/src/core/SkClipStack.cpp b/src/core/SkClipStack.cpp index 06418b46ba..12ad3bb27c 100644 --- a/src/core/SkClipStack.cpp +++ b/src/core/SkClipStack.cpp @@ -646,6 +646,31 @@ bool SkClipStack::quickContains(const SkRect& rect) const { return true; } +bool SkClipStack::quickContains(const SkRRect& rrect) const { + + Iter iter(*this, Iter::kTop_IterStart); + const Element* element = iter.prev(); + while (element != nullptr) { + if (SkRegion::kIntersect_Op != element->getOp() && SkRegion::kReplace_Op != element->getOp()) + return false; + if (element->isInverseFilled()) { + // Part of 'rrect' could be trimmed off by the inverse-filled clip element + if (SkRect::Intersects(element->getBounds(), rrect.getBounds())) { + return false; + } + } else { + if (!element->contains(rrect)) { + return false; + } + } + if (SkRegion::kReplace_Op == element->getOp()) { + break; + } + element = iter.prev(); + } + return true; +} + bool SkClipStack::asPath(SkPath *path) const { bool isAA = false; diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index 6cb216ee0c..a3a0de509c 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -30,6 +30,14 @@ bool GrClipStackClip::quickContains(const SkRect& rect) const { SkIntToScalar(fOrigin.y()))); } +bool GrClipStackClip::quickContains(const SkRRect& rrect) const { + if (!fStack) { + return true; + } + return fStack->quickContains(rrect.makeOffset(SkIntToScalar(fOrigin.fX), + SkIntToScalar(fOrigin.fY))); +} + void GrClipStackClip::getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const { if (!fStack) { diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h index 98675e62ac..15025471d2 100644 --- a/src/gpu/GrClipStackClip.h +++ b/src/gpu/GrClipStackClip.h @@ -31,6 +31,7 @@ public: } bool quickContains(const SkRect&) const final; + bool quickContains(const SkRRect&) const final; void getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const final; bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSettings, diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp index 76e0d8a66c..202be23590 100644 --- a/src/gpu/GrDrawContext.cpp +++ b/src/gpu/GrDrawContext.cpp @@ -781,7 +781,7 @@ void GrDrawContext::drawAtlas(const GrClip& clip, /////////////////////////////////////////////////////////////////////////////// -void GrDrawContext::drawRRect(const GrClip& clip, +void GrDrawContext::drawRRect(const GrClip& origClip, const GrPaint& paint, const SkMatrix& viewMatrix, const SkRRect& rrect, @@ -790,11 +790,23 @@ void GrDrawContext::drawRRect(const GrClip& clip, RETURN_IF_ABANDONED SkDEBUGCODE(this->validate();) GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawRRect"); - if (rrect.isEmpty()) { return; } + GrNoClip noclip; + const GrClip* clip = &origClip; +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + // The Android framework frequently clips rrects to themselves where the clip is non-aa and the + // draw is aa. Since our lower level clip code works from batch bounds, which are SkRects, it + // doesn't detect that the clip can be ignored (modulo antialiasing). The following test + // attempts to mitigate the stencil clip cost but will only help when the entire clip stack + // can be ignored. We'd prefer to fix this in the framework by removing the clips calls. + SkRRect devRRect; + if (rrect.transform(viewMatrix, &devRRect) && clip->quickContains(devRRect)) { + clip = &noclip; + } +#endif SkASSERT(!style.pathEffect()); // this should've been devolved to a path in SkGpuDevice AutoCheckFlush acf(fDrawingManager); @@ -809,7 +821,7 @@ void GrDrawContext::drawRRect(const GrClip& clip, &useHWAA)); if (batch) { GrPipelineBuilder pipelineBuilder(paint, useHWAA); - this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch); + this->getDrawTarget()->drawBatch(pipelineBuilder, this, *clip, batch); return; } } @@ -823,7 +835,7 @@ void GrDrawContext::drawRRect(const GrClip& clip, shaderCaps)); if (batch) { GrPipelineBuilder pipelineBuilder(paint, useHWAA); - this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch); + this->getDrawTarget()->drawBatch(pipelineBuilder, this, *clip, batch); return; } } @@ -831,7 +843,7 @@ void GrDrawContext::drawRRect(const GrClip& clip, SkPath path; path.setIsVolatile(true); path.addRRect(rrect); - this->internalDrawPath(clip, paint, viewMatrix, path, style); + this->internalDrawPath(*clip, paint, viewMatrix, path, style); } bool GrDrawContext::drawFilledDRRect(const GrClip& clip, |