aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-01-30 16:42:37 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-02-01 16:33:23 +0000
commitf510e26a070ba3553b4cce3831cc9cd97b58a6bb (patch)
tree0a8140a326a9d7988880c2c871b18f7c1ba99e2f /src
parentd2bc6207ba80c3babdb115bee7a9bbcf3c91be2e (diff)
ccpr: Pack wind into existing varyings
Bug: skia: Change-Id: I189a22a6779af5d3fa7671992da50ede36eaaa8f Reviewed-on: https://skia-review.googlesource.com/102067 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.cpp20
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.h38
-rw-r--r--src/gpu/ccpr/GrCCCubicShader.cpp49
-rw-r--r--src/gpu/ccpr/GrCCCubicShader.h13
-rw-r--r--src/gpu/ccpr/GrCCQuadraticShader.cpp49
-rw-r--r--src/gpu/ccpr/GrCCQuadraticShader.h15
-rw-r--r--src/gpu/ccpr/GrCCTriangleShader.cpp30
-rw-r--r--src/gpu/ccpr/GrCCTriangleShader.h11
8 files changed, 109 insertions, 116 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
index 032d177c3b..c875625745 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp
@@ -15,31 +15,13 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLVertexGeoBuilder.h"
-void GrCCCoverageProcessor::Shader::emitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope, SkString* code,
- const char* position, const char* coverage,
- const char* wind) {
- SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
- WindHandling windHandling = this->onEmitVaryings(varyingHandler, scope, code, position,
- coverage, wind);
- if (WindHandling::kNotHandled == windHandling) {
- fWind.reset(kHalf_GrSLType, scope);
- varyingHandler->addFlatVarying("wind", &fWind);
- code->appendf("%s = %s;", OutName(fWind), wind);
- }
-}
-
void GrCCCoverageProcessor::Shader::emitFragmentCode(const GrCCCoverageProcessor& proc,
GrGLSLPPFragmentBuilder* f,
const char* skOutputColor,
const char* skOutputCoverage) const {
f->codeAppendf("half coverage = 0;");
this->onEmitFragmentCode(f, "coverage");
- if (fWind.fsIn()) {
- f->codeAppendf("%s.a = coverage * %s;", skOutputColor, fWind.fsIn());
- } else {
- f->codeAppendf("%s.a = coverage;", skOutputColor);
- }
+ f->codeAppendf("%s.a = coverage;", skOutputColor);
f->codeAppendf("%s = half4(1);", skOutputCoverage);
#ifdef SK_DEBUG
if (proc.debugVisualizationsEnabled()) {
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index eeb2ace60d..1296e089dc 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -59,7 +59,7 @@ public:
enum class RenderPass {
// For a Hull, the Impl generates a "conservative raster hull" around the input points. This
// is the geometry that causes a pixel to be rasterized if it is touched anywhere by the
- // input polygon. The initial coverage values sent to the Shader at each vertex are either
+ // input polygon. The input coverage values sent to the Shader at each vertex are either
// null, or +1 all around if the Impl combines this pass with kTriangleEdges. Logically,
// the conservative raster hull is equivalent to the convex hull of pixel size boxes
// centered on each input point.
@@ -68,7 +68,7 @@ public:
kCubicHulls,
// For Edges, the Impl generates conservative rasters around every input edge (i.e. convex
- // hulls of two pixel-size boxes centered on both of the edge's endpoints). The initial
+ // hulls of two pixel-size boxes centered on both of the edge's endpoints). The input
// coverage values sent to the Shader at each vertex are -1 on the outside border of the
// edge geometry and 0 on the inside. This is the only geometry type that associates
// coverage values with the output vertices. Interpolated, these coverage values convert
@@ -80,7 +80,7 @@ public:
// For Corners, the Impl Generates the conservative rasters of corner points (i.e.
// pixel-size boxes). It generates 3 corner boxes for triangles and 2 for curves. The Shader
- // specifies which corners. Initial coverage values sent to the Shader will be null.
+ // specifies which corners. Input coverage values sent to the Shader will be null.
kTriangleCorners,
kQuadraticCorners,
kCubicCorners
@@ -162,8 +162,12 @@ public:
const char* repetitionID, const char* wind,
GeometryVars*) const {}
- void emitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
- const char* position, const char* coverage, const char* wind);
+ void emitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope,
+ SkString* code, const char* position, const char* inputCoverage,
+ const char* wind) {
+ SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
+ this->onEmitVaryings(varyingHandler, scope, code, position, inputCoverage, wind);
+ }
void emitFragmentCode(const GrCCCoverageProcessor& proc, GrGLSLPPFragmentBuilder*,
const char* skOutputColor, const char* skOutputCoverage) const;
@@ -178,25 +182,16 @@ public:
virtual ~Shader() {}
protected:
- enum class WindHandling : bool {
- kHandled,
- kNotHandled
- };
-
// Here the subclass adds its internal varyings to the handler and produces code to
- // initialize those varyings from a given position, coverage value, and wind.
+ // initialize those varyings from a given position, input coverage value, and wind.
//
- // Returns whether the subclass will handle wind modulation or if this base class should
- // take charge of multiplying the final coverage output by "wind".
- //
- // NOTE: the coverage parameter is only relevant for edges (see comments in RenderPass).
+ // NOTE: the coverage input is only relevant for edges (see comments in RenderPass).
// Otherwise it is +1 all around.
- virtual WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope,
- SkString* code, const char* position,
- const char* coverage, const char* wind) = 0;
+ virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* inputCoverage,
+ const char* wind) = 0;
- // Emits the fragment code that calculates a pixel's coverage value. If using
- // WindHandling::kHandled, this value must be signed appropriately.
+ // Emits the fragment code that calculates a pixel's signed coverage value.
virtual void onEmitFragmentCode(GrGLSLPPFragmentBuilder*,
const char* outputCoverage) const = 0;
@@ -213,9 +208,6 @@ public:
//
// Returns the number of samples.
static int DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f, const char* samplesName);
-
- private:
- GrGLSLVarying fWind;
};
class GSImpl;
diff --git a/src/gpu/ccpr/GrCCCubicShader.cpp b/src/gpu/ccpr/GrCCCubicShader.cpp
index 295de0ca6c..fbaf7d9da8 100644
--- a/src/gpu/ccpr/GrCCCubicShader.cpp
+++ b/src/gpu/ccpr/GrCCCubicShader.cpp
@@ -58,12 +58,14 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
// Evaluate the cubic at T=.5 for a mid-ish point.
s->codeAppendf("float2 midpoint = %s * float4(.125, .375, .375, .125);", pts);
- // Orient the KLM matrix so we fill the correct side of the curve.
+ // Orient the KLM matrix so L & M have matching signs on the side of the curve we wish to fill.
+ // We give L & M both the same sign as wind, in order to pass this value to the fragment shader.
+ // (Cubics are pre-chopped such that L & M do not change sign within any individual segment).
s->codeAppendf("float2 orientation = sign(float3(midpoint, 1) * float2x3(%s[1], %s[2]));",
fKLMMatrix.c_str(), fKLMMatrix.c_str());
s->codeAppendf("%s *= float3x3(orientation[0] * orientation[1], 0, 0, "
- "0, orientation[0], 0, "
- "0, 0, orientation[1]);", fKLMMatrix.c_str());
+ "0, orientation[0] * %s, 0, "
+ "0, 0, orientation[1] * %s);", fKLMMatrix.c_str(), wind, wind);
// Determine the amount of additional coverage to subtract out for the flat edge (P3 -> P0).
s->declareGlobal(fEdgeDistanceEquation);
@@ -75,11 +77,11 @@ void GrCCCubicShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
this->onEmitSetupCode(s, pts, repetitionID, vars);
}
-Shader::WindHandling GrCCCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope,
- SkString* code, const char* position,
- const char* coverage, const char* /*wind*/) {
- SkASSERT(!coverage);
+void GrCCCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLVarying::Scope scope, SkString* code,
+ const char* position, const char* inputCoverage,
+ const char* /*wind*/) {
+ SkASSERT(!inputCoverage);
fKLMD.reset(kFloat4_GrSLType, scope);
varyingHandler->addVarying("klmd", &fKLMD);
@@ -88,7 +90,20 @@ Shader::WindHandling GrCCCubicShader::onEmitVaryings(GrGLSLVaryingHandler* varyi
code->appendf("%s = float4(klm, d);", OutName(fKLMD));
this->onEmitVaryings(varyingHandler, scope, code);
- return WindHandling::kNotHandled;
+}
+
+void GrCCCubicShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
+ f->codeAppendf("float k = %s.x, l = %s.y, m = %s.z, d = %s.w;",
+ fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn());
+
+ this->emitCoverage(f, outputCoverage);
+
+ // Wind is the sign of both L and/or M. Take the sign of whichever has the larger magnitude.
+ // (In reality, either would be fine because we chop cubics with more than a half pixel of
+ // padding around the L & M lines, so neither should approach zero.)
+ f->codeAppend ("half wind = sign(l + m);");
+ f->codeAppendf("%s *= wind;", outputCoverage);
}
void GrCCCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
@@ -101,14 +116,13 @@ void GrCCCubicHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
OutName(fGradMatrix), fKLMMatrix.c_str(), fKLMMatrix.c_str());
}
-void GrCCCubicHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
- const char* outputCoverage) const {
- f->codeAppendf("float k = %s.x, l = %s.y, m = %s.z, d = %s.w;",
- fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn());
+void GrCCCubicHullShader::emitCoverage(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
+ // k,l,m,d are defined by the base class.
f->codeAppend ("float f = k*k*k - l*m;");
f->codeAppendf("float2 grad_f = %s * float2(k, 1);", fGradMatrix.fsIn());
f->codeAppendf("%s = clamp(0.5 - f * inversesqrt(dot(grad_f, grad_f)), 0, 1);", outputCoverage);
- f->codeAppendf("%s += min(d, 0);", outputCoverage); // Flat closing edge.
+ f->codeAppendf("%s += min(d, 0);", outputCoverage); // Flat edge opposite the curve.
}
void GrCCCubicCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
@@ -132,14 +146,13 @@ void GrCCCubicCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
fKLMMatrix.c_str(), fEdgeDistanceEquation.c_str());
}
-void GrCCCubicCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
- const char* outputCoverage) const {
+void GrCCCubicCornerShader::emitCoverage(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
f->codeAppendf("float2x4 grad_klmd = float2x4(%s, %s);", fdKLMDdx.fsIn(), fdKLMDdy.fsIn());
// Erase what the previous hull shader wrote. We don't worry about the two corners falling on
// the same pixel because those cases should have been weeded out by this point.
- f->codeAppendf("float k = %s.x, l = %s.y, m = %s.z, d = %s.w;",
- fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn(), fKLMD.fsIn());
+ // k,l,m,d are defined by the base class.
f->codeAppend ("float f = k*k*k - l*m;");
f->codeAppend ("float2 grad_f = float3(3*k*k, -m, -l) * float2x3(grad_klmd);");
f->codeAppendf("%s = -clamp(0.5 - f * inversesqrt(dot(grad_f, grad_f)), 0, 1);",
diff --git a/src/gpu/ccpr/GrCCCubicShader.h b/src/gpu/ccpr/GrCCCubicShader.h
index a9875b6a4c..ffb9103969 100644
--- a/src/gpu/ccpr/GrCCCubicShader.h
+++ b/src/gpu/ccpr/GrCCCubicShader.h
@@ -25,15 +25,16 @@ class GrCCCubicShader : public GrCCCoverageProcessor::Shader {
protected:
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const final;
-
virtual void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const {}
- WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
- const char* position, const char* coverage, const char* wind) final;
-
+ void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* inputCoverage, const char* wind) final;
virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) = 0;
+ void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const final;
+ virtual void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const = 0;
+
GrShaderVar fKLMMatrix{"klm_matrix", kFloat3x3_GrSLType};
GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
GrGLSLVarying fKLMD;
@@ -41,7 +42,7 @@ protected:
class GrCCCubicHullShader : public GrCCCubicShader {
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
- void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
+ void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fGradMatrix;
};
@@ -50,7 +51,7 @@ class GrCCCubicCornerShader : public GrCCCubicShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
- void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
+ void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fdKLMDdx;
GrGLSLVarying fdKLMDdy;
diff --git a/src/gpu/ccpr/GrCCQuadraticShader.cpp b/src/gpu/ccpr/GrCCQuadraticShader.cpp
index d08026ad19..002fcfd340 100644
--- a/src/gpu/ccpr/GrCCQuadraticShader.cpp
+++ b/src/gpu/ccpr/GrCCQuadraticShader.cpp
@@ -33,23 +33,28 @@ void GrCCQuadraticShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const char* p
this->onEmitSetupCode(s, pts, repetitionID, vars);
}
-Shader::WindHandling GrCCQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope,
- SkString* code, const char* position,
- const char* coverage,
- const char* /*wind*/) {
- SkASSERT(!coverage);
-
- fXYD.reset(kFloat3_GrSLType, scope);
- varyingHandler->addVarying("xyd", &fXYD);
+void GrCCQuadraticShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLVarying::Scope scope, SkString* code,
+ const char* position, const char* inputCoverage,
+ const char* wind) {
+ SkASSERT(!inputCoverage);
+
+ fXYDW.reset(kFloat4_GrSLType, scope);
+ varyingHandler->addVarying("xydw", &fXYDW);
code->appendf("%s.xy = (%s * float3(%s, 1)).xy;",
- OutName(fXYD), fCanonicalMatrix.c_str(), position);
+ OutName(fXYDW), fCanonicalMatrix.c_str(), position);
code->appendf("%s.z = dot(%s.xy, %s) + %s.z;",
- OutName(fXYD), fEdgeDistanceEquation.c_str(), position,
+ OutName(fXYDW), fEdgeDistanceEquation.c_str(), position,
fEdgeDistanceEquation.c_str());
+ code->appendf("%s.w = %s;", OutName(fXYDW), wind);
this->onEmitVaryings(varyingHandler, scope, code);
- return WindHandling::kNotHandled;
+}
+
+void GrCCQuadraticShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
+ this->emitCoverage(f, outputCoverage);
+ f->codeAppendf("%s *= %s.w;", outputCoverage, fXYDW.fsIn()); // Sign by wind.
}
void GrCCQuadraticHullShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
@@ -76,15 +81,15 @@ void GrCCQuadraticHullShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandle
fGrad.reset(kFloat2_GrSLType, scope);
varyingHandler->addVarying("grad", &fGrad);
code->appendf("%s = float2(2 * %s.x, -1) * float2x2(%s);",
- OutName(fGrad), OutName(fXYD), fCanonicalMatrix.c_str());
+ OutName(fGrad), OutName(fXYDW), fCanonicalMatrix.c_str());
}
-void GrCCQuadraticHullShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
- const char* outputCoverage) const {
+void GrCCQuadraticHullShader::emitCoverage(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
f->codeAppendf("float d = (%s.x * %s.x - %s.y) * inversesqrt(dot(%s, %s));",
- fXYD.fsIn(), fXYD.fsIn(), fXYD.fsIn(), fGrad.fsIn(), fGrad.fsIn());
+ fXYDW.fsIn(), fXYDW.fsIn(), fXYDW.fsIn(), fGrad.fsIn(), fGrad.fsIn());
f->codeAppendf("%s = clamp(0.5 - d, 0, 1);", outputCoverage);
- f->codeAppendf("%s += min(%s.z, 0);", outputCoverage, fXYD.fsIn()); // Flat closing edge.
+ f->codeAppendf("%s += min(%s.z, 0);", outputCoverage, fXYDW.fsIn()); // Flat closing edge.
}
void GrCCQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const char* pts,
@@ -95,7 +100,7 @@ void GrCCQuadraticCornerShader::onEmitSetupCode(GrGLSLVertexGeoBuilder* s, const
}
void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope, SkString* code) {
+ GrGLSLVarying::Scope scope, SkString* code) {
fdXYDdx.reset(kFloat3_GrSLType, scope);
varyingHandler->addFlatVarying("dXYDdx", &fdXYDdx);
code->appendf("%s = float3(%s[0].x, %s[0].y, %s.x);",
@@ -109,10 +114,10 @@ void GrCCQuadraticCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHand
fEdgeDistanceEquation.c_str());
}
-void GrCCQuadraticCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
- const char* outputCoverage) const {
+void GrCCQuadraticCornerShader::emitCoverage(GrGLSLPPFragmentBuilder* f,
+ const char* outputCoverage) const {
f->codeAppendf("float x = %s.x, y = %s.y, d = %s.z;",
- fXYD.fsIn(), fXYD.fsIn(), fXYD.fsIn());
+ fXYDW.fsIn(), fXYDW.fsIn(), fXYDW.fsIn());
f->codeAppendf("float2x3 grad_xyd = float2x3(%s, %s);", fdXYDdx.fsIn(), fdXYDdy.fsIn());
// Erase what the previous hull shader wrote. We don't worry about the two corners falling on
@@ -124,7 +129,7 @@ void GrCCQuadraticCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
// Use software msaa to approximate coverage at the corner pixels.
int sampleCount = Shader::DefineSoftSampleLocations(f, "samples");
- f->codeAppendf("float3 xyd_center = float3(%s.xy, %s.z + 0.5);", fXYD.fsIn(), fXYD.fsIn());
+ f->codeAppendf("float3 xyd_center = float3(%s.xy, %s.z + 0.5);", fXYDW.fsIn(), fXYDW.fsIn());
f->codeAppendf("for (int i = 0; i < %i; ++i) {", sampleCount);
f->codeAppend ( "float3 xyd = grad_xyd * samples[i] + xyd_center;");
f->codeAppend ( "half f = xyd.y - xyd.x * xyd.x;"); // f > 0 -> inside curve.
diff --git a/src/gpu/ccpr/GrCCQuadraticShader.h b/src/gpu/ccpr/GrCCQuadraticShader.h
index 09fe01c1b4..bba3d36c30 100644
--- a/src/gpu/ccpr/GrCCQuadraticShader.h
+++ b/src/gpu/ccpr/GrCCQuadraticShader.h
@@ -24,18 +24,19 @@ class GrCCQuadraticShader : public GrCCCoverageProcessor::Shader {
protected:
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const final;
-
virtual void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const = 0;
- WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
- const char* position, const char* coverage, const char* wind) final;
-
+ void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* inputCoverage, const char* wind) final;
virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) {}
+ void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const final;
+ virtual void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const = 0;
+
const GrShaderVar fCanonicalMatrix{"canonical_matrix", kFloat3x3_GrSLType};
const GrShaderVar fEdgeDistanceEquation{"edge_distance_equation", kFloat3_GrSLType};
- GrGLSLVarying fXYD;
+ GrGLSLVarying fXYDW;
};
/**
@@ -48,7 +49,7 @@ class GrCCQuadraticHullShader : public GrCCQuadraticShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
- void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
+ void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fGrad;
};
@@ -60,7 +61,7 @@ class GrCCQuadraticCornerShader : public GrCCQuadraticShader {
void onEmitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
GeometryVars*) const override;
void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code) override;
- void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
+ void emitCoverage(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fdXYDdx;
GrGLSLVarying fdXYDdy;
diff --git a/src/gpu/ccpr/GrCCTriangleShader.cpp b/src/gpu/ccpr/GrCCTriangleShader.cpp
index b507b3747c..6e9b13ef69 100644
--- a/src/gpu/ccpr/GrCCTriangleShader.cpp
+++ b/src/gpu/ccpr/GrCCTriangleShader.cpp
@@ -12,19 +12,18 @@
using Shader = GrCCCoverageProcessor::Shader;
-Shader::WindHandling GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope,
- SkString* code, const char* /*position*/,
- const char* coverage, const char* wind) {
+void GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLVarying::Scope scope, SkString* code,
+ const char* /*position*/, const char* inputCoverage,
+ const char* wind) {
fCoverageTimesWind.reset(kHalf_GrSLType, scope);
- if (!coverage) {
+ if (!inputCoverage) {
varyingHandler->addFlatVarying("wind", &fCoverageTimesWind);
code->appendf("%s = %s;", OutName(fCoverageTimesWind), wind);
} else {
varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind);
- code->appendf("%s = %s * %s;", OutName(fCoverageTimesWind), coverage, wind);
+ code->appendf("%s = %s * %s;", OutName(fCoverageTimesWind), inputCoverage, wind);
}
- return WindHandling::kHandled;
}
void GrCCTriangleShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
@@ -86,12 +85,11 @@ void GrCCTriangleCornerShader::emitSetupCode(GrGLSLVertexGeoBuilder* s, const ch
s->codeAppend ("}");
}
-Shader::WindHandling
-GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
- GrGLSLVarying::Scope scope, SkString* code,
- const char* position, const char* coverage,
- const char* /*wind*/) {
- SkASSERT(!coverage);
+void GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
+ GrGLSLVarying::Scope scope, SkString* code,
+ const char* position, const char* inputCoverage,
+ const char* wind) {
+ SkASSERT(!inputCoverage);
fCornerLocationInAABoxes.reset(kFloat2x2_GrSLType, scope);
varyingHandler->addVarying("corner_location_in_aa_boxes", &fCornerLocationInAABoxes);
@@ -106,7 +104,9 @@ GrCCTriangleCornerShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler,
code->appendf( "%s[i] = %s[i];", OutName(fBisectInAABoxes), fGeoShaderBisects.c_str());
code->appendf("}");
- return WindHandling::kNotHandled;
+ fWindTimesHalf.reset(kHalf_GrSLType, scope);
+ varyingHandler->addFlatVarying("wind_times_half", &fWindTimesHalf);
+ code->appendf("%s = %s * .5;", OutName(fWindTimesHalf), wind);
}
void GrCCTriangleCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
@@ -148,5 +148,5 @@ void GrCCTriangleCornerShader::onEmitFragmentCode(GrGLSLPPFragmentBuilder* f,
f->codeAppendf( "%s += (corner.x - 1) * exit.y;", outputCoverage);
f->codeAppendf("}");
- f->codeAppendf("%s *= .5;", outputCoverage);
+ f->codeAppendf("%s *= %s;", outputCoverage, fWindTimesHalf.fsIn());
}
diff --git a/src/gpu/ccpr/GrCCTriangleShader.h b/src/gpu/ccpr/GrCCTriangleShader.h
index d40c2361f3..cc7bd0eb4f 100644
--- a/src/gpu/ccpr/GrCCTriangleShader.h
+++ b/src/gpu/ccpr/GrCCTriangleShader.h
@@ -17,9 +17,8 @@
* implement these steps in either one or two actual render passes.
*/
class GrCCTriangleShader : public GrCCCoverageProcessor::Shader {
- WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
- const char* position, const char* coverage,
- const char* wind) override;
+ void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* inputCoverage, const char* wind) override;
void onEmitFragmentCode(GrGLSLPPFragmentBuilder*, const char* outputCoverage) const override;
GrGLSLVarying fCoverageTimesWind;
@@ -33,9 +32,8 @@ class GrCCTriangleShader : public GrCCCoverageProcessor::Shader {
class GrCCTriangleCornerShader : public GrCCCoverageProcessor::Shader {
void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts, const char* repetitionID,
const char* wind, GeometryVars*) const override;
- WindHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
- const char* position, const char* coverage,
- const char* wind) override;
+ void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* inputCoverage, const char* wind) override;
void onEmitFragmentCode(GrGLSLPPFragmentBuilder* f, const char* outputCoverage) const override;
GrShaderVar fAABoxMatrices{"aa_box_matrices", kFloat2x2_GrSLType, 2};
@@ -43,6 +41,7 @@ class GrCCTriangleCornerShader : public GrCCCoverageProcessor::Shader {
GrShaderVar fGeoShaderBisects{"bisects", kFloat2_GrSLType, 2};
GrGLSLVarying fCornerLocationInAABoxes;
GrGLSLVarying fBisectInAABoxes;
+ GrGLSLVarying fWindTimesHalf;
};
#endif