aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp')
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp107
1 files changed, 43 insertions, 64 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
index 1fef1c3338..e64b8c0838 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp
@@ -75,7 +75,10 @@ protected:
SkString emitVertexFn;
SkSTArray<2, GrShaderVar> emitArgs;
const char* position = emitArgs.emplace_back("position", kFloat2_GrSLType).c_str();
- const char* coverage = emitArgs.emplace_back("coverage", kHalf_GrSLType).c_str();
+ const char* coverage = nullptr;
+ if (RenderPass::kTriangleCorners != proc.fRenderPass) {
+ coverage = emitArgs.emplace_back("coverage", kHalf_GrSLType).c_str();
+ }
g->emitFunction(kVoid_GrSLType, "emitVertex", emitArgs.count(), emitArgs.begin(), [&]() {
SkString fnBody;
fShader->emitVaryings(varyingHandler, GrGLSLVarying::Scope::kGeoToFrag, &fnBody,
@@ -113,7 +116,7 @@ protected:
* coverage ramp from -1 to 0. These edge coverage values convert jagged conservative raster edges
* into smooth, antialiased ones.
*
- * The final corners get touched up in a later step by GSTriangleCornerImpl.
+ * The final corners get touched up in a later step by GSCornerImpl.
*/
class GSTriangleImpl : public GrCCCoverageProcessor::GSImpl {
public:
@@ -121,8 +124,6 @@ public:
void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind,
const char* emitVertexFn) const override {
- SkAssertResult(!fShader->emitSetupCode(g, "pts"));
-
// Visualize the input triangle as upright and equilateral, with a flat base. Paying special
// attention to wind, we can identify the points as top, bottom-left, and bottom-right.
//
@@ -211,69 +212,19 @@ public:
};
/**
- * Generates conservative rasters around triangle corners (aka pixel-size boxes) and calculates
- * coverage ramps that fix up the coverage values written by GSTriangleImpl.
- */
-class GSTriangleCornerImpl : public GrCCCoverageProcessor::GSImpl {
-public:
- GSTriangleCornerImpl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
-
- void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind,
- const char* emitVertexFn) const override {
- SkAssertResult(!fShader->emitSetupCode(g, "pts"));
-
- g->codeAppendf("float2 corner = pts[sk_InvocationID];");
- g->codeAppendf("float2 left = pts[(sk_InvocationID + (%s > 0 ? 2 : 1)) %% 3];",
- wind.c_str());
- g->codeAppendf("float2 right = pts[(sk_InvocationID + (%s > 0 ? 1 : 2)) %% 3];",
- wind.c_str());
-
- // Find "outbloat" and "crossbloat" at our corner. The outbloat points diagonally out of the
- // triangle, in the direction that should ramp to zero coverage. The crossbloat runs
- // perpindicular to outbloat, and ramps from left-edge coverage to right-edge coverage.
- g->codeAppend ("float2 leftdir = normalize(corner - left);");
- g->codeAppend ("float2 rightdir = normalize(right - corner);");
- g->codeAppend ("float2 outbloat = float2(leftdir.x > rightdir.x ? +1 : -1, "
- "leftdir.y > rightdir.y ? +1 : -1);");
- g->codeAppend ("float2 crossbloat = float2(-outbloat.y, +outbloat.x);");
-
- g->codeAppend ("half2 left_coverages; {");
- Shader::CalcEdgeCoveragesAtBloatVertices(g, "left", "corner", "outbloat", "crossbloat",
- "left_coverages");
- g->codeAppend ("}");
-
- g->codeAppend ("half2 right_coverages; {");
- Shader::CalcEdgeCoveragesAtBloatVertices(g, "corner", "right", "outbloat", "-crossbloat",
- "right_coverages");
- g->codeAppend ("}");
-
- // Emit a corner box that erases whatever coverage was written previously, and replaces it
- // using linearly-interpolated values that ramp to zero in bloat vertices that fall outside
- // the triangle.
- //
- // NOTE: Since this is not a linear mapping, it is important that the box's diagonal shared
- // edge points out of the triangle as much as possible.
- g->codeAppendf("%s(corner - crossbloat * bloat, -right_coverages[1]);", emitVertexFn);
- g->codeAppendf("%s(corner + outbloat * bloat, "
- "-1 - left_coverages[0] - right_coverages[0]);", emitVertexFn);
- g->codeAppendf("%s(corner - outbloat * bloat, 0);", emitVertexFn);
- g->codeAppendf("%s(corner + crossbloat * bloat, -left_coverages[1]);", emitVertexFn);
-
- g->configure(InputType::kLines, OutputType::kTriangleStrip, 4, 3);
- }
-};
-
-/**
* Generates a conservative raster hull around a convex quadrilateral that encloses a cubic or
* quadratic, as well as its shared edge.
*/
-class GSCurveImpl : public GrCCCoverageProcessor::GSImpl {
+class GSHull4Impl : public GrCCCoverageProcessor::GSImpl {
public:
- GSCurveImpl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
+ GSHull4Impl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {}
void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind,
const char* emitVertexFn) const override {
- const char* hullPts = fShader->emitSetupCode(g, "pts");
+ Shader::GeometryVars vars;
+ fShader->emitSetupCode(g, "pts", nullptr, wind.c_str(), &vars);
+
+ const char* hullPts = vars.fHullVars.fAlternatePoints;
if (!hullPts) {
hullPts = "pts";
}
@@ -363,6 +314,34 @@ public:
}
};
+/**
+ * Generates conservative rasters around corners. (See comments for RenderPass)
+ */
+class GSCornerImpl : public GrCCCoverageProcessor::GSImpl {
+public:
+ GSCornerImpl(std::unique_ptr<Shader> shader, int numCorners)
+ : GSImpl(std::move(shader)), fNumCorners(numCorners) {}
+
+ void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind,
+ const char* emitVertexFn) const override {
+ Shader::GeometryVars vars;
+ fShader->emitSetupCode(g, "pts", "sk_InvocationID", wind.c_str(), &vars);
+
+ const char* corner = vars.fCornerVars.fPoint;
+ SkASSERT(corner);
+
+ g->codeAppendf("%s(%s + float2(-bloat, -bloat));", emitVertexFn, corner);
+ g->codeAppendf("%s(%s + float2(-bloat, +bloat));", emitVertexFn, corner);
+ g->codeAppendf("%s(%s + float2(+bloat, -bloat));", emitVertexFn, corner);
+ g->codeAppendf("%s(%s + float2(+bloat, +bloat));", emitVertexFn, corner);
+
+ g->configure(InputType::kLines, OutputType::kTriangleStrip, 4, fNumCorners);
+ }
+
+private:
+ const int fNumCorners;
+};
+
void GrCCCoverageProcessor::initGS() {
SkASSERT(Impl::kGeometryShader == fImpl);
if (RenderPass::kCubics == fRenderPass || WindMethod::kInstanceData == fWindMethod) {
@@ -393,12 +372,12 @@ void GrCCCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceC
GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGSImpl(std::unique_ptr<Shader> shadr) const {
switch (fRenderPass) {
case RenderPass::kTriangles:
- return (GSTriangleSubpass::kHullsAndEdges == fGSTriangleSubpass)
- ? (GSImpl*) new GSTriangleImpl(std::move(shadr))
- : (GSImpl*) new GSTriangleCornerImpl(std::move(shadr));
+ return new GSTriangleImpl(std::move(shadr));
+ case RenderPass::kTriangleCorners:
+ return new GSCornerImpl(std::move(shadr), 3);
case RenderPass::kQuadratics:
case RenderPass::kCubics:
- return new GSCurveImpl(std::move(shadr));
+ return new GSHull4Impl(std::move(shadr));
}
SK_ABORT("Invalid RenderPass");
return nullptr;