Move user stencil settings from GrPipeline to GrProgramInfo
Bug: skia:10419
Change-Id: If11d28f6d9348ba0011825f719123c09f0103603
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/319481
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/gm/tessellation.cpp b/gm/tessellation.cpp
index 34c58cc..4e300aa 100644
--- a/gm/tessellation.cpp
+++ b/gm/tessellation.cpp
@@ -345,8 +345,9 @@
GrProgramInfo programInfo(state->proxy()->numSamples(), state->proxy()->numStencilSamples(),
state->proxy()->backendFormat(), state->writeView()->origin(),
- &pipeline, shader.get(), GrPrimitiveType::kPatches,
- tessellationPatchVertexCount, state->renderPassBarriers());
+ &pipeline, &GrUserStencilSettings::kUnused, shader.get(),
+ GrPrimitiveType::kPatches, tessellationPatchVertexCount,
+ state->renderPassBarriers());
state->bindPipeline(programInfo, SkRect::MakeIWH(kWidth, kHeight));
state->bindBuffers(nullptr, nullptr, std::move(fVertexBuffer));
diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp
index 89434d4..2201b65 100644
--- a/src/gpu/GrOpFlushState.cpp
+++ b/src/gpu/GrOpFlushState.cpp
@@ -35,7 +35,8 @@
}
void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(
- const GrOp* op, const SkRect& chainBounds, const GrPipeline* pipeline) {
+ const GrOp* op, const SkRect& chainBounds, const GrPipeline* pipeline,
+ const GrUserStencilSettings* userStencilSettings) {
SkASSERT(this->opsRenderPass());
while (fCurrDraw != fDraws.end() && fCurrDraw->fOp == op) {
@@ -51,6 +52,7 @@
this->proxy()->backendFormat(),
this->writeView()->origin(),
pipeline,
+ userStencilSettings,
fCurrDraw->fGeometryProcessor,
fCurrDraw->fPrimitiveType,
0,
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index f833ef2..84d0bc9 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -46,7 +46,7 @@
/** Called as ops are executed. Must be called in the same order as the ops were prepared. */
void executeDrawsAndUploadsForMeshDrawOp(const GrOp* op, const SkRect& chainBounds,
- const GrPipeline*);
+ const GrPipeline*, const GrUserStencilSettings*);
GrOpsRenderPass* opsRenderPass() { return fOpsRenderPass; }
void setOpsRenderPass(GrOpsRenderPass* renderPass) { fOpsRenderPass = renderPass; }
diff --git a/src/gpu/GrOpsRenderPass.cpp b/src/gpu/GrOpsRenderPass.cpp
index cd329de..4dde2cc 100644
--- a/src/gpu/GrOpsRenderPass.cpp
+++ b/src/gpu/GrOpsRenderPass.cpp
@@ -77,8 +77,8 @@
SkASSERT(this->gpu()->caps()->wireframeSupport());
}
if (this->gpu()->caps()->twoSidedStencilRefsAndMasksMustMatch() &&
- programInfo.pipeline().isStencilEnabled()) {
- const GrUserStencilSettings* stencil = programInfo.pipeline().getUserStencil();
+ programInfo.isStencilEnabled()) {
+ const GrUserStencilSettings* stencil = programInfo.userStencilSettings();
if (stencil->isTwoSided(programInfo.pipeline().hasStencilClip())) {
SkASSERT(stencil->fCCWFace.fRef == stencil->fCWFace.fRef);
SkASSERT(stencil->fCCWFace.fTestMask == stencil->fCWFace.fTestMask);
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index a16ee31..39e3f06 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -28,7 +28,6 @@
}
fWindowRectsState = hardClip.windowRectsState();
- this->setUserStencil(args.fUserStencil);
fXferProcessor = std::move(xferProcessor);
@@ -74,8 +73,7 @@
GrPipeline::GrPipeline(GrScissorTest scissorTest,
sk_sp<const GrXferProcessor> xp,
const GrSwizzle& writeSwizzle,
- InputFlags inputFlags,
- const GrUserStencilSettings* userStencil)
+ InputFlags inputFlags)
: fWindowRectsState()
, fFlags((Flags)inputFlags)
, fXferProcessor(std::move(xp))
@@ -83,7 +81,6 @@
if (GrScissorTest::kEnabled == scissorTest) {
fFlags |= Flags::kScissorTestEnabled;
}
- this->setUserStencil(userStencil);
}
void GrPipeline::genKey(GrProcessorKeyBuilder* b, const GrCaps& caps) const {
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index 43f278d..fcc35d2 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -67,7 +67,6 @@
struct InitArgs {
InputFlags fInputFlags = InputFlags::kNone;
- const GrUserStencilSettings* fUserStencil = &GrUserStencilSettings::kUnused;
const GrCaps* fCaps = nullptr;
GrXferProcessor::DstProxyView fDstProxyView;
GrSwizzle fWriteSwizzle;
@@ -81,19 +80,16 @@
GrPipeline(GrScissorTest scissor,
SkBlendMode blend,
const GrSwizzle& writeSwizzle,
- InputFlags flags = InputFlags::kNone,
- const GrUserStencilSettings* stencil = &GrUserStencilSettings::kUnused)
+ InputFlags flags = InputFlags::kNone)
: GrPipeline(scissor,
GrPorterDuffXPFactory::MakeNoCoverageXP(blend),
writeSwizzle,
- flags,
- stencil) {}
+ flags) {}
GrPipeline(GrScissorTest,
sk_sp<const GrXferProcessor>,
const GrSwizzle& writeSwizzle,
- InputFlags = InputFlags::kNone,
- const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
+ InputFlags = InputFlags::kNone);
GrPipeline(const InitArgs& args, sk_sp<const GrXferProcessor>, const GrAppliedHardClip&);
GrPipeline(const InitArgs&, GrProcessorSet&&, GrAppliedClip&&);
@@ -167,14 +163,6 @@
/// @}
- const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
- void setUserStencil(const GrUserStencilSettings* stencil) {
- fUserStencilSettings = stencil;
- if (!fUserStencilSettings->isDisabled(fFlags & Flags::kHasStencilClip)) {
- fFlags |= Flags::kStencilEnabled;
- }
- }
-
bool isScissorTestEnabled() const {
return SkToBool(fFlags & Flags::kScissorTestEnabled);
}
@@ -190,9 +178,6 @@
bool hasStencilClip() const {
return SkToBool(fFlags & Flags::kHasStencilClip);
}
- bool isStencilEnabled() const {
- return SkToBool(fFlags & Flags::kStencilEnabled);
- }
#ifdef SK_DEBUG
bool allProxiesInstantiated() const {
for (int i = 0; i < fFragmentProcessors.count(); ++i) {
@@ -223,8 +208,7 @@
/** This is a continuation of the public "InputFlags" enum. */
enum class Flags : uint8_t {
kHasStencilClip = (kLastInputFlag << 1),
- kStencilEnabled = (kLastInputFlag << 2),
- kScissorTestEnabled = (kLastInputFlag << 3),
+ kScissorTestEnabled = (kLastInputFlag << 2),
};
GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
@@ -241,7 +225,6 @@
// GrDstSampleType).
GrDstSampleType fDstSampleType = GrDstSampleType::kNone;
GrWindowRectsState fWindowRectsState;
- const GrUserStencilSettings* fUserStencilSettings;
Flags fFlags;
sk_sp<const GrXferProcessor> fXferProcessor;
FragmentProcessorArray fFragmentProcessors;
diff --git a/src/gpu/GrProgramInfo.cpp b/src/gpu/GrProgramInfo.cpp
index 9256fff..85f5121 100644
--- a/src/gpu/GrProgramInfo.cpp
+++ b/src/gpu/GrProgramInfo.cpp
@@ -12,10 +12,8 @@
GrStencilSettings GrProgramInfo::nonGLStencilSettings() const {
GrStencilSettings stencil;
- if (this->pipeline().isStencilEnabled()) {
- stencil.reset(*this->pipeline().getUserStencil(),
- this->pipeline().hasStencilClip(),
- 8);
+ if (this->isStencilEnabled()) {
+ stencil.reset(*fUserStencilSettings, this->pipeline().hasStencilClip(), 8);
}
return stencil;
diff --git a/src/gpu/GrProgramInfo.h b/src/gpu/GrProgramInfo.h
index cbcce48..be0f77d 100644
--- a/src/gpu/GrProgramInfo.h
+++ b/src/gpu/GrProgramInfo.h
@@ -21,20 +21,22 @@
const GrBackendFormat& backendFormat,
GrSurfaceOrigin origin,
const GrPipeline* pipeline,
+ const GrUserStencilSettings* userStencilSettings,
const GrPrimitiveProcessor* primProc,
GrPrimitiveType primitiveType,
uint8_t tessellationPatchVertexCount,
GrXferBarrierFlags renderPassXferBarriers)
: fNumSamples(numSamples)
, fNumStencilSamples(numStencilSamples)
- , fIsMixedSampled(pipeline->isStencilEnabled() && numStencilSamples > numSamples)
, fBackendFormat(backendFormat)
, fOrigin(origin)
, fPipeline(pipeline)
+ , fUserStencilSettings(userStencilSettings)
, fPrimProc(primProc)
, fPrimitiveType(primitiveType)
, fTessellationPatchVertexCount(tessellationPatchVertexCount)
- , fRenderPassXferBarriers(renderPassXferBarriers) {
+ , fRenderPassXferBarriers(renderPassXferBarriers)
+ , fIsMixedSampled(this->isStencilEnabled() && numStencilSamples > numSamples) {
SkASSERT(this->numRasterSamples() > 0);
SkASSERT((GrPrimitiveType::kPatches == fPrimitiveType) ==
(fTessellationPatchVertexCount > 0));
@@ -51,10 +53,13 @@
int numSamples() const { return fNumSamples; }
int numStencilSamples() const { return fNumStencilSamples; }
- bool isStencilEnabled() const { return fPipeline->isStencilEnabled(); }
-
+ bool isStencilEnabled() const {
+ return fUserStencilSettings != &GrUserStencilSettings::kUnused ||
+ fPipeline->hasStencilClip();
+ }
+ const GrUserStencilSettings* userStencilSettings() const { return fUserStencilSettings; }
int numRasterSamples() const {
- return fPipeline->isStencilEnabled() ? fNumStencilSamples : fNumSamples;
+ return this->isStencilEnabled() ? fNumStencilSamples : fNumSamples;
}
bool isMixedSampled() const { return fIsMixedSampled; }
// The backend format of the destination render target [proxy]
@@ -97,15 +102,16 @@
private:
const int fNumSamples;
const int fNumStencilSamples;
- const bool fIsMixedSampled;
const GrBackendFormat fBackendFormat;
const GrSurfaceOrigin fOrigin;
const GrPipeline* fPipeline;
+ const GrUserStencilSettings* fUserStencilSettings;
const GrPrimitiveProcessor* fPrimProc;
GrProcessor::CustomFeatures fRequestedFeatures;
GrPrimitiveType fPrimitiveType;
uint8_t fTessellationPatchVertexCount; // GrPrimType::kPatches.
GrXferBarrierFlags fRenderPassXferBarriers;
+ const bool fIsMixedSampled;
};
#endif
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index 782cc23..5c382e2 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -196,11 +196,12 @@
}
void GrCCCoverageProcessor::bindPipeline(GrOpFlushState* flushState, const GrPipeline& pipeline,
- const SkRect& drawBounds) const {
+ const SkRect& drawBounds,
+ const GrUserStencilSettings* stencil) const {
GrProgramInfo programInfo(flushState->proxy()->numSamples(),
flushState->proxy()->numStencilSamples(),
flushState->proxy()->backendFormat(),
- flushState->writeView()->origin(), &pipeline, this,
+ flushState->writeView()->origin(), &pipeline, stencil, this,
this->primType(), 0, flushState->renderPassBarriers());
flushState->bindPipeline(programInfo, drawBounds);
}
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index c7a9639..8b4821f 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -111,7 +111,8 @@
// subpassIdx of each PrimitiveType, it calls reset/bind*/drawInstances.
virtual int numSubpasses() const = 0;
virtual void reset(PrimitiveType, int subpassIdx, GrResourceProvider*) = 0;
- void bindPipeline(GrOpFlushState*, const GrPipeline&, const SkRect& drawBounds) const;
+ void bindPipeline(GrOpFlushState*, const GrPipeline&, const SkRect& drawBounds,
+ const GrUserStencilSettings* = &GrUserStencilSettings::kUnused) const;
virtual void bindBuffers(GrOpsRenderPass*, sk_sp<const GrBuffer> instanceBuffer) const = 0;
virtual void drawInstances(GrOpsRenderPass*, int instanceCount, int baseInstance) const = 0;
diff --git a/src/gpu/ccpr/GrCCFiller.cpp b/src/gpu/ccpr/GrCCFiller.cpp
index 783be74..27250cc 100644
--- a/src/gpu/ccpr/GrCCFiller.cpp
+++ b/src/gpu/ccpr/GrCCFiller.cpp
@@ -472,7 +472,7 @@
void GrCCFiller::drawFills(
GrOpFlushState* flushState, GrCCCoverageProcessor* proc, const GrPipeline& pipeline,
- BatchID batchID, const SkIRect& drawBounds) const {
+ BatchID batchID, const SkIRect& drawBounds, const GrUserStencilSettings* stencil) const {
using PrimitiveType = GrCCCoverageProcessor::PrimitiveType;
SkASSERT(fInstanceBuffer.hasGpuBuffer());
@@ -485,7 +485,7 @@
if (batchTotalCounts.fTriangles) {
for (int i = 0; i < numSubpasses; ++i) {
proc->reset(PrimitiveType::kTriangles, i, rp);
- this->drawPrimitives(flushState, *proc, pipeline, batchID,
+ this->drawPrimitives(flushState, *proc, pipeline, stencil, batchID,
&PrimitiveTallies::fTriangles, drawBounds);
}
}
@@ -494,7 +494,7 @@
SkASSERT(Algorithm::kStencilWindingCount != fAlgorithm);
for (int i = 0; i < numSubpasses; ++i) {
proc->reset(PrimitiveType::kWeightedTriangles, i, rp);
- this->drawPrimitives(flushState, *proc, pipeline, batchID,
+ this->drawPrimitives(flushState, *proc, pipeline, stencil, batchID,
&PrimitiveTallies::fWeightedTriangles, drawBounds);
}
}
@@ -502,7 +502,7 @@
if (batchTotalCounts.fQuadratics) {
for (int i = 0; i < numSubpasses; ++i) {
proc->reset(PrimitiveType::kQuadratics, i, rp);
- this->drawPrimitives(flushState, *proc, pipeline, batchID,
+ this->drawPrimitives(flushState, *proc, pipeline, stencil, batchID,
&PrimitiveTallies::fQuadratics, drawBounds);
}
}
@@ -510,27 +510,28 @@
if (batchTotalCounts.fCubics) {
for (int i = 0; i < numSubpasses; ++i) {
proc->reset(PrimitiveType::kCubics, i, rp);
- this->drawPrimitives(flushState, *proc, pipeline, batchID, &PrimitiveTallies::fCubics,
- drawBounds);
+ this->drawPrimitives(flushState, *proc, pipeline, stencil, batchID,
+ &PrimitiveTallies::fCubics, drawBounds);
}
}
if (batchTotalCounts.fConics) {
for (int i = 0; i < numSubpasses; ++i) {
proc->reset(PrimitiveType::kConics, i, rp);
- this->drawPrimitives(flushState, *proc, pipeline, batchID, &PrimitiveTallies::fConics,
- drawBounds);
+ this->drawPrimitives(flushState, *proc, pipeline, stencil, batchID,
+ &PrimitiveTallies::fConics, drawBounds);
}
}
}
void GrCCFiller::drawPrimitives(
GrOpFlushState* flushState, const GrCCCoverageProcessor& proc, const GrPipeline& pipeline,
- BatchID batchID, int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const {
+ const GrUserStencilSettings* stencil, BatchID batchID, int PrimitiveTallies::*instanceType,
+ const SkIRect& drawBounds) const {
SkASSERT(pipeline.isScissorTestEnabled());
GrOpsRenderPass* renderPass = flushState->opsRenderPass();
- proc.bindPipeline(flushState, pipeline, SkRect::Make(drawBounds));
+ proc.bindPipeline(flushState, pipeline, SkRect::Make(drawBounds), stencil);
proc.bindBuffers(renderPass, fInstanceBuffer.gpuBuffer());
SkASSERT(batchID > 0);
diff --git a/src/gpu/ccpr/GrCCFiller.h b/src/gpu/ccpr/GrCCFiller.h
index f90bc85..b27ea7b 100644
--- a/src/gpu/ccpr/GrCCFiller.h
+++ b/src/gpu/ccpr/GrCCFiller.h
@@ -51,7 +51,8 @@
// Called after prepareToDraw(). Draws the given batch of path fills.
void drawFills(GrOpFlushState*, GrCCCoverageProcessor*, const GrPipeline&, BatchID,
- const SkIRect& drawBounds) const;
+ const SkIRect& drawBounds,
+ const GrUserStencilSettings* = &GrUserStencilSettings::kUnused) const;
private:
static constexpr int kNumScissorModes = 2;
@@ -107,7 +108,8 @@
GrCCCoverageProcessor::TriPointInstance::Ordering,
GrCCCoverageProcessor::TriPointInstance*, GrCCCoverageProcessor::QuadPointInstance*,
GrCCFillGeometry::PrimitiveTallies*);
- void drawPrimitives(GrOpFlushState*, const GrCCCoverageProcessor&, const GrPipeline&, BatchID,
+ void drawPrimitives(GrOpFlushState*, const GrCCCoverageProcessor&, const GrPipeline&,
+ const GrUserStencilSettings*, BatchID,
int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const;
const Algorithm fAlgorithm;
diff --git a/src/gpu/ccpr/GrCCPathProcessor.cpp b/src/gpu/ccpr/GrCCPathProcessor.cpp
index d381274..fcae131 100644
--- a/src/gpu/ccpr/GrCCPathProcessor.cpp
+++ b/src/gpu/ccpr/GrCCPathProcessor.cpp
@@ -147,7 +147,7 @@
GrRenderTargetProxy* rtProxy = flushState->proxy();
GrProgramInfo programInfo(rtProxy->numSamples(), rtProxy->numStencilSamples(),
rtProxy->backendFormat(), flushState->writeView()->origin(),
- &pipeline, this, primitiveType, 0,
+ &pipeline, &GrUserStencilSettings::kUnused, this, primitiveType, 0,
flushState->renderPassBarriers());
flushState->bindPipelineAndScissorClip(programInfo, bounds);
diff --git a/src/gpu/ccpr/GrCCStroker.cpp b/src/gpu/ccpr/GrCCStroker.cpp
index a6b00f8..debb8d4 100644
--- a/src/gpu/ccpr/GrCCStroker.cpp
+++ b/src/gpu/ccpr/GrCCStroker.cpp
@@ -729,9 +729,9 @@
GrProgramInfo programInfo(flushState->proxy()->numSamples(),
flushState->proxy()->numStencilSamples(),
flushState->proxy()->backendFormat(),
- flushState->writeView()->origin(), &pipeline, &processor,
- GrPrimitiveType::kTriangleStrip, 0,
- flushState->renderPassBarriers());
+ flushState->writeView()->origin(), &pipeline,
+ &GrUserStencilSettings::kUnused, &processor,
+ GrPrimitiveType::kTriangleStrip, 0, flushState->renderPassBarriers());
flushState->bindPipeline(programInfo, SkRect::Make(drawBounds));
flushState->bindBuffers(nullptr, fInstanceBuffer, nullptr);
diff --git a/src/gpu/ccpr/GrStencilAtlasOp.cpp b/src/gpu/ccpr/GrStencilAtlasOp.cpp
index bee43b0..ba6c88e 100644
--- a/src/gpu/ccpr/GrStencilAtlasOp.cpp
+++ b/src/gpu/ccpr/GrStencilAtlasOp.cpp
@@ -142,15 +142,12 @@
GrPipeline pipeline(GrScissorTest::kEnabled, GrDisableColorXPFactory::MakeXferProcessor(),
flushState->drawOpArgs().writeSwizzle(),
- GrPipeline::InputFlags::kHWAntialias, &kIncrDecrStencil);
+ GrPipeline::InputFlags::kHWAntialias);
GrSampleMaskProcessor sampleMaskProc;
fResources->filler().drawFills(
- flushState, &sampleMaskProc, pipeline, fFillBatchID, drawBoundsRect);
-
- fResources->stroker().drawStrokes(
- flushState, &sampleMaskProc, fStrokeBatchID, drawBoundsRect);
+ flushState, &sampleMaskProc, pipeline, fFillBatchID, drawBoundsRect, &kIncrDecrStencil);
// We resolve the stencil coverage to alpha by drawing pixel-aligned boxes. Fine raster is
// not necessary, and will even cause artifacts if using mixed samples.
@@ -161,12 +158,10 @@
StencilResolveProcessor primProc;
if (!flushState->caps().twoSidedStencilRefsAndMasksMustMatch()) {
- if (flushState->caps().discardStencilValuesAfterRenderPass()) {
- resolvePipeline.setUserStencil(&kResolveStencilCoverage);
- } else {
- resolvePipeline.setUserStencil(&kResolveStencilCoverageAndReset);
- }
- this->drawResolve(flushState, resolvePipeline, primProc, drawBoundsRect);
+ const GrUserStencilSettings* stencil =
+ (flushState->caps().discardStencilValuesAfterRenderPass()) ?
+ &kResolveStencilCoverage : &kResolveStencilCoverageAndReset;
+ this->drawResolve(flushState, resolvePipeline, stencil, primProc, drawBoundsRect);
return;
}
@@ -174,21 +169,21 @@
// don't reset back to zero.
SkASSERT(!flushState->caps().discardStencilValuesAfterRenderPass());
- resolvePipeline.setUserStencil(&kResolveWindingCoverageAndReset);
- this->drawResolve(flushState, resolvePipeline, primProc, drawBoundsRect);
-
- resolvePipeline.setUserStencil(&kResolveEvenOddCoverageAndReset);
- this->drawResolve(flushState, resolvePipeline, primProc, drawBoundsRect);
+ this->drawResolve(flushState, resolvePipeline, &kResolveWindingCoverageAndReset, primProc,
+ drawBoundsRect);
+ this->drawResolve(flushState, resolvePipeline, &kResolveEvenOddCoverageAndReset, primProc,
+ drawBoundsRect);
}
void GrStencilAtlasOp::drawResolve(GrOpFlushState* flushState, const GrPipeline& resolvePipeline,
+ const GrUserStencilSettings* stencil,
const GrPrimitiveProcessor& primProc,
const SkIRect& drawBounds) const {
GrProgramInfo programInfo(flushState->proxy()->numSamples(),
flushState->proxy()->numStencilSamples(),
flushState->proxy()->backendFormat(),
- flushState->writeView()->origin(), &resolvePipeline, &primProc,
- GrPrimitiveType::kTriangleStrip, 0,
+ flushState->writeView()->origin(), &resolvePipeline, stencil,
+ &primProc, GrPrimitiveType::kTriangleStrip, 0,
flushState->renderPassBarriers());
flushState->bindPipeline(programInfo, SkRect::Make(drawBounds));
flushState->setScissorRect(drawBounds);
diff --git a/src/gpu/ccpr/GrStencilAtlasOp.h b/src/gpu/ccpr/GrStencilAtlasOp.h
index d749dc4..72ab6b3 100644
--- a/src/gpu/ccpr/GrStencilAtlasOp.h
+++ b/src/gpu/ccpr/GrStencilAtlasOp.h
@@ -60,8 +60,8 @@
GrXferBarrierFlags renderPassXferBarriers) override {}
void onPrepare(GrOpFlushState*) override {}
void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
- void drawResolve(GrOpFlushState*, const GrPipeline&, const GrPrimitiveProcessor&,
- const SkIRect& drawBounds) const;
+ void drawResolve(GrOpFlushState*, const GrPipeline&, const GrUserStencilSettings*,
+ const GrPrimitiveProcessor&, const SkIRect& drawBounds) const;
friend class ::GrOpMemoryPool; // for ctor
diff --git a/src/gpu/dawn/GrDawnOpsRenderPass.cpp b/src/gpu/dawn/GrDawnOpsRenderPass.cpp
index 700aef5..552b134 100644
--- a/src/gpu/dawn/GrDawnOpsRenderPass.cpp
+++ b/src/gpu/dawn/GrDawnOpsRenderPass.cpp
@@ -120,10 +120,10 @@
auto bindGroup = program->setUniformData(fGpu, fRenderTarget, programInfo);
fPassEncoder.SetPipeline(program->fRenderPipeline);
fPassEncoder.SetBindGroup(0, bindGroup, 0, nullptr);
- const GrPipeline& pipeline = programInfo.pipeline();
- if (pipeline.isStencilEnabled()) {
- fPassEncoder.SetStencilReference(pipeline.getUserStencil()->fCCWFace.fRef);
+ if (programInfo.isStencilEnabled()) {
+ fPassEncoder.SetStencilReference(programInfo.userStencilSettings()->fCCWFace.fRef);
}
+ const GrPipeline& pipeline = programInfo.pipeline();
GrXferProcessor::BlendInfo blendInfo = pipeline.getXferProcessor().getBlendInfo();
const float* c = blendInfo.fBlendConstant.vec();
wgpu::Color color{c[0], c[1], c[2], c[3]};
diff --git a/src/gpu/dawn/GrDawnProgramBuilder.cpp b/src/gpu/dawn/GrDawnProgramBuilder.cpp
index 5242941..62965f1 100644
--- a/src/gpu/dawn/GrDawnProgramBuilder.cpp
+++ b/src/gpu/dawn/GrDawnProgramBuilder.cpp
@@ -351,7 +351,7 @@
wgpu::DepthStencilStateDescriptor depthStencilState;
#ifdef SK_DEBUG
- if (pipeline.isStencilEnabled()) {
+ if (programInfo.isStencilEnabled()) {
SkASSERT(renderTarget->numStencilBits() == 8);
}
#endif
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 49115b37..6156086 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1864,9 +1864,9 @@
GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(renderTarget);
GrStencilSettings stencil;
- if (programInfo.pipeline().isStencilEnabled()) {
+ if (programInfo.isStencilEnabled()) {
SkASSERT(glRT->getStencilAttachment());
- stencil.reset(*programInfo.pipeline().getUserStencil(),
+ stencil.reset(*programInfo.userStencilSettings(),
programInfo.pipeline().hasStencilClip(),
glRT->numStencilBits());
}
diff --git a/src/gpu/mtl/GrMtlCaps.mm b/src/gpu/mtl/GrMtlCaps.mm
index 340992c..695e412 100644
--- a/src/gpu/mtl/GrMtlCaps.mm
+++ b/src/gpu/mtl/GrMtlCaps.mm
@@ -1035,14 +1035,14 @@
b.add32(programInfo.numRasterSamples());
#ifdef SK_DEBUG
- if (rt && programInfo.pipeline().isStencilEnabled()) {
+ if (rt && programInfo.isStencilEnabled()) {
SkASSERT(rt->getStencilAttachment());
}
#endif
b.add32(rt && rt->getStencilAttachment() ? this->preferredStencilFormat().fInternalFormat
: MTLPixelFormatInvalid);
- b.add32((uint32_t)programInfo.pipeline().isStencilEnabled());
+ b.add32((uint32_t)programInfo.isStencilEnabled());
// Stencil samples don't seem to be tracked in the MTLRenderPipeline
programInfo.pipeline().genKey(&b, *this);
diff --git a/src/gpu/mtl/GrMtlPipelineState.mm b/src/gpu/mtl/GrMtlPipelineState.mm
index 7ce78181..500bb1c 100644
--- a/src/gpu/mtl/GrMtlPipelineState.mm
+++ b/src/gpu/mtl/GrMtlPipelineState.mm
@@ -74,7 +74,7 @@
fDataManager.resetDirtyBits();
#ifdef SK_DEBUG
- if (programInfo.pipeline().isStencilEnabled()) {
+ if (programInfo.isStencilEnabled()) {
SkASSERT(renderTarget->getStencilAttachment());
SkASSERT(renderTarget->numStencilBits() == 8);
}
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index bc40662..202cb37 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -1020,7 +1020,7 @@
fProgramInfos[0] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
arena, pipeline, writeView, lineGP, GrPrimitiveType::kTriangles,
- renderPassXferBarriers);
+ renderPassXferBarriers, fHelper.stencilSettings());
}
void AAHairlineOp::makeQuadProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
@@ -1044,7 +1044,7 @@
fProgramInfos[1] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
arena, pipeline, writeView, quadGP, GrPrimitiveType::kTriangles,
- renderPassXferBarriers);
+ renderPassXferBarriers, fHelper.stencilSettings());
}
void AAHairlineOp::makeConicProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
@@ -1068,7 +1068,7 @@
fProgramInfos[2] = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
arena, pipeline, writeView, conicGP, GrPrimitiveType::kTriangles,
- renderPassXferBarriers);
+ renderPassXferBarriers, fHelper.stencilSettings());
}
AAHairlineOp::Program AAHairlineOp::predictPrograms(const GrCaps* caps) const {
@@ -1118,8 +1118,8 @@
geometryProcessorLocalM = &SkMatrix::I();
}
- auto pipeline = fHelper.createPipelineWithStencil(caps, arena, writeView->swizzle(),
- std::move(appliedClip), dstProxyView);
+ auto pipeline = fHelper.createPipeline(caps, arena, writeView->swizzle(),
+ std::move(appliedClip), dstProxyView);
if (fCharacterization & kLine_Program) {
this->makeLineProgramInfo(*caps, arena, pipeline, writeView,
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 4054121..b0762d7 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -271,7 +271,8 @@
std::move(fProcessors),
GrPipeline::InputFlags::kNone);
- flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline);
+ flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline,
+ &GrUserStencilSettings::kUnused);
}
void GrAtlasTextOp::createDrawForGeneratedGlyphs(
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index d49bc52..f56f2ed 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -83,8 +83,7 @@
auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState,
this->detachProcessorSet(),
- pipelineFlags,
- &kCoverPass);
+ pipelineFlags);
sk_sp<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(), this->viewMatrix()));
@@ -94,6 +93,7 @@
proxy->backendFormat(),
flushState->writeView()->origin(),
pipeline,
+ &kCoverPass,
pathProc.get(),
GrPrimitiveType::kPath,
0,
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
index 4a876ec..23bc438 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp
@@ -115,12 +115,10 @@
GrAppliedClip&& appliedClip,
const GrXferProcessor::DstProxyView& dstProxyView,
GrProcessorSet&& processorSet,
- GrPipeline::InputFlags pipelineFlags,
- const GrUserStencilSettings* stencilSettings) {
+ GrPipeline::InputFlags pipelineFlags) {
GrPipeline::InitArgs pipelineArgs;
pipelineArgs.fInputFlags = pipelineFlags;
- pipelineArgs.fUserStencil = stencilSettings;
pipelineArgs.fCaps = caps;
pipelineArgs.fDstProxyView = dstProxyView;
pipelineArgs.fWriteSwizzle = writeViewSwizzle;
@@ -133,16 +131,14 @@
const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(
GrOpFlushState* flushState,
GrProcessorSet&& processorSet,
- GrPipeline::InputFlags pipelineFlags,
- const GrUserStencilSettings* stencilSettings) {
+ GrPipeline::InputFlags pipelineFlags) {
return CreatePipeline(&flushState->caps(),
flushState->allocator(),
flushState->writeView()->swizzle(),
flushState->detachAppliedClip(),
flushState->dstProxyView(),
std::move(processorSet),
- pipelineFlags,
- stencilSettings);
+ pipelineFlags);
}
const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flushState) {
@@ -155,6 +151,21 @@
this->pipelineFlags());
}
+const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(
+ const GrCaps* caps,
+ SkArenaAlloc* arena,
+ GrSwizzle writeViewSwizzle,
+ GrAppliedClip&& appliedClip,
+ const GrXferProcessor::DstProxyView& dstProxyView) {
+ return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
+ arena,
+ writeViewSwizzle,
+ std::move(appliedClip),
+ dstProxyView,
+ this->detachProcessorSet(),
+ this->pipelineFlags());
+}
+
GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(
const GrCaps* caps,
SkArenaAlloc* arena,
@@ -173,11 +184,10 @@
std::move(appliedClip),
dstProxyView,
std::move(processorSet),
- pipelineFlags,
- stencilSettings);
+ pipelineFlags);
return CreateProgramInfo(arena, pipeline, writeView, geometryProcessor, primitiveType,
- renderPassXferBarriers);
+ renderPassXferBarriers, stencilSettings);
}
GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(SkArenaAlloc* arena,
@@ -185,7 +195,8 @@
const GrSurfaceProxyView* writeView,
GrGeometryProcessor* geometryProcessor,
GrPrimitiveType primitiveType,
- GrXferBarrierFlags renderPassXferBarriers) {
+ GrXferBarrierFlags xferBarrierFlags,
+ const GrUserStencilSettings* stencilSettings) {
GrRenderTargetProxy* outputProxy = writeView->asRenderTargetProxy();
auto tmp = arena->make<GrProgramInfo>(outputProxy->numSamples(),
@@ -193,10 +204,11 @@
outputProxy->backendFormat(),
writeView->origin(),
pipeline,
+ stencilSettings,
geometryProcessor,
primitiveType,
0,
- renderPassXferBarriers);
+ xferBarrierFlags);
return tmp;
}
@@ -230,6 +242,12 @@
if (flags & GrPipeline::InputFlags::kHWAntialias) {
result->append("HW Antialiasing enabled.\n");
}
+ if (flags & GrPipeline::InputFlags::kWireframe) {
+ result->append("Wireframe enabled.\n");
+ }
+ if (flags & GrPipeline::InputFlags::kConservativeRaster) {
+ result->append("Conservative raster enabled.\n");
+ }
return;
}
result->append("No pipeline flags\n");
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
index 3ef6d8e..679c6c6 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h
@@ -130,22 +130,28 @@
GrAppliedClip&&,
const GrXferProcessor::DstProxyView&,
GrProcessorSet&&,
- GrPipeline::InputFlags pipelineFlags,
- const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
+ GrPipeline::InputFlags pipelineFlags);
static const GrPipeline* CreatePipeline(
GrOpFlushState*,
GrProcessorSet&&,
- GrPipeline::InputFlags pipelineFlags,
- const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
+ GrPipeline::InputFlags pipelineFlags);
const GrPipeline* createPipeline(GrOpFlushState* flushState);
+ const GrPipeline* createPipeline(const GrCaps*,
+ SkArenaAlloc*,
+ GrSwizzle writeViewSwizzle,
+ GrAppliedClip&&,
+ const GrXferProcessor::DstProxyView&);
+
static GrProgramInfo* CreateProgramInfo(SkArenaAlloc*,
const GrPipeline*,
const GrSurfaceProxyView* writeView,
GrGeometryProcessor*,
GrPrimitiveType,
- GrXferBarrierFlags renderPassXferBarriers);
+ GrXferBarrierFlags renderPassXferBarriers,
+ const GrUserStencilSettings*
+ = &GrUserStencilSettings::kUnused);
// Create a programInfo with the following properties:
// its primitive processor uses no textures
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
index 000b699..bc8353f 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.cpp
@@ -7,31 +7,6 @@
#include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
-const GrPipeline* GrSimpleMeshDrawOpHelperWithStencil::createPipelineWithStencil(
- const GrCaps* caps,
- SkArenaAlloc* arena,
- GrSwizzle writeViewSwizzle,
- GrAppliedClip&& appliedClip,
- const GrXferProcessor::DstProxyView& dstProxyView) {
- return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
- arena,
- writeViewSwizzle,
- std::move(appliedClip),
- dstProxyView,
- this->detachProcessorSet(),
- this->pipelineFlags(),
- this->stencilSettings());
-}
-
-const GrPipeline* GrSimpleMeshDrawOpHelperWithStencil::createPipelineWithStencil(
- GrOpFlushState* flushState) {
- return this->createPipelineWithStencil(&flushState->caps(),
- flushState->allocator(),
- flushState->writeView()->swizzle(),
- flushState->detachAppliedClip(),
- flushState->dstProxyView());
-}
-
GrSimpleMeshDrawOpHelperWithStencil::GrSimpleMeshDrawOpHelperWithStencil(
const MakeArgs& args,
GrAAType aaType,
diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
index b1339ad..2036ae8 100644
--- a/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
+++ b/src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h
@@ -21,14 +21,7 @@
using InputFlags = GrSimpleMeshDrawOpHelper::InputFlags;
using GrSimpleMeshDrawOpHelper::visitProxies;
-
- const GrPipeline* createPipelineWithStencil(const GrCaps*,
- SkArenaAlloc*,
- GrSwizzle writeViewSwizzle,
- GrAppliedClip&&,
- const GrXferProcessor::DstProxyView&);
-
- const GrPipeline* createPipelineWithStencil(GrOpFlushState* flushState);
+ using GrSimpleMeshDrawOpHelper::createPipeline;
GrProgramInfo* createProgramInfoWithStencil(const GrCaps*,
SkArenaAlloc*,
@@ -39,7 +32,6 @@
GrPrimitiveType,
GrXferBarrierFlags renderPassXferBarriers);
-
// using declarations can't be templated, so this is a pass through function instead.
template <typename Op, typename... OpArgs>
static std::unique_ptr<GrDrawOp> FactoryHelper(GrRecordingContext* context, GrPaint&& paint,
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 8d44fb8..d444dc3 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -610,9 +610,10 @@
}
void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
- auto pipeline = fHelper.createPipelineWithStencil(flushState);
+ auto pipeline = fHelper.createPipeline(flushState);
- flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline);
+ flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, pipeline,
+ fHelper.stencilSettings());
}
const SkPMColor4f& color() const { return fShapes[0].fColor; }
diff --git a/src/gpu/tessellate/GrDrawAtlasPathOp.cpp b/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
index 1631cfa..7716a53 100644
--- a/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
+++ b/src/gpu/tessellate/GrDrawAtlasPathOp.cpp
@@ -180,8 +180,8 @@
GrProgramInfo programInfo(state->proxy()->numSamples(), state->proxy()->numStencilSamples(),
state->proxy()->backendFormat(), state->writeView()->origin(),
- &pipeline, &shader, GrPrimitiveType::kTriangleStrip, 0,
- state->renderPassBarriers());
+ &pipeline, &GrUserStencilSettings::kUnused, &shader,
+ GrPrimitiveType::kTriangleStrip, 0, state->renderPassBarriers());
state->bindPipelineAndScissorClip(programInfo, this->bounds());
state->bindTextures(shader, *fAtlasProxy, pipeline);
diff --git a/src/gpu/tessellate/GrPathShader.h b/src/gpu/tessellate/GrPathShader.h
index 2043102..246a306 100644
--- a/src/gpu/tessellate/GrPathShader.h
+++ b/src/gpu/tessellate/GrPathShader.h
@@ -38,6 +38,7 @@
GrProcessorSet&& processors, GrAppliedClip&& appliedClip,
const GrXferProcessor::DstProxyView& dstProxyView,
GrXferBarrierFlags renderPassXferBarriers,
+ const GrUserStencilSettings* stencil,
const GrCaps& caps) {
GrPipeline::InitArgs pipelineArgs;
pipelineArgs.fInputFlags = pipelineFlags;
@@ -47,7 +48,7 @@
auto* pipeline = arena->make<GrPipeline>(pipelineArgs, std::move(processors),
std::move(appliedClip));
return MakeProgramInfo(shader, arena, writeView, pipeline, dstProxyView,
- renderPassXferBarriers, caps);
+ renderPassXferBarriers, stencil, caps);
}
static GrProgramInfo* MakeProgramInfo(const GrPathShader* shader, SkArenaAlloc* arena,
@@ -55,11 +56,12 @@
const GrPipeline* pipeline,
const GrXferProcessor::DstProxyView& dstProxyView,
GrXferBarrierFlags renderPassXferBarriers,
+ const GrUserStencilSettings* stencil,
const GrCaps& caps) {
GrRenderTargetProxy* proxy = writeView->asRenderTargetProxy();
return arena->make<GrProgramInfo>(proxy->numSamples(), proxy->numStencilSamples(),
proxy->backendFormat(), writeView->origin(), pipeline,
- shader, shader->fPrimitiveType,
+ stencil, shader, shader->fPrimitiveType,
shader->fTessellationPatchVertexCount,
renderPassXferBarriers);
}
diff --git a/src/gpu/tessellate/GrPathTessellateOp.cpp b/src/gpu/tessellate/GrPathTessellateOp.cpp
index 1281355..29c5ae5 100644
--- a/src/gpu/tessellate/GrPathTessellateOp.cpp
+++ b/src/gpu/tessellate/GrPathTessellateOp.cpp
@@ -169,14 +169,37 @@
return true;
}
+// Increments clockwise triangles and decrements counterclockwise. Used for "winding" fill.
+constexpr static GrUserStencilSettings kIncrDecrStencil(
+ GrUserStencilSettings::StaticInitSeparate<
+ 0x0000, 0x0000,
+ GrUserStencilTest::kAlwaysIfInClip, GrUserStencilTest::kAlwaysIfInClip,
+ 0xffff, 0xffff,
+ GrUserStencilOp::kIncWrap, GrUserStencilOp::kDecWrap,
+ GrUserStencilOp::kKeep, GrUserStencilOp::kKeep,
+ 0xffff, 0xffff>());
+
+// Inverts the bottom stencil bit. Used for "even/odd" fill.
+constexpr static GrUserStencilSettings kInvertStencil(
+ GrUserStencilSettings::StaticInit<
+ 0x0000,
+ GrUserStencilTest::kAlwaysIfInClip,
+ 0xffff,
+ GrUserStencilOp::kInvert,
+ GrUserStencilOp::kKeep,
+ 0x0001>());
+
+constexpr static const GrUserStencilSettings* stencil_pass_settings(SkPathFillType fillType) {
+ return (fillType == SkPathFillType::kWinding) ? &kIncrDecrStencil : &kInvertStencil;
+}
+
void GrPathTessellateOp::prePrepareStencilTrianglesProgram(const PrePrepareArgs& args) {
SkASSERT(!fStencilTrianglesProgram);
auto* shader = args.fArena->make<GrStencilTriangleShader>(fViewMatrix);
this->prePrepareSharedStencilPipeline(args);
- fStencilTrianglesProgram = GrPathShader::MakeProgramInfo(shader, args.fArena, args.fWriteView,
- fSharedStencilPipeline,
- *args.fDstProxfView,
- args.fXferBarrierFlags, *args.fCaps);
+ fStencilTrianglesProgram = GrPathShader::MakeProgramInfo(
+ shader, args.fArena, args.fWriteView, fSharedStencilPipeline, *args.fDstProxfView,
+ args.fXferBarrierFlags, stencil_pass_settings(fPath.getFillType()), *args.fCaps);
}
template<typename ShaderType>
@@ -184,10 +207,9 @@
SkASSERT(!fStencilCubicsProgram);
auto* shader = args.fArena->make<ShaderType>(fViewMatrix);
this->prePrepareSharedStencilPipeline(args);
- fStencilCubicsProgram = GrPathShader::MakeProgramInfo(shader, args.fArena, args.fWriteView,
- fSharedStencilPipeline,
- *args.fDstProxfView,
- args.fXferBarrierFlags, *args.fCaps);
+ fStencilCubicsProgram = GrPathShader::MakeProgramInfo(
+ shader, args.fArena, args.fWriteView, fSharedStencilPipeline, *args.fDstProxfView,
+ args.fXferBarrierFlags, stencil_pass_settings(fPath.getFillType()), *args.fCaps);
}
void GrPathTessellateOp::prePrepareSharedStencilPipeline(const PrePrepareArgs& args) {
@@ -195,26 +217,6 @@
return;
}
- // Increments clockwise triangles and decrements counterclockwise. Used for "winding" fill.
- constexpr static GrUserStencilSettings kIncrDecrStencil(
- GrUserStencilSettings::StaticInitSeparate<
- 0x0000, 0x0000,
- GrUserStencilTest::kAlwaysIfInClip, GrUserStencilTest::kAlwaysIfInClip,
- 0xffff, 0xffff,
- GrUserStencilOp::kIncWrap, GrUserStencilOp::kDecWrap,
- GrUserStencilOp::kKeep, GrUserStencilOp::kKeep,
- 0xffff, 0xffff>());
-
- // Inverts the bottom stencil bit. Used for "even/odd" fill.
- constexpr static GrUserStencilSettings kInvertStencil(
- GrUserStencilSettings::StaticInit<
- 0x0000,
- GrUserStencilTest::kAlwaysIfInClip,
- 0xffff,
- GrUserStencilOp::kInvert,
- GrUserStencilOp::kKeep,
- 0x0001>());
-
GrPipeline::InitArgs initArgs;
if (GrAAType::kNone != fAAType) {
initArgs.fInputFlags |= GrPipeline::InputFlags::kHWAntialias;
@@ -224,8 +226,6 @@
}
SkASSERT(SkPathFillType::kWinding == fPath.getFillType() ||
SkPathFillType::kEvenOdd == fPath.getFillType());
- initArgs.fUserStencil = (SkPathFillType::kWinding == fPath.getFillType()) ?
- &kIncrDecrStencil : &kInvertStencil;
initArgs.fCaps = args.fCaps;
const auto& hardClip = (args.fClip) ? args.fClip->hardClip() : GrAppliedHardClip::Disabled();
fSharedStencilPipeline = args.fArena->make<GrPipeline>(
@@ -742,26 +742,28 @@
GrUserStencilOp::kZero,
0xffff>());
+ const GrUserStencilSettings* stencil;
if (fStencilTrianglesProgram) {
// The path was already stencilled. Here we just need to do a cover pass.
- pipeline.setUserStencil(&kTestAndResetStencil);
+ stencil = &kTestAndResetStencil;
} else if (fCubicVertexCount == 0) {
// There are no stencilled curves. We can ignore stencil and fill the path directly.
- pipeline.setUserStencil(&GrUserStencilSettings::kUnused);
+ stencil = &GrUserStencilSettings::kUnused;
} else if (SkPathFillType::kWinding == fPath.getFillType()) {
// Fill in the path pixels not touched by curves, incr/decr stencil otherwise.
SkASSERT(!pipeline.hasStencilClip());
- pipeline.setUserStencil(&kFillOrIncrDecrStencil);
+ stencil = &kFillOrIncrDecrStencil;
} else {
// Fill in the path pixels not touched by curves, invert stencil otherwise.
SkASSERT(!pipeline.hasStencilClip());
- pipeline.setUserStencil(&kFillOrInvertStencil);
+ stencil = &kFillOrInvertStencil;
}
GrFillTriangleShader fillTrianglesShader(fViewMatrix, fColor);
auto* fillTrianglesProgram = GrPathShader::MakeProgramInfo(
&fillTrianglesShader, flushState->allocator(), flushState->writeView(), &pipeline,
- flushState->dstProxyView(), flushState->renderPassBarriers(), flushState->caps());
+ flushState->dstProxyView(), flushState->renderPassBarriers(), stencil,
+ flushState->caps());
flushState->bindPipelineAndScissorClip(*fillTrianglesProgram, this->bounds());
flushState->bindTextures(fillTrianglesShader, nullptr, pipeline);
flushState->bindBuffers(nullptr, nullptr, fTriangleBuffer);
@@ -773,12 +775,11 @@
// At this point, every pixel is filled in except the ones touched by curves. Issue a
// final cover pass over the curves by drawing their convex hulls. This will fill in any
// remaining samples and reset the stencil buffer.
- pipeline.setUserStencil(&kTestAndResetStencil);
GrFillCubicHullShader fillCubicHullsShader(fViewMatrix, fColor);
auto* fillCubicHullsProgram = GrPathShader::MakeProgramInfo(
&fillCubicHullsShader, flushState->allocator(), flushState->writeView(),
&pipeline, flushState->dstProxyView(), flushState->renderPassBarriers(),
- flushState->caps());
+ &kTestAndResetStencil, flushState->caps());
flushState->bindPipelineAndScissorClip(*fillCubicHullsProgram, this->bounds());
flushState->bindTextures(fillCubicHullsShader, nullptr, pipeline);
@@ -793,12 +794,11 @@
}
// There are no triangles to fill. Just draw a bounding box.
- pipeline.setUserStencil(&kTestAndResetStencil);
GrFillBoundingBoxShader fillBoundingBoxShader(fViewMatrix, fColor, fPath.getBounds());
auto* fillBoundingBoxProgram = GrPathShader::MakeProgramInfo(
&fillBoundingBoxShader, flushState->allocator(), flushState->writeView(),
&pipeline, flushState->dstProxyView(), flushState->renderPassBarriers(),
- flushState->caps());
+ &kTestAndResetStencil, flushState->caps());
flushState->bindPipelineAndScissorClip(*fillBoundingBoxProgram, this->bounds());
flushState->bindTextures(fillBoundingBoxShader, nullptr, pipeline);
flushState->bindBuffers(nullptr, nullptr, nullptr);
diff --git a/src/gpu/tessellate/GrStrokeTessellateOp.cpp b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
index 8b45257..ecacda0 100644
--- a/src/gpu/tessellate/GrStrokeTessellateOp.cpp
+++ b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
@@ -101,7 +101,8 @@
}
fColorProgram = GrPathShader::MakeProgramInfo(strokeShader, arena, writeView, pipelineFlags,
std::move(fProcessors), std::move(clip),
- dstProxyView, renderPassXferBarriers, caps);
+ dstProxyView, renderPassXferBarriers,
+ &GrUserStencilSettings::kUnused, caps);
}
void GrStrokeTessellateOp::onPrepare(GrOpFlushState* flushState) {
diff --git a/src/gpu/vk/GrVkPipelineStateCache.cpp b/src/gpu/vk/GrVkPipelineStateCache.cpp
index e2c3c04..3a35afb5 100644
--- a/src/gpu/vk/GrVkPipelineStateCache.cpp
+++ b/src/gpu/vk/GrVkPipelineStateCache.cpp
@@ -75,7 +75,7 @@
const GrProgramInfo& programInfo,
VkRenderPass compatibleRenderPass) {
#ifdef SK_DEBUG
- if (programInfo.pipeline().isStencilEnabled()) {
+ if (programInfo.isStencilEnabled()) {
SkASSERT(renderTarget->getStencilAttachment());
SkASSERT(renderTarget->numStencilBits() == 8);
SkASSERT(renderTarget->getStencilAttachment()->numSamples() ==
diff --git a/tests/GrMeshTest.cpp b/tests/GrMeshTest.cpp
index ee3e5c3b..03bd645 100644
--- a/tests/GrMeshTest.cpp
+++ b/tests/GrMeshTest.cpp
@@ -577,7 +577,8 @@
GrProgramInfo programInfo(fState->proxy()->numSamples(), fState->proxy()->numStencilSamples(),
fState->proxy()->backendFormat(), fState->writeView()->origin(),
- pipeline, mtp, primitiveType, 0, fState->renderPassBarriers());
+ pipeline, &GrUserStencilSettings::kUnused, mtp, primitiveType, 0,
+ fState->renderPassBarriers());
fState->opsRenderPass()->bindPipeline(programInfo, SkRect::MakeIWH(kImageWidth, kImageHeight));
return fState->opsRenderPass();
diff --git a/tests/GrPipelineDynamicStateTest.cpp b/tests/GrPipelineDynamicStateTest.cpp
index 11da0e2..46e6149 100644
--- a/tests/GrPipelineDynamicStateTest.cpp
+++ b/tests/GrPipelineDynamicStateTest.cpp
@@ -166,6 +166,7 @@
flushState->proxy()->backendFormat(),
flushState->writeView()->origin(),
&pipeline,
+ &GrUserStencilSettings::kUnused,
geomProc,
GrPrimitiveType::kTriangleStrip, 0,
flushState->renderPassBarriers());