Index: src/gpu/GrClipStackClip.cpp |
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp |
index 7138f4b68a1d42bf6211b2a9f1dd36adf556a494..41a639705c1b2c8d0869fa235f89887416015a2d 100644 |
--- a/src/gpu/GrClipStackClip.cpp |
+++ b/src/gpu/GrClipStackClip.cpp |
@@ -468,10 +468,12 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, |
// The texture may be larger than necessary, this rect represents the part of the texture |
// we populate with a rasterization of the clip. |
SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip.height()); |
+ GrFixedClip clip(maskSpaceIBounds); |
// The scratch texture that we are drawing into can be substantially larger than the mask. Only |
// clear the part that we care about. |
- dc->clear(&maskSpaceIBounds, InitialState::kAllIn == reducedClip.initialState() ? -1 : 0, true); |
+ GrColor initialCoverage = InitialState::kAllIn == reducedClip.initialState() ? -1 : 0; |
+ dc->drawContextPriv().clear(clip, initialCoverage, true); |
// Set the matrix so that rendered clip elements are transformed to mask space from clip |
// space. |
@@ -488,8 +490,6 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, |
SkRegion::Op op = element->getOp(); |
bool invert = element->isInverseFilled(); |
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { |
- GrFixedClip clip(maskSpaceIBounds); |
- |
// draw directly into the result with the stencil set to make the pixels affected |
// by the clip shape be non-zero. |
static constexpr GrUserStencilSettings kStencilInElement( |
@@ -539,8 +539,33 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, |
} |
//////////////////////////////////////////////////////////////////////////////// |
-// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
-// (as opposed to canvas) coordinates |
+// Create a 1-bit clip mask in the stencil buffer. |
+ |
+class StencilFixedClip final : public GrFixedClip { |
+public: |
+ StencilFixedClip(const SkIRect& scissorRect) : INHERITED(scissorRect), fUseClipBit(false) {} |
+ void useClipBit(bool use) { fUseClipBit = use; } |
+ |
+private: |
+ bool quickContains(const SkRect& rect) const override { |
+ return fUseClipBit ? false : INHERITED::quickContains(rect); |
+ } |
+ bool apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA, |
+ bool hasUserStencilSettings, GrAppliedClip* out) const override { |
+ if (!INHERITED::apply(context, drawContext, useHWAA, hasUserStencilSettings, out)) { |
+ return false; |
+ } |
+ if (fUseClipBit) { |
+ out->addStencilClip(); |
+ } |
+ return true; |
+ } |
+ |
+ bool fUseClipBit; |
+ |
+ typedef GrFixedClip INHERITED; |
+}; |
+ |
bool GrClipStackClip::CreateStencilClipMask(GrContext* context, |
GrDrawContext* drawContext, |
const GrReducedClip& reducedClip, |
@@ -569,10 +594,10 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, |
// We set the current clip to the bounds so that our recursive draws are scissored to them. |
SkIRect stencilSpaceIBounds(reducedClip.ibounds()); |
stencilSpaceIBounds.offset(clipSpaceToStencilOffset); |
- GrFixedClip clip(stencilSpaceIBounds); |
+ StencilFixedClip clip(stencilSpaceIBounds); |
- bool insideClip = InitialState::kAllIn == reducedClip.initialState(); |
- drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, insideClip); |
+ bool initialState = InitialState::kAllIn == reducedClip.initialState(); |
+ drawContext->drawContextPriv().clearStencilClip(clip, initialState); |
// walk through each clip element and perform its set op |
// with the existing clip. |
@@ -582,7 +607,7 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, |
bool fillInverted = false; |
// enabled at bottom of loop |
- clip.disableStencilClip(); |
+ clip.useClipBit(false); |
// This will be used to determine whether the clip shape can be rendered into the |
// stencil with arbitrary stencil settings. |
@@ -677,8 +702,9 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, |
} |
} |
- // Just enable stencil clip. The passes choose whether or not they will actually use it. |
- clip.enableStencilClip(); |
+ // This doesn't mean the current pass will be clipped by the stencil buffer. That is |
+ // decided by GrUserStencilSettings. This just tells it there is data in the clip bit. |
+ clip.useClipBit(true); |
// now we modify the clip bit by rendering either the clip |
// element directly or a bounding rect of the entire clip. |