Make BoundingBoxShader inherit from GrGeometryProcessor directly
This is not a tessellation shader, and only inherited from
GrPathTessellationShader because it was used by the tessellation path
renderer. Remove its dependence on GrPathTessellationShader.
Bug: skia:10419
Change-Id: Ia97ef68488fae1c90674c5a006a62a3157bb707f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/430019
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/tessellate/GrPathStencilCoverOp.cpp b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
index 09ea443..b5c9e55 100644
--- a/src/gpu/tessellate/GrPathStencilCoverOp.cpp
+++ b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
@@ -13,6 +13,8 @@
#include "src/gpu/GrOpFlushState.h"
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrResourceProvider.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
+#include "src/gpu/glsl/GrGLSLVarying.h"
#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
#include "src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h"
#include "src/gpu/tessellate/GrPathCurveTessellator.h"
@@ -27,50 +29,82 @@
// Fills a path's bounding box, with subpixel outset to avoid possible T-junctions with extreme
// edges of the path.
// NOTE: The emitted geometry may not be axis-aligned, depending on the view matrix.
-class BoundingBoxShader : public GrPathTessellationShader {
+class BoundingBoxShader : public GrGeometryProcessor {
public:
BoundingBoxShader(const SkMatrix& viewMatrix, SkPMColor4f color, const GrShaderCaps& shaderCaps)
- : GrPathTessellationShader(kTessellate_BoundingBoxShader_ClassID,
- GrPrimitiveType::kTriangleStrip, 0, viewMatrix, color) {
- constexpr static Attribute kPathBoundsAttrib("pathBounds", kFloat4_GrVertexAttribType,
- kFloat4_GrSLType);
- this->setInstanceAttributes(&kPathBoundsAttrib, 1);
+ : GrGeometryProcessor(kTessellate_BoundingBoxShader_ClassID)
+ , fViewMatrix(viewMatrix)
+ , fColor(color) {
+ // The 1/4px outset logic does not work with perspective yet.
+ SkASSERT(!fViewMatrix.hasPerspective());
if (!shaderCaps.vertexIDSupport()) {
constexpr static Attribute kUnitCoordAttrib("unitCoord", kFloat2_GrVertexAttribType,
kFloat2_GrSLType);
this->setVertexAttributes(&kUnitCoordAttrib, 1);
}
+ constexpr static Attribute kPathBoundsAttrib("pathBounds", kFloat4_GrVertexAttribType,
+ kFloat4_GrSLType);
+ this->setInstanceAttributes(&kPathBoundsAttrib, 1);
}
private:
const char* name() const final { return "tessellate_BoundingBoxShader"; }
void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const final {}
GrGLSLGeometryProcessor* createGLSLInstance(const GrShaderCaps&) const final;
+
+ const SkMatrix fViewMatrix;
+ const SkPMColor4f fColor;
};
GrGLSLGeometryProcessor* BoundingBoxShader::createGLSLInstance(const GrShaderCaps&) const {
- class Impl : public GrPathTessellationShader::Impl {
- void emitVertexCode(const GrShaderCaps& shaderCaps, const GrPathTessellationShader&,
- GrGLSLVertexBuilder* v, GrGPArgs* gpArgs) override {
- if (shaderCaps.vertexIDSupport()) {
+ class Impl : public GrGLSLGeometryProcessor {
+ void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) final {
+ args.fVaryingHandler->emitAttributes(args.fGeomProc);
+
+ // Vertex shader.
+ const char* viewMatrix;
+ fViewMatrixUniform = args.fUniformHandler->addUniform(nullptr, kVertex_GrShaderFlag,
+ kFloat3x3_GrSLType, "viewMatrix",
+ &viewMatrix);
+ if (args.fShaderCaps->vertexIDSupport()) {
// If we don't have sk_VertexID support then "unitCoord" already came in as a vertex
// attrib.
- v->codeAppendf(R"(
+ args.fVertBuilder->codeAppendf(R"(
float2 unitCoord = float2(sk_VertexID & 1, sk_VertexID >> 1);)");
}
+ args.fVertBuilder->codeAppendf(R"(
+ float3x3 VIEW_MATRIX = %s;
- v->codeAppend(R"(
- // Bloat the bounding box by 1/4px to avoid potential T-junctions at the edges.
- float2x2 M_ = inverse(AFFINE_MATRIX);
+ // Bloat the bounding box by 1/4px to be certain we will reset every stencil value.
+ float2x2 M_ = inverse(float2x2(VIEW_MATRIX));
float2 bloat = float2(abs(M_[0]) + abs(M_[1])) * .25;
// Find the vertex position.
float2 localcoord = mix(pathBounds.xy - bloat, pathBounds.zw + bloat, unitCoord);
- float2 vertexpos = AFFINE_MATRIX * localcoord + TRANSLATE;)");
+ float2 vertexpos = (VIEW_MATRIX * float3(localcoord, 1)).xy;)", viewMatrix);
gpArgs->fLocalCoordVar.set(kFloat2_GrSLType, "localcoord");
gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertexpos");
+
+ // Fragment shader.
+ const char* color;
+ fColorUniform = args.fUniformHandler->addUniform(nullptr, kFragment_GrShaderFlag,
+ kHalf4_GrSLType, "color", &color);
+ args.fFragBuilder->codeAppendf("half4 %s = %s;", args.fOutputColor, color);
+ args.fFragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
}
+
+ void setData(const GrGLSLProgramDataManager& pdman, const GrShaderCaps&,
+ const GrGeometryProcessor& gp) override {
+ const auto& bboxShader = gp.cast<BoundingBoxShader>();
+ pdman.setSkMatrix(fViewMatrixUniform, bboxShader.fViewMatrix);
+ const SkPMColor4f& color = bboxShader.fColor;
+ pdman.set4f(fColorUniform, color.fR, color.fG, color.fB, color.fA);
+ }
+
+ GrGLSLUniformHandler::UniformHandle fViewMatrixUniform;
+ GrGLSLUniformHandler::UniformHandle fColorUniform;
};
+
return new Impl;
}
@@ -153,8 +187,15 @@
std::move(fProcessors));
auto* bboxStencil =
GrPathTessellationShader::TestAndResetStencilSettings(fPath.isInverseFillType());
- fCoverBBoxProgram = GrTessellationShader::MakeProgram(args, bboxShader, bboxPipeline,
- bboxStencil);
+ fCoverBBoxProgram = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
+ args.fArena,
+ bboxPipeline,
+ args.fWriteView,
+ bboxShader,
+ GrPrimitiveType::kTriangleStrip,
+ args.fXferBarrierFlags,
+ args.fColorLoadOp,
+ bboxStencil);
}
}