Reland "Fix tessellation checks for "usesVaryingCoords""
This is a reland of bd727d0620c4bd85663d6d7c57beb6d40605fb3e
TBR=jvanverth@google.com
Original change's description:
> Fix tessellation checks for "usesVaryingCoords"
>
> We can't use our hardware tessellation back door if any FPs in the
> program have varyings. Before this CL, we were forgetting to check the
> clip FP for strokes, and weren't checking any FPs yet for fills.
>
> Bug: skia:10419
> Change-Id: Ica631ab3cf0407fb359c02c6d53f88f5f301cddc
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417237
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Bug: skia:10419
Change-Id: If8c1e18efc663641b2d565314110f66a6840f8bb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417317
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/bench/TessellateBench.cpp b/bench/TessellateBench.cpp
index 2694a75..6a96581 100644
--- a/bench/TessellateBench.cpp
+++ b/bench/TessellateBench.cpp
@@ -113,18 +113,22 @@
DEF_PATH_TESS_BENCH(GrPathOuterCurveTessellator, make_cubic_path(8), SkMatrix::I()) {
SkArenaAlloc arena(1024);
+ GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
+ GrSwizzle::RGBA());
auto tess = GrPathCurveTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
GrPathCurveTessellator::DrawInnerFan::kNo,
fTarget->caps().minPathVerbsForHwTessellation(),
- fTarget->caps());
+ noVaryingsPipeline, fTarget->caps());
tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
}
DEF_PATH_TESS_BENCH(GrPathWedgeTessellator, make_cubic_path(8), SkMatrix::I()) {
SkArenaAlloc arena(1024);
+ GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
+ GrSwizzle::RGBA());
auto tess = GrPathWedgeTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
fTarget->caps().minPathVerbsForHwTessellation(),
- fTarget->caps());
+ noVaryingsPipeline, fTarget->caps());
tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
}
diff --git a/samplecode/SamplePathTessellators.cpp b/samplecode/SamplePathTessellators.cpp
index 18e8f2f..e154694 100644
--- a/samplecode/SamplePathTessellators.cpp
+++ b/samplecode/SamplePathTessellators.cpp
@@ -74,30 +74,34 @@
const GrCaps& caps = flushState->caps();
int numVerbsToGetMiddleOut = 0;
int numVerbsToGetTessellation = caps.minPathVerbsForHwTessellation();
+ auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, std::move(fProcessors),
+ fPipelineFlags);
switch (fMode) {
using DrawInnerFan = GrPathCurveTessellator::DrawInnerFan;
case Mode::kWedgeMiddleOut:
fTessellator = GrPathWedgeTessellator::Make(alloc, fMatrix, kCyan,
- numVerbsToGetMiddleOut, caps);
+ numVerbsToGetMiddleOut, *pipeline,
+ caps);
break;
case Mode::kCurveMiddleOut:
fTessellator = GrPathCurveTessellator::Make(alloc, fMatrix, kCyan,
DrawInnerFan::kYes,
- numVerbsToGetMiddleOut, caps);
+ numVerbsToGetMiddleOut, *pipeline,
+ caps);
break;
case Mode::kWedgeTessellate:
fTessellator = GrPathWedgeTessellator::Make(alloc, fMatrix, kCyan,
- numVerbsToGetTessellation, caps);
+ numVerbsToGetTessellation, *pipeline,
+ caps);
break;
case Mode::kCurveTessellate:
fTessellator = GrPathCurveTessellator::Make(alloc, fMatrix, kCyan,
DrawInnerFan::kYes,
- numVerbsToGetTessellation, caps);
+ numVerbsToGetTessellation, *pipeline,
+ caps);
break;
}
fTessellator->prepare(flushState, this->bounds(), fPath);
- auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, std::move(fProcessors),
- fPipelineFlags);
fProgram = GrTessellationShader::MakeProgram({alloc, flushState->writeView(),
&flushState->dstProxyView(),
flushState->renderPassBarriers(),
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index aaf68dc..c7172da 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -110,6 +110,15 @@
bool isColorFragmentProcessor(int idx) const { return idx < fNumColorProcessors; }
bool isCoverageFragmentProcessor(int idx) const { return idx >= fNumColorProcessors; }
+ bool usesVaryingCoords() const {
+ for (const auto& fp : fFragmentProcessors) {
+ if (fp->usesVaryingCoords()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
const GrXferProcessor& getXferProcessor() const {
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index ab1e28b..7dbf695 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -43,11 +43,6 @@
return fCoverageFragmentProcessor.get();
}
- bool usesVaryingCoords() const {
- return (fColorFragmentProcessor && fColorFragmentProcessor->usesVaryingCoords()) ||
- (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesVaryingCoords());
- }
-
const GrXferProcessor* xferProcessor() const {
SkASSERT(this->isFinalized());
return fXP.fProcessor;
diff --git a/src/gpu/tessellate/GrPathCurveTessellator.cpp b/src/gpu/tessellate/GrPathCurveTessellator.cpp
index de4894a..cf3adf3 100644
--- a/src/gpu/tessellate/GrPathCurveTessellator.cpp
+++ b/src/gpu/tessellate/GrPathCurveTessellator.cpp
@@ -137,10 +137,12 @@
GrPathTessellator* GrPathCurveTessellator::Make(SkArenaAlloc* arena, const SkMatrix& viewMatrix,
const SkPMColor4f& color, DrawInnerFan drawInnerFan,
- int numPathVerbs, const GrCaps& caps) {
+ int numPathVerbs, const GrPipeline& pipeline,
+ const GrCaps& caps) {
using PatchType = GrPathTessellationShader::PatchType;
GrPathTessellationShader* shader;
if (caps.shaderCaps()->tessellationSupport() &&
+ !pipeline.usesVaryingCoords() && // Our tessellation back door doesn't handle varyings.
numPathVerbs >= caps.minPathVerbsForHwTessellation()) {
shader = GrPathTessellationShader::MakeHardwareTessellationShader(arena, viewMatrix, color,
PatchType::kCurves);
diff --git a/src/gpu/tessellate/GrPathCurveTessellator.h b/src/gpu/tessellate/GrPathCurveTessellator.h
index ac9da97..1132fa7 100644
--- a/src/gpu/tessellate/GrPathCurveTessellator.h
+++ b/src/gpu/tessellate/GrPathCurveTessellator.h
@@ -25,7 +25,8 @@
// Creates a curve tessellator with the shader type best suited for the given path description.
static GrPathTessellator* Make(SkArenaAlloc*, const SkMatrix& viewMatrix, const SkPMColor4f&,
- DrawInnerFan, int numPathVerbs, const GrCaps&);
+ DrawInnerFan, int numPathVerbs, const GrPipeline&,
+ const GrCaps&);
void prepare(GrMeshDrawOp::Target*, const SkRect& cullBounds, const SkPath&,
const BreadcrumbTriangleList*) override;
diff --git a/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp b/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
index cbeffc1..41054fe 100644
--- a/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
+++ b/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
@@ -192,7 +192,8 @@
fTessellator = GrPathCurveTessellator::Make(args.fArena, fViewMatrix,
SK_PMColor4fTRANSPARENT,
GrPathCurveTessellator::DrawInnerFan::kNo,
- fPath.countVerbs(), *args.fCaps);
+ fPath.countVerbs(), *pipelineForStencils,
+ *args.fCaps);
const GrUserStencilSettings* stencilPathSettings =
GrPathTessellationShader::StencilPathSettings(fPath.getFillType());
fStencilCurvesProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(),
diff --git a/src/gpu/tessellate/GrPathStencilCoverOp.cpp b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
index aff707a..525092c 100644
--- a/src/gpu/tessellate/GrPathStencilCoverOp.cpp
+++ b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
@@ -113,11 +113,12 @@
fTessellator = GrPathCurveTessellator::Make(args.fArena, fViewMatrix,
SK_PMColor4fTRANSPARENT,
GrPathCurveTessellator::DrawInnerFan::kNo,
- fPath.countVerbs(), *args.fCaps);
+ fPath.countVerbs(), *stencilPipeline,
+ *args.fCaps);
} else {
fTessellator = GrPathWedgeTessellator::Make(args.fArena, fViewMatrix,
SK_PMColor4fTRANSPARENT, fPath.countVerbs(),
- *args.fCaps);
+ *stencilPipeline, *args.fCaps);
}
fStencilPathProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(),
stencilPipeline, stencilPathSettings);
diff --git a/src/gpu/tessellate/GrPathWedgeTessellator.cpp b/src/gpu/tessellate/GrPathWedgeTessellator.cpp
index b380fb7..d00e866 100644
--- a/src/gpu/tessellate/GrPathWedgeTessellator.cpp
+++ b/src/gpu/tessellate/GrPathWedgeTessellator.cpp
@@ -227,10 +227,11 @@
GrPathTessellator* GrPathWedgeTessellator::Make(SkArenaAlloc* arena, const SkMatrix& viewMatrix,
const SkPMColor4f& color, int numPathVerbs,
- const GrCaps& caps) {
+ const GrPipeline& pipeline, const GrCaps& caps) {
using PatchType = GrPathTessellationShader::PatchType;
GrPathTessellationShader* shader;
if (caps.shaderCaps()->tessellationSupport() &&
+ !pipeline.usesVaryingCoords() && // Our tessellation back door doesn't handle varyings.
numPathVerbs >= caps.minPathVerbsForHwTessellation()) {
shader = GrPathTessellationShader::MakeHardwareTessellationShader(arena, viewMatrix, color,
PatchType::kWedges);
diff --git a/src/gpu/tessellate/GrPathWedgeTessellator.h b/src/gpu/tessellate/GrPathWedgeTessellator.h
index da3c6c0..660be63 100644
--- a/src/gpu/tessellate/GrPathWedgeTessellator.h
+++ b/src/gpu/tessellate/GrPathWedgeTessellator.h
@@ -19,7 +19,7 @@
public:
// Creates a wedge tessellator with the shader type best suited for the given path description.
static GrPathTessellator* Make(SkArenaAlloc*, const SkMatrix& viewMatrix, const SkPMColor4f&,
- int numPathVerbs, const GrCaps&);
+ int numPathVerbs, const GrPipeline&, const GrCaps&);
void prepare(GrMeshDrawOp::Target*, const SkRect& cullBounds, const SkPath&,
const BreadcrumbTriangleList*) override;
diff --git a/src/gpu/tessellate/GrStrokeTessellateOp.cpp b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
index bd4d8fd..fb2526e 100644
--- a/src/gpu/tessellate/GrStrokeTessellateOp.cpp
+++ b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
@@ -146,12 +146,11 @@
GrUserStencilOp::kReplace,
0xffff>());
-bool GrStrokeTessellateOp::canUseHardwareTessellation(int numVerbs, const GrCaps& caps) {
- SkASSERT(!fStencilProgram && !fFillProgram); // Ensure we haven't std::moved fProcessors.
+bool can_use_hardware_tessellation(int numVerbs, const GrPipeline& pipeline, const GrCaps& caps) {
if (!caps.shaderCaps()->tessellationSupport()) {
return false;
}
- if (fProcessors.usesVaryingCoords()) {
+ if (pipeline.usesVaryingCoords()) {
// Our back door for HW tessellation shaders isn't currently capable of passing varyings to
// the fragment shader, so if the processors have varyings, we need to use instanced draws
// instead.
@@ -185,7 +184,10 @@
}
SkRect strokeCullBounds = this->bounds().makeOutset(devInflationRadius, devInflationRadius);
- if (this->canUseHardwareTessellation(fTotalCombinedVerbCnt, caps)) {
+ auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(clip),
+ std::move(fProcessors));
+
+ if (can_use_hardware_tessellation(fTotalCombinedVerbCnt, *pipeline, caps)) {
// Only use hardware tessellation if we're drawing a somewhat large number of verbs.
// Otherwise we seem to be better off using instanced draws.
fTessellator = arena->make<GrStrokeHardwareTessellator>(fShaderFlags, *caps.shaderCaps(),
@@ -199,8 +201,6 @@
strokeCullBounds);
}
- auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(clip),
- std::move(fProcessors));
auto fillStencil = &GrUserStencilSettings::kUnused;
if (fNeedsStencil) {
fStencilProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(), pipeline,
diff --git a/src/gpu/tessellate/GrStrokeTessellateOp.h b/src/gpu/tessellate/GrStrokeTessellateOp.h
index e3890cb..e8f61e1 100644
--- a/src/gpu/tessellate/GrStrokeTessellateOp.h
+++ b/src/gpu/tessellate/GrStrokeTessellateOp.h
@@ -41,8 +41,6 @@
return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
}
- bool canUseHardwareTessellation(int numVerbs, const GrCaps& caps);
-
const char* name() const override { return "GrStrokeTessellateOp"; }
void visitProxies(const VisitProxyFunc& fn) const override;
bool usesMSAA() const override { return fAAType == GrAAType::kMSAA; }