diff options
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp')
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp | 99 |
1 files changed, 53 insertions, 46 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp index 0bb34b16a0..4207f85c15 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp @@ -21,7 +21,6 @@ protected: GSImpl(std::unique_ptr<Shader> shader) : fShader(std::move(shader)) {} virtual bool hasCoverage() const { return false; } - virtual bool hasAttenuatedCoverage() const { return false; } void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor&, FPCoordTransformIter&& transformIter) final { @@ -81,21 +80,20 @@ protected: if (this->hasCoverage()) { coverage = emitArgs.emplace_back("coverage", kHalf_GrSLType).c_str(); } - const char* attenuatedCoverage = nullptr; - if (this->hasAttenuatedCoverage()) { - attenuatedCoverage = emitArgs.emplace_back("attenuated_coverage", - kHalf2_GrSLType).c_str(); + const char* cornerCoverage = nullptr; + if (GSSubpass::kCorners == proc.fGSSubpass) { + cornerCoverage = emitArgs.emplace_back("corner_coverage", kHalf2_GrSLType).c_str(); } g->emitFunction(kVoid_GrSLType, "emitVertex", emitArgs.count(), emitArgs.begin(), [&]() { SkString fnBody; if (coverage) { fnBody.appendf("%s *= %s;", coverage, wind.c_str()); } - if (attenuatedCoverage) { - fnBody.appendf("%s.x *= %s;", attenuatedCoverage, wind.c_str()); + if (cornerCoverage) { + fnBody.appendf("%s.x *= %s;", cornerCoverage, wind.c_str()); } fShader->emitVaryings(varyingHandler, GrGLSLVarying::Scope::kGeoToFrag, &fnBody, - position, coverage ? coverage : wind.c_str(), attenuatedCoverage); + position, coverage ? coverage : wind.c_str(), cornerCoverage); g->emitVertex(&fnBody, position, rtAdjust); return fnBody; }().c_str(), &emitVertexFn); @@ -303,7 +301,6 @@ public: GSCornerImpl(std::unique_ptr<Shader> shader) : GSImpl(std::move(shader)) {} bool hasCoverage() const override { return true; } - bool hasAttenuatedCoverage() const override { return true; } void onEmitGeometryShader(const GrCCCoverageProcessor& proc, GrGLSLGeometryBuilder* g, const GrShaderVar& wind, const char* emitVertexFn) const override { @@ -334,47 +331,57 @@ public: "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 ("half attenuation; {"); + Shader::CalcCornerAttenuation(g, "leftdir", "rightdir", "attenuation"); g->codeAppend ("}"); - g->codeAppend ("half2 right_coverages; {"); - Shader::CalcEdgeCoveragesAtBloatVertices(g, "corner", "right", "-outbloat", "crossbloat", - "right_coverages"); - g->codeAppend ("}"); + if (isTriangle) { + 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. The first coverage argument erases the values that were written + // previously by the hull and edge geometry. The second pair are multiplied together by + // the fragment shader. They ramp to 0 with attenuation in the direction of outbloat, + // and linearly from left-edge coverage to right-edge coverage in the direction of + // crossbloat. + // + // NOTE: Since this is not a linear mapping, it is important that the box's diagonal + // shared edge points in the direction of outbloat. + g->codeAppendf("%s(corner - crossbloat * bloat, right_coverages[1] - left_coverages[1]," + "half2(1 + left_coverages[1], 1));", + emitVertexFn); - g->codeAppend ("half attenuation; {"); - Shader::CalcCornerCoverageAttenuation(g, "leftdir", "rightdir", "attenuation"); - g->codeAppend ("}"); + g->codeAppendf("%s(corner + outbloat * bloat, " + "1 + left_coverages[0] + right_coverages[0], half2(0, attenuation));", + emitVertexFn); - // Emit a corner box. The first coverage argument erases the values that were written - // previously by the hull and edge geometry. The second pair are multiplied together by the - // fragment shader. They ramp to 0 with attenuation in the direction of outbloat, and - // linearly from left-edge coverage to right-edge coverage in the direction of crossbloat. - // - // NOTE: Since this is not a linear mapping, it is important that the box's diagonal shared - // edge points in the direction of outbloat. - g->codeAppendf("%s(corner - crossbloat * bloat, %s, half2(1 + left_coverages[1], 1));", - emitVertexFn, - // Erase what the hull wrote previously. - isTriangle ? "right_coverages[1] - left_coverages[1]" : "-1"); - - g->codeAppendf("%s(corner + outbloat * bloat, %s, half2(0, attenuation));", - emitVertexFn, - // Erase what the hull wrote previously. - isTriangle ? "1 + left_coverages[0] + right_coverages[0]" : "-1"); - - g->codeAppendf("%s(corner - outbloat * bloat, %s, " - "half2(1 + left_coverages[0] + right_coverages[0], 1));", - emitVertexFn, - // Erase what the hull wrote previously. - isTriangle ? "-1 - left_coverages[0] - right_coverages[0]" : "-1"); - - g->codeAppendf("%s(corner + crossbloat * bloat, %s, half2(1 + right_coverages[1], 1));", - emitVertexFn, - // Erase what the hull wrote previously. - isTriangle ? "left_coverages[1] - right_coverages[1]" : "-1"); + g->codeAppendf("%s(corner - outbloat * bloat, " + "-1 - left_coverages[0] - right_coverages[0], " + "half2(1 + left_coverages[0] + right_coverages[0], 1));", + emitVertexFn); + + g->codeAppendf("%s(corner + crossbloat * bloat, left_coverages[1] - right_coverages[1]," + "half2(1 + right_coverages[1], 1));", + emitVertexFn); + } else { + // Curves are simpler. The first coverage value of -1 means "wind = -wind", and causes + // the Shader to erase what it had written previously for the hull. Then, at each vertex + // of the corner box, the Shader will calculate the curve's local coverage value, + // interpolate it alongside our attenuation parameter, and multiply the two together for + // a final coverage value. + g->codeAppendf("%s(corner - crossbloat * bloat, -1, half2(1));", emitVertexFn); + g->codeAppendf("%s(corner + outbloat * bloat, -1, half2(0, attenuation));", + emitVertexFn); + g->codeAppendf("%s(corner - outbloat * bloat, -1, half2(1));", emitVertexFn); + g->codeAppendf("%s(corner + crossbloat * bloat, -1, half2(1));", emitVertexFn); + } g->configure(InputType::kLines, OutputType::kTriangleStrip, 4, isTriangle ? 3 : 2); } |