From 5183e649efdcf4bf46a2883fdedec7a3b7e4fb0f Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Wed, 7 Mar 2018 12:53:01 -0700 Subject: [PATCH] ccpr: Combine GS triangle hulls and edges into a single draw Updates the geometry shader backend to match the vertex backend and draw triangle rasters together with their their edges in a single draw call. This gives a performance boost as well as cleaning up some API awkwardness. This is one step toward the final goal of drawing ccpr primitives in a single pass. Bug: skia: Change-Id: I2723692d02b9e39ca5dc5d9e022b528a051988ab Reviewed-on: https://skia-review.googlesource.com/112104 Commit-Queue: Chris Dalton Reviewed-by: Brian Salomon --- samplecode/SampleCCPRGeometry.cpp | 10 +- src/gpu/ccpr/GrCCCoverageProcessor.cpp | 7 +- src/gpu/ccpr/GrCCCoverageProcessor.h | 58 ++---- src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp | 173 ++++++++---------- src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp | 34 ++-- src/gpu/ccpr/GrCCPathParser.cpp | 18 +- src/gpu/ccpr/GrCCTriangleShader.cpp | 11 +- 7 files changed, 123 insertions(+), 188 deletions(-) diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp index a0c5d7be7a..a90ece09a1 100644 --- a/samplecode/SampleCCPRGeometry.cpp +++ b/samplecode/SampleCCPRGeometry.cpp @@ -33,7 +33,7 @@ using RenderPass = GrCCCoverageProcessor::RenderPass; static constexpr float kDebugBloat = 40; static int is_quadratic(RenderPass pass) { - return pass == RenderPass::kQuadraticHulls || pass == RenderPass::kQuadraticCorners; + return pass == RenderPass::kQuadratics || pass == RenderPass::kQuadraticCorners; } /** @@ -59,7 +59,7 @@ private: void updateGpuData(); - RenderPass fRenderPass = RenderPass::kTriangleHulls; + RenderPass fRenderPass = RenderPass::kTriangles; SkCubicType fCubicType; SkMatrix fCubicKLM; @@ -249,10 +249,6 @@ void CCPRGeometryView::Op::onExecute(GrOpFlushState* state) { ? static_cast(state->gpu()) : nullptr; - if (!GrCCCoverageProcessor::DoesRenderPass(fView->fRenderPass, state->caps())) { - return; - } - GrCCCoverageProcessor proc(rp, fView->fRenderPass, GrCCCoverageProcessor::WindMethod::kCrossProduct); SkDEBUGCODE(proc.enableDebugVisualizations(kDebugBloat)); @@ -346,7 +342,7 @@ bool CCPRGeometryView::onQuery(SkEvent* evt) { } SkUnichar unichar; if (SampleCode::CharQ(*evt, &unichar)) { - if (unichar >= '1' && unichar <= '7') { + if (unichar >= '1' && unichar <= '6') { fRenderPass = RenderPass(unichar - '1'); this->updateAndInval(); return true; diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.cpp b/src/gpu/ccpr/GrCCCoverageProcessor.cpp index 8c85a75d81..686ab5514d 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor.cpp @@ -119,20 +119,19 @@ void GrCCCoverageProcessor::getGLSLProcessorKey(const GrShaderCaps&, GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGLSLInstance(const GrShaderCaps&) const { std::unique_ptr shader; switch (fRenderPass) { - case RenderPass::kTriangleHulls: - case RenderPass::kTriangleEdges: + case RenderPass::kTriangles: shader = skstd::make_unique(); break; case RenderPass::kTriangleCorners: shader = skstd::make_unique(); break; - case RenderPass::kQuadraticHulls: + case RenderPass::kQuadratics: shader = skstd::make_unique(); break; case RenderPass::kQuadraticCorners: shader = skstd::make_unique(); break; - case RenderPass::kCubicHulls: + case RenderPass::kCubics: shader = skstd::make_unique(); break; case RenderPass::kCubicCorners: diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h index 698087735c..c1f85993a1 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor.h +++ b/src/gpu/ccpr/GrCCCoverageProcessor.h @@ -54,49 +54,21 @@ public: void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans, float w); }; - // All primitive shapes (triangles and closed, convex bezier curves) require more than one - // render pass. Here we enumerate every render pass needed in order to produce a complete + // All primitive shapes (triangles and closed, convex bezier curves) require two + // render passes: One to draw a rough outline of the shape, and a second pass to touch up the + // corners. Here we enumerate every render pass needed in order to produce a complete // coverage count mask. This is an exhaustive list of all ccpr coverage shaders. - // - // During a render pass, the "Impl" (GSImpl or VSimpl) generates conservative geometry for - // rasterization, and the Shader decides the coverage value at each pixel. 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 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. - kTriangleHulls, - kQuadraticHulls, - 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 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 - // jagged conservative raster edges into a smooth antialiased edge. - // - // NOTE: The Impl may combine this pass with kTriangleHulls, in which case DoesRenderPass() - // will be false for kTriangleEdges and it must not be used. - kTriangleEdges, - - // 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. Input coverage values sent to the Shader will be null. + kTriangles, kTriangleCorners, + kQuadratics, kQuadraticCorners, + kCubics, kCubicCorners }; static bool RenderPassIsCubic(RenderPass); static const char* RenderPassName(RenderPass); - constexpr static bool DoesRenderPass(RenderPass renderPass, const GrCaps& caps) { - return RenderPass::kTriangleEdges != renderPass || - caps.shaderCaps()->geometryShaderSupport(); - } - enum class WindMethod : bool { kCrossProduct, // Calculate wind = +/-1 by sign of the cross product. kInstanceData // Instance data provides custom, signed wind values of any magnitude. @@ -109,7 +81,6 @@ public: , fWindMethod(windMethod) , fImpl(rp->caps()->shaderCaps()->geometryShaderSupport() ? Impl::kGeometryShader : Impl::kVertexShader) { - SkASSERT(DoesRenderPass(pass, *rp->caps())); if (Impl::kGeometryShader == fImpl) { this->initGS(); } else { @@ -204,8 +175,7 @@ public: // Here the subclass adds its internal varyings to the handler and produces code to // initialize those varyings from a given position, input coverage value, and wind. // - // NOTE: the coverage input is only relevant for edges (see comments in RenderPass). - // Otherwise it is +1 all around. + // NOTE: the coverage input is only relevant for triangles. Otherwise it is null. virtual void onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code, const char* position, const char* inputCoverage, const char* wind) = 0; @@ -301,13 +271,12 @@ inline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint& p0, con inline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) { switch (pass) { - case RenderPass::kTriangleHulls: - case RenderPass::kTriangleEdges: + case RenderPass::kTriangles: case RenderPass::kTriangleCorners: - case RenderPass::kQuadraticHulls: + case RenderPass::kQuadratics: case RenderPass::kQuadraticCorners: return false; - case RenderPass::kCubicHulls: + case RenderPass::kCubics: case RenderPass::kCubicCorners: return true; } @@ -317,12 +286,11 @@ inline bool GrCCCoverageProcessor::RenderPassIsCubic(RenderPass pass) { inline const char* GrCCCoverageProcessor::RenderPassName(RenderPass pass) { switch (pass) { - case RenderPass::kTriangleHulls: return "kTriangleHulls"; - case RenderPass::kTriangleEdges: return "kTriangleEdges"; + case RenderPass::kTriangles: return "kTriangles"; case RenderPass::kTriangleCorners: return "kTriangleCorners"; - case RenderPass::kQuadraticHulls: return "kQuadraticHulls"; + case RenderPass::kQuadratics: return "kQuadratics"; case RenderPass::kQuadraticCorners: return "kQuadraticCorners"; - case RenderPass::kCubicHulls: return "kCubicHulls"; + case RenderPass::kCubics: return "kCubics"; case RenderPass::kCubicCorners: return "kCubicCorners"; } SK_ABORT("Invalid RenderPass"); diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp index fe541483b6..d9febc0e66 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor_GSImpl.cpp @@ -76,7 +76,7 @@ protected: SkSTArray<2, GrShaderVar> emitArgs; const char* position = emitArgs.emplace_back("position", kFloat2_GrSLType).c_str(); const char* coverage = nullptr; - if (RenderPass::kTriangleEdges == proc.fRenderPass) { + if (RenderPass::kTriangles == proc.fRenderPass) { coverage = emitArgs.emplace_back("coverage", kHalf_GrSLType).c_str(); } g->emitFunction(kVoid_GrSLType, "emitVertex", emitArgs.count(), emitArgs.begin(), [&]() { @@ -109,80 +109,110 @@ protected: }; /** - * Generates a conservative raster hull around a triangle. (See comments for RenderPass) + * Generates conservative rasters around a triangle and its edges, and calculates coverage ramps. + * + * Triangle rough outlines are drawn in two steps: (1) draw a conservative raster of the entire + * triangle, with a coverage of +1, and (2) draw conservative rasters around each edge, with a + * 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 GSCornerImpl. */ -class GSHull3Impl : public GrCCCoverageProcessor::GSImpl { +class GSTriangleImpl : public GrCCCoverageProcessor::GSImpl { public: - GSHull3Impl(std::unique_ptr shader) : GSImpl(std::move(shader)) {} + GSTriangleImpl(std::unique_ptr shader) : GSImpl(std::move(shader)) {} void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind, const char* emitVertexFn) const override { - Shader::GeometryVars vars; - fShader->emitSetupCode(g, "pts", nullptr, wind.c_str(), &vars); - - const char* hullPts = vars.fHullVars.fAlternatePoints; - if (!hullPts) { - hullPts = "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. // - // NOTE: We generate the hull in 2 independent invocations, so each invocation designates + // NOTE: We generate the rasters in 5 independent invocations, so each invocation designates // the corner it will begin with as the top. - g->codeAppendf("int i = %s > 0 ? sk_InvocationID : 1 - sk_InvocationID;", wind.c_str()); - g->codeAppendf("float2 top = %s[i];", hullPts); - g->codeAppendf("float2 left = %s[%s > 0 ? (1 - i) * 2 : i + 1];", hullPts, wind.c_str()); - g->codeAppendf("float2 right = %s[%s > 0 ? i + 1 : (1 - i) * 2];", hullPts, wind.c_str()); + g->codeAppendf("int i = (%s > 0 ? sk_InvocationID : 4 - sk_InvocationID) %% 3;", + wind.c_str()); + g->codeAppend ("float2 top = pts[i];"); + g->codeAppendf("float2 right = pts[(i + (%s > 0 ? 1 : 2)) %% 3];", wind.c_str()); + g->codeAppendf("float2 left = pts[(i + (%s > 0 ? 2 : 1)) %% 3];", wind.c_str()); - // Determine how much to outset the conservative raster hull from each of the three edges. - g->codeAppend ("float2 leftbloat = float2(top.y > left.y ? +bloat : -bloat, " - "top.x > left.x ? -bloat : +bloat);"); - g->codeAppend ("float2 rightbloat = float2(right.y > top.y ? +bloat : -bloat, " - "right.x > top.x ? -bloat : +bloat);"); - g->codeAppend ("float2 downbloat = float2(left.y > right.y ? +bloat : -bloat, " - "left.x > right.x ? -bloat : +bloat);"); + // Determine which direction to outset the conservative raster from each of the three edges. + g->codeAppend ("float2 leftbloat = sign(top - left);"); + g->codeAppend ("leftbloat = float2(0 != leftbloat.y ? leftbloat.y : leftbloat.x, " + "0 != leftbloat.x ? -leftbloat.x : -leftbloat.y);"); - // Here we generate the conservative raster geometry. It is the convex hull of 3 pixel-size - // boxes centered on the input points, split between two invocations. This translates to a - // polygon with either one, two, or three vertices at each input point, depending on how - // sharp the corner is. For more details on conservative raster, see: + g->codeAppend ("float2 rightbloat = sign(right - top);"); + g->codeAppend ("rightbloat = float2(0 != rightbloat.y ? rightbloat.y : rightbloat.x, " + "0 != rightbloat.x ? -rightbloat.x : -rightbloat.y);"); + + g->codeAppend ("float2 downbloat = sign(left - right);"); + g->codeAppend ("downbloat = float2(0 != downbloat.y ? downbloat.y : downbloat.x, " + "0 != downbloat.x ? -downbloat.x : -downbloat.y);"); + + // The triangle's conservative raster has a coverage of +1 all around. + g->codeAppend ("half4 coverages = half4(+1);"); + + // Edges have coverage ramps. + g->codeAppend ("if (sk_InvocationID >= 2) {"); // Are we an edge? + Shader::CalcEdgeCoverageAtBloatVertex(g, "top", "right", + "float2(+rightbloat.y, -rightbloat.x)", + "coverages[0]"); + g->codeAppend ( "coverages.yzw = half3(-1, 0, -1 - coverages[0]);"); + // Reassign bloats to characterize a conservative raster around a single edge, rather than + // the entire triangle. + g->codeAppend ( "leftbloat = downbloat = -rightbloat;"); + g->codeAppend ("}"); + + // These can't be scaled until after we calculate coverage. + g->codeAppend ("leftbloat *= bloat;"); + g->codeAppend ("rightbloat *= bloat;"); + g->codeAppend ("downbloat *= bloat;"); + + // Here we generate the conservative raster geometry. The triangle's conservative raster is + // the convex hull of 3 pixel-size boxes centered on the input points. This translates to a + // convex polygon with either one, two, or three vertices at each input point (depending on + // how sharp the corner is) that we split between two invocations. Edge conservative rasters + // are convex hulls of 2 pixel-size boxes, one at each endpoint. For more details on + // conservative raster, see: // https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter42.html g->codeAppendf("bool2 left_right_notequal = notEqual(leftbloat, rightbloat);"); g->codeAppend ("if (all(left_right_notequal)) {"); // The top corner will have three conservative raster vertices. Emit the // middle one first to the triangle strip. - g->codeAppendf( "%s(top + float2(-leftbloat.y, leftbloat.x));", emitVertexFn); + g->codeAppendf( "%s(top + float2(-leftbloat.y, +leftbloat.x), coverages[0]);", + emitVertexFn); g->codeAppend ("}"); g->codeAppend ("if (any(left_right_notequal)) {"); // Second conservative raster vertex for the top corner. - g->codeAppendf( "%s(top + rightbloat);", emitVertexFn); + g->codeAppendf( "%s(top + rightbloat, coverages[1]);", emitVertexFn); g->codeAppend ("}"); - // Main interior body of the triangle. - g->codeAppendf("%s(top + leftbloat);", emitVertexFn); - g->codeAppendf("%s(right + rightbloat);", emitVertexFn); + // Main interior body. + g->codeAppendf("%s(top + leftbloat, coverages[2]);", emitVertexFn); + g->codeAppendf("%s(right + rightbloat, coverages[1]);", emitVertexFn); - // Here the two invocations diverge. We can't symmetrically divide three triangle points - // between two invocations, so each does the following: + // Here the invocations diverge slightly. We can't symmetrically divide three triangle + // points between two invocations, so each does the following: // - // sk_InvocationID=0: Finishes the main interior body of the triangle. - // sk_InvocationID=1: Remaining two conservative raster vertices for the third corner. + // sk_InvocationID=0: Finishes the main interior body of the triangle hull. + // sk_InvocationID=1: Remaining two conservative raster vertices for the third hull corner. + // sk_InvocationID=2..4: Finish the opposite endpoint of their corresponding edge. g->codeAppendf("bool2 right_down_notequal = notEqual(rightbloat, downbloat);"); g->codeAppend ("if (any(right_down_notequal) || 0 == sk_InvocationID) {"); - g->codeAppendf( "%s(sk_InvocationID == 0 ? left + leftbloat : right + downbloat);", - emitVertexFn); + g->codeAppendf( "%s(0 == sk_InvocationID ? left + leftbloat : right + downbloat, " + "coverages[2]);", emitVertexFn); g->codeAppend ("}"); g->codeAppend ("if (all(right_down_notequal) && 0 != sk_InvocationID) {"); - g->codeAppendf( "%s(right + float2(-rightbloat.y, rightbloat.x));", emitVertexFn); + g->codeAppendf( "%s(right + float2(-rightbloat.y, +rightbloat.x), coverages[3]);", + emitVertexFn); g->codeAppend ("}"); - g->configure(InputType::kLines, OutputType::kTriangleStrip, 6, 2); + // 5 invocations: 2 triangle hull invocations and 3 edges. + g->configure(InputType::kLines, OutputType::kTriangleStrip, 6, 5); } }; /** - * Generates a conservative raster hull around a convex quadrilateral. (See comments for RenderPass) + * Generates a conservative raster around a convex quadrilateral that encloses a cubic or quadratic. */ class GSHull4Impl : public GrCCCoverageProcessor::GSImpl { public: @@ -252,53 +282,6 @@ public: } }; -/** - * Generates conservatives around each edge of a triangle. (See comments for RenderPass) - */ -class GSEdgeImpl : public GrCCCoverageProcessor::GSImpl { -public: - GSEdgeImpl(std::unique_ptr shader) : GSImpl(std::move(shader)) {} - - void onEmitGeometryShader(GrGLSLGeometryBuilder* g, const GrShaderVar& wind, - const char* emitVertexFn) const override { - fShader->emitSetupCode(g, "pts", "sk_InvocationID", wind.c_str(), nullptr); - - g->codeAppend ("int nextidx = 2 != sk_InvocationID ? sk_InvocationID + 1 : 0;"); - g->codeAppendf("float2 left = pts[%s > 0 ? sk_InvocationID : nextidx];", wind.c_str()); - g->codeAppendf("float2 right = pts[%s > 0 ? nextidx : sk_InvocationID];", wind.c_str()); - - // Which quadrant does the vector from left -> right fall into? - g->codeAppend ("float2 qlr = sign(right - left);"); - g->codeAppend ("float2x2 outer_pts = float2x2(left - bloat * qlr, right + bloat * qlr);"); - g->codeAppend ("half outer_coverage;"); - Shader::CalcEdgeCoverageAtBloatVertex(g, "left", "right", "qlr", "outer_coverage"); - - g->codeAppend ("float2 d1 = float2(qlr.y, -qlr.x);"); - g->codeAppend ("float2 d2 = d1;"); - g->codeAppend ("bool aligned = qlr.x == 0 || qlr.y == 0;"); - g->codeAppend ("if (aligned) {"); - g->codeAppend ( "d1 -= qlr;"); - g->codeAppend ( "d2 += qlr;"); - g->codeAppend ("}"); - - // Emit the convex hull of 2 pixel-size boxes centered on the endpoints of the edge. Each - // invocation emits a different edge. Emit negative coverage that subtracts the appropiate - // amount back out from the hull we drew above. - g->codeAppend ("if (!aligned) {"); - g->codeAppendf( "%s(outer_pts[0], -1 - outer_coverage);", emitVertexFn); - g->codeAppend ("}"); - g->codeAppendf("%s(left + bloat * d1, -1);", emitVertexFn); - g->codeAppendf("%s(left - bloat * d2, 0);", emitVertexFn); - g->codeAppendf("%s(right + bloat * d2, -1);", emitVertexFn); - g->codeAppendf("%s(right - bloat * d1, 0);", emitVertexFn); - g->codeAppend ("if (!aligned) {"); - g->codeAppendf( "%s(outer_pts[1], outer_coverage);", emitVertexFn); - g->codeAppend ("}"); - - g->configure(InputType::kLines, OutputType::kTriangleStrip, 6, 3); - } -}; - /** * Generates conservative rasters around corners. (See comments for RenderPass) */ @@ -358,15 +341,13 @@ void GrCCCoverageProcessor::appendGSMesh(GrBuffer* instanceBuffer, int instanceC GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createGSImpl(std::unique_ptr shadr) const { switch (fRenderPass) { - case RenderPass::kTriangleHulls: - return new GSHull3Impl(std::move(shadr)); - case RenderPass::kQuadraticHulls: - case RenderPass::kCubicHulls: - return new GSHull4Impl(std::move(shadr)); - case RenderPass::kTriangleEdges: - return new GSEdgeImpl(std::move(shadr)); + case RenderPass::kTriangles: + return new GSTriangleImpl(std::move(shadr)); case RenderPass::kTriangleCorners: return new GSCornerImpl(std::move(shadr), 3); + case RenderPass::kQuadratics: + case RenderPass::kCubics: + return new GSHull4Impl(std::move(shadr)); case RenderPass::kQuadraticCorners: case RenderPass::kCubicCorners: return new GSCornerImpl(std::move(shadr), 2); diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp index 4c3bb67a93..144a4a5d58 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp @@ -244,8 +244,18 @@ static constexpr uint16_t kHull4IndicesAsTris[] = { GR_DECLARE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey); /** - * Generates a conservative raster hull around a convex polygon. For triangles, we also generate - * independent conservative rasters around each edge. (See comments for RenderPass) + * Generates a conservative raster hull around a convex polygon. For triangles we generate + * additional conservative rasters around the edges and calculate coverage ramps. + * + * Triangle rough outlines are drawn in two steps: (1) draw a conservative raster of the entire + * triangle, with a coverage of +1, and (2) draw conservative rasters around each edge, with a + * coverage ramp from -1 to 0. These edge coverage values convert jagged conservative raster edges + * into smooth, antialiased ones. + * + * Curve rough outlines are just the conservative raster of a convex quadrilateral that encloses the + * curve. The Shader takes care of everything else for now. + * + * The final corners get touched up in a later step by VSCornerImpl. */ class VSHullAndEdgeImpl : public GrCCCoverageProcessor::VSImpl { public: @@ -392,7 +402,7 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { const GrCaps& caps = *rp->caps(); switch (fRenderPass) { - case RenderPass::kTriangleHulls: { + case RenderPass::kTriangles: { GR_DEFINE_STATIC_UNIQUE_KEY(gHull3AndEdgeVertexBufferKey); fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType, sizeof(kHull3AndEdgeVertices), @@ -414,8 +424,9 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { } break; } - case RenderPass::kQuadraticHulls: - case RenderPass::kCubicHulls: { + + case RenderPass::kQuadratics: + case RenderPass::kCubics: { GR_DEFINE_STATIC_UNIQUE_KEY(gHull4VertexBufferKey); fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType, sizeof(kHull4Vertices), kHull4Vertices, gHull4VertexBufferKey); @@ -435,9 +446,7 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { } break; } - case RenderPass::kTriangleEdges: - SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl."); - break; + case RenderPass::kTriangleCorners: case RenderPass::kQuadraticCorners: case RenderPass::kCubicCorners: { @@ -514,14 +523,11 @@ void GrCCCoverageProcessor::appendVSMesh(GrBuffer* instanceBuffer, int instanceC GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createVSImpl(std::unique_ptr shadr) const { switch (fRenderPass) { - case RenderPass::kTriangleHulls: + case RenderPass::kTriangles: return new VSHullAndEdgeImpl(std::move(shadr), 3); - case RenderPass::kQuadraticHulls: - case RenderPass::kCubicHulls: + case RenderPass::kQuadratics: + case RenderPass::kCubics: return new VSHullAndEdgeImpl(std::move(shadr), 4); - case RenderPass::kTriangleEdges: - SK_ABORT("kTriangleEdges RenderPass is not used by VSImpl."); - return nullptr; case RenderPass::kTriangleCorners: case RenderPass::kQuadraticCorners: case RenderPass::kCubicCorners: diff --git a/src/gpu/ccpr/GrCCPathParser.cpp b/src/gpu/ccpr/GrCCPathParser.cpp index 8bb507bd01..43f5e6be6a 100644 --- a/src/gpu/ccpr/GrCCPathParser.cpp +++ b/src/gpu/ccpr/GrCCPathParser.cpp @@ -512,36 +512,30 @@ void GrCCPathParser::drawCoverageCount(GrOpFlushState* flushState, CoverageCount SkBlendMode::kPlus); if (batchTotalCounts.fTriangles) { - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleHulls, + this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangles, WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles, drawBounds); - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleEdges, - WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles, - drawBounds); // Might get skipped. this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleCorners, WindMethod::kCrossProduct, &PrimitiveTallies::fTriangles, drawBounds); } if (batchTotalCounts.fWoundTriangles) { - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleHulls, + this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangles, WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles, drawBounds); - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleEdges, - WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles, - drawBounds); // Might get skipped. this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kTriangleCorners, WindMethod::kInstanceData, &PrimitiveTallies::fWoundTriangles, drawBounds); } if (batchTotalCounts.fQuadratics) { - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticHulls, + this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadratics, WindMethod::kCrossProduct, &PrimitiveTallies::fQuadratics, drawBounds); this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kQuadraticCorners, WindMethod::kCrossProduct, &PrimitiveTallies::fQuadratics, drawBounds); } if (batchTotalCounts.fCubics) { - this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicHulls, + this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubics, WindMethod::kCrossProduct, &PrimitiveTallies::fCubics, drawBounds); this->drawRenderPass(flushState, pipeline, batchID, RenderPass::kCubicCorners, WindMethod::kCrossProduct, &PrimitiveTallies::fCubics, drawBounds); @@ -556,10 +550,6 @@ void GrCCPathParser::drawRenderPass(GrOpFlushState* flushState, const GrPipeline const SkIRect& drawBounds) const { SkASSERT(pipeline.getScissorState().enabled()); - if (!GrCCCoverageProcessor::DoesRenderPass(renderPass, flushState->caps())) { - return; - } - // Don't call reset(), as that also resets the reserve count. fMeshesScratchBuffer.pop_back_n(fMeshesScratchBuffer.count()); fDynamicStatesScratchBuffer.pop_back_n(fDynamicStatesScratchBuffer.count()); diff --git a/src/gpu/ccpr/GrCCTriangleShader.cpp b/src/gpu/ccpr/GrCCTriangleShader.cpp index f371b03fac..e086201b42 100644 --- a/src/gpu/ccpr/GrCCTriangleShader.cpp +++ b/src/gpu/ccpr/GrCCTriangleShader.cpp @@ -16,15 +16,10 @@ void GrCCTriangleShader::onEmitVaryings(GrGLSLVaryingHandler* varyingHandler, GrGLSLVarying::Scope scope, SkString* code, const char* /*position*/, const char* inputCoverage, const char* wind) { + SkASSERT(inputCoverage); fCoverageTimesWind.reset(kHalf_GrSLType, scope); - if (!inputCoverage) { - varyingHandler->addVarying("wind", &fCoverageTimesWind, - GrGLSLVaryingHandler::Interpolation::kCanBeFlat); - code->appendf("%s = %s;", OutName(fCoverageTimesWind), wind); - } else { - varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind); - code->appendf("%s = %s * %s;", OutName(fCoverageTimesWind), inputCoverage, wind); - } + varyingHandler->addVarying("coverage_times_wind", &fCoverageTimesWind); + code->appendf("%s = %s * %s;", OutName(fCoverageTimesWind), inputCoverage, wind); } void GrCCTriangleShader::onEmitFragmentCode(GrGLSLFPFragmentBuilder* f,