Refactor stencil clip mask generation into helper
Change-Id: If3dc80efde3b44e87ba8e7af3a258896ec5e78e6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/288977
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index a90c7a4..469b7f9 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -17,6 +17,7 @@
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/GrStencilClip.h"
+#include "src/gpu/GrStencilMaskHelper.h"
#include "src/gpu/GrStencilSettings.h"
#include "src/gpu/GrStyle.h"
#include "src/gpu/GrUserStencilSettings.h"
@@ -711,16 +712,6 @@
return false;
}
-static void stencil_device_rect(GrRenderTargetContext* rtc,
- const GrHardClip& clip,
- const GrUserStencilSettings* ss,
- GrAA aa,
- const SkRect& rect) {
- GrPaint paint;
- paint.setXPFactory(GrDisableColorXPFactory::Get());
- rtc->priv().stencilRect(clip, ss, std::move(paint), aa, SkMatrix::I(), rect);
-}
-
static void draw_element(GrRenderTargetContext* rtc,
const GrClip& clip, // TODO: can this just always be WideOpen?
GrPaint&& paint,
@@ -822,153 +813,32 @@
bool GrReducedClip::drawStencilClipMask(GrRecordingContext* context,
GrRenderTargetContext* renderTargetContext) const {
- // We set the current clip to the bounds so that our recursive draws are scissored to them.
- GrStencilClip stencilClip(fScissor, this->maskGenID());
-
- if (!fWindowRects.empty()) {
- stencilClip.fixedClip().setWindowRectangles(fWindowRects,
- GrWindowRectsState::Mode::kExclusive);
+ GrStencilMaskHelper helper(context, renderTargetContext);
+ if (!helper.init(fScissor, this->maskGenID(), fWindowRects, this->numAnalyticFPs())) {
+ // The stencil mask doesn't need updating
+ return true;
}
- bool initialState = InitialState::kAllIn == this->initialState();
- renderTargetContext->priv().clearStencilClip(stencilClip.fixedClip(), initialState);
+ helper.clear(InitialState::kAllIn == this->initialState());
// walk through each clip element and perform its set op with the existing clip.
for (ElementList::Iter iter(fMaskElements); iter.get(); iter.next()) {
const Element* element = iter.get();
- // MIXED SAMPLES TODO: We can use stencil with mixed samples as well.
- bool doStencilMSAA = element->isAA() && renderTargetContext->numSamples() > 1;
- // Since we are only drawing to the stencil buffer, we can use kMSAA even if the render
- // target is mixed sampled.
- auto pathAAType = (doStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone;
- bool fillInverted = false;
-
- // This will be used to determine whether the clip shape can be rendered into the
- // stencil with arbitrary stencil settings.
- GrPathRenderer::StencilSupport stencilSupport;
-
SkRegion::Op op = (SkRegion::Op)element->getOp();
+ GrAA aa = element->isAA() ? GrAA::kYes : GrAA::kNo;
- GrPathRenderer* pr = nullptr;
- SkPath clipPath;
if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) {
- stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
- fillInverted = false;
+ helper.drawRect(element->getDeviceSpaceRect(), SkMatrix::I(), op, aa);
} else {
- element->asDeviceSpacePath(&clipPath);
- fillInverted = clipPath.isInverseFillType();
- if (fillInverted) {
- clipPath.toggleInverseFillType();
- }
-
- GrStyledShape shape(clipPath, GrStyle::SimpleFill());
- GrPathRenderer::CanDrawPathArgs canDrawArgs;
- canDrawArgs.fCaps = context->priv().caps();
- canDrawArgs.fProxy = renderTargetContext->asRenderTargetProxy();
- canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
- canDrawArgs.fViewMatrix = &SkMatrix::I();
- canDrawArgs.fShape = &shape;
- canDrawArgs.fPaint = nullptr;
- canDrawArgs.fAAType = pathAAType;
- canDrawArgs.fHasUserStencilSettings = false;
- canDrawArgs.fTargetIsWrappedVkSecondaryCB = renderTargetContext->wrapsVkSecondaryCB();
-
- GrDrawingManager* dm = context->priv().drawingManager();
- pr = dm->getPathRenderer(canDrawArgs, false, GrPathRendererChain::DrawType::kStencil,
- &stencilSupport);
- if (!pr) {
+ SkPath path;
+ element->asDeviceSpacePath(&path);
+ if (!helper.drawPath(path, SkMatrix::I(), op, aa)) {
return false;
}
}
-
- bool canRenderDirectToStencil =
- GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
- bool drawDirectToClip; // Given the renderer, the element,
- // fill rule, and set operation should
- // we render the element directly to
- // stencil bit used for clipping.
- GrUserStencilSettings const* const* stencilPasses =
- GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, fillInverted,
- &drawDirectToClip);
-
- // draw the element to the client stencil bits if necessary
- if (!drawDirectToClip) {
- static constexpr GrUserStencilSettings kDrawToStencil(
- GrUserStencilSettings::StaticInit<
- 0x0000,
- GrUserStencilTest::kAlways,
- 0xffff,
- GrUserStencilOp::kIncMaybeClamp,
- GrUserStencilOp::kIncMaybeClamp,
- 0xffff>()
- );
- if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) {
- stencil_device_rect(renderTargetContext, stencilClip.fixedClip(), &kDrawToStencil,
- GrAA(doStencilMSAA), element->getDeviceSpaceRect());
- } else {
- if (!clipPath.isEmpty()) {
- GrStyledShape shape(clipPath, GrStyle::SimpleFill());
- if (canRenderDirectToStencil) {
- GrPaint paint;
- paint.setXPFactory(GrDisableColorXPFactory::Get());
-
- GrPathRenderer::DrawPathArgs args{context,
- std::move(paint),
- &kDrawToStencil,
- renderTargetContext,
- &stencilClip.fixedClip(),
- &stencilClip.fixedClip().scissorRect(),
- &SkMatrix::I(),
- &shape,
- pathAAType,
- false};
- pr->drawPath(args);
- } else {
- GrPathRenderer::StencilPathArgs args;
- args.fContext = context;
- args.fRenderTargetContext = renderTargetContext;
- args.fClip = &stencilClip.fixedClip();
- args.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
- args.fViewMatrix = &SkMatrix::I();
- args.fDoStencilMSAA = GrAA(doStencilMSAA);
- args.fShape = &shape;
- pr->stencilPath(args);
- }
- }
- }
- }
-
- // now we modify the clip bit by rendering either the clip
- // element directly or a bounding rect of the entire clip.
- for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
- if (drawDirectToClip) {
- if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) {
- stencil_device_rect(renderTargetContext, stencilClip, *pass,
- GrAA(doStencilMSAA), element->getDeviceSpaceRect());
- } else {
- GrStyledShape shape(clipPath, GrStyle::SimpleFill());
- GrPaint paint;
- paint.setXPFactory(GrDisableColorXPFactory::Get());
- GrPathRenderer::DrawPathArgs args{context,
- std::move(paint),
- *pass,
- renderTargetContext,
- &stencilClip,
- &stencilClip.fixedClip().scissorRect(),
- &SkMatrix::I(),
- &shape,
- pathAAType,
- false};
- pr->drawPath(args);
- }
- } else {
- // The view matrix is setup to do clip space -> stencil space translation, so
- // draw rect in clip space.
- stencil_device_rect(renderTargetContext, stencilClip, *pass, GrAA(doStencilMSAA),
- SkRect::Make(fScissor));
- }
- }
}
+
+ helper.finish();
return true;
}