diff options
author | 2018-03-08 15:55:58 +0000 | |
---|---|---|
committer | 2018-03-08 15:56:02 +0000 | |
commit | baf3e78092243210ca4489e51134df6fc8a90eee (patch) | |
tree | 41d16430ad639f72787a148f04476ee079e9ad56 /src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp | |
parent | fe462efbcb105914e4c4bbf689525b530a438773 (diff) |
Revert "ccpr: Draw curves in a single pass"
This reverts commit df04ce29490a24f9d5b4f5caafd8f6a3368a19e0.
Reason for revert: Going to revisit AAA quality
Original change's description:
> ccpr: Draw curves in a single pass
>
> Throws out the complicated MSAA curve corner shaders, and instead just
> ramps coverage to zero at bloat vertices that fall outside the curve.
>
> Updates SampleCCPRGeometry to better visualize this new geometry by
> clearing to black and drawing with SkBlendMode::kPlus.
>
> Bug: skia:
> Change-Id: Ibe86cbc741d8b015127b10dd43e3b52e7cb35732
> Reviewed-on: https://skia-review.googlesource.com/112626
> Commit-Queue: Chris Dalton <csmartdalton@google.com>
> Reviewed-by: Brian Salomon <bsalomon@google.com>
TBR=bsalomon@google.com,csmartdalton@google.com
Change-Id: I014baa60b248d870717f5ee8794e0bed66da86e6
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:
Reviewed-on: https://skia-review.googlesource.com/113181
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp')
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp | 199 |
1 files changed, 96 insertions, 103 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp index 08398e1900..144a4a5d58 100644 --- a/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp +++ b/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp @@ -92,13 +92,13 @@ protected: static constexpr int kVertexData_LeftNeighborIdShift = 9; static constexpr int kVertexData_RightNeighborIdShift = 7; static constexpr int kVertexData_BloatIdxShift = 5; -static constexpr int kVertexData_InvertNegativeCoverageBit = 1 << 4; +static constexpr int kVertexData_InvertCoverageBit = 1 << 4; static constexpr int kVertexData_IsEdgeBit = 1 << 3; static constexpr int kVertexData_IsHullBit = 1 << 2; /** * Vertex data tells the shader how to offset vertices for conservative raster, and how/whether to - * calculate coverage values. See VSHullAndEdgeImpl. + * calculate initial coverage values for edges. See VSHullAndEdgeImpl. */ static constexpr int32_t pack_vertex_data(int32_t leftNeighborID, int32_t rightNeighborID, int32_t bloatIdx, int32_t cornerID, @@ -114,12 +114,15 @@ static constexpr int32_t hull_vertex_data(int32_t cornerID, int32_t bloatIdx, in kVertexData_IsHullBit); } -static constexpr int32_t edge_vertex_data(int32_t leftID, int rightID, int32_t bloatIdx, - int32_t extraData = 0) { - return pack_vertex_data(leftID, leftID, bloatIdx, rightID, kVertexData_IsEdgeBit | extraData); +static constexpr int32_t edge_vertex_data(int32_t edgeID, int32_t endptIdx, int32_t bloatIdx, + int n) { + return pack_vertex_data(0 == endptIdx ? (edgeID + 1) % n : edgeID, + 0 == endptIdx ? (edgeID + 1) % n : edgeID, + bloatIdx, 0 == endptIdx ? edgeID : (edgeID + 1) % n, + kVertexData_IsEdgeBit | + (!endptIdx ? kVertexData_InvertCoverageBit : 0)); } - static constexpr int32_t kHull3AndEdgeVertices[] = { hull_vertex_data(0, 0, 3), hull_vertex_data(0, 1, 3), @@ -131,26 +134,26 @@ static constexpr int32_t kHull3AndEdgeVertices[] = { hull_vertex_data(2, 1, 3), hull_vertex_data(2, 2, 3), - edge_vertex_data(0, 1, 0), - edge_vertex_data(0, 1, 1), - edge_vertex_data(0, 1, 2), - edge_vertex_data(1, 0, 0, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(1, 0, 1, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(1, 0, 2, kVertexData_InvertNegativeCoverageBit), - - edge_vertex_data(1, 2, 0), - edge_vertex_data(1, 2, 1), - edge_vertex_data(1, 2, 2), - edge_vertex_data(2, 1, 0, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(2, 1, 1, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(2, 1, 2, kVertexData_InvertNegativeCoverageBit), - - edge_vertex_data(2, 0, 0), - edge_vertex_data(2, 0, 1), - edge_vertex_data(2, 0, 2), - edge_vertex_data(0, 2, 0, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(0, 2, 1, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(0, 2, 2, kVertexData_InvertNegativeCoverageBit), + edge_vertex_data(0, 0, 0, 3), + edge_vertex_data(0, 0, 1, 3), + edge_vertex_data(0, 0, 2, 3), + edge_vertex_data(0, 1, 0, 3), + edge_vertex_data(0, 1, 1, 3), + edge_vertex_data(0, 1, 2, 3), + + edge_vertex_data(1, 0, 0, 3), + edge_vertex_data(1, 0, 1, 3), + edge_vertex_data(1, 0, 2, 3), + edge_vertex_data(1, 1, 0, 3), + edge_vertex_data(1, 1, 1, 3), + edge_vertex_data(1, 1, 2, 3), + + edge_vertex_data(2, 0, 0, 3), + edge_vertex_data(2, 0, 1, 3), + edge_vertex_data(2, 0, 2, 3), + edge_vertex_data(2, 1, 0, 3), + edge_vertex_data(2, 1, 1, 3), + edge_vertex_data(2, 1, 2, 3), }; GR_DECLARE_STATIC_UNIQUE_KEY(gHull3AndEdgeVertexBufferKey); @@ -198,7 +201,7 @@ static constexpr uint16_t kHull3AndEdgeIndicesAsTris[] = { GR_DECLARE_STATIC_UNIQUE_KEY(gHull3AndEdgeIndexBufferKey); -static constexpr int32_t kHull4AndEdgeVertices[] = { +static constexpr int32_t kHull4Vertices[] = { hull_vertex_data(0, 0, 4), hull_vertex_data(0, 1, 4), hull_vertex_data(0, 2, 4), @@ -212,23 +215,17 @@ static constexpr int32_t kHull4AndEdgeVertices[] = { hull_vertex_data(3, 1, 4), hull_vertex_data(3, 2, 4), - edge_vertex_data(0, 3, 0, kVertexData_InvertNegativeCoverageBit), - edge_vertex_data(0, 3, 1), - edge_vertex_data(0, 3, 2), - edge_vertex_data(3, 0, 0), - edge_vertex_data(3, 0, 1), - edge_vertex_data(3, 0, 2, kVertexData_InvertNegativeCoverageBit), + // No edges for now (beziers don't use edges). }; -GR_DECLARE_STATIC_UNIQUE_KEY(gHull4AndEdgeVertexBufferKey); +GR_DECLARE_STATIC_UNIQUE_KEY(gHull4VertexBufferKey); -static constexpr uint16_t kHull4AndEdgeIndicesAsStrips[] = { +static constexpr uint16_t kHull4IndicesAsStrips[] = { 1, 0, 2, 11, 3, 5, 4, kRestartStrip, // First half of the hull (split diagonally). - 7, 6, 8, 5, 9, 11, 10, kRestartStrip, // Second half of the hull. - 13, 12, 14, 17, 15, 16 // Shared edge. + 7, 6, 8, 5, 9, 11, 10 // Second half of the hull. }; -static constexpr uint16_t kHull4AndEdgeIndicesAsTris[] = { +static constexpr uint16_t kHull4IndicesAsTris[] = { // First half of the hull (split diagonally). 1, 0, 2, 0, 11, 2, @@ -242,30 +239,23 @@ static constexpr uint16_t kHull4AndEdgeIndicesAsTris[] = { 8, 5, 9, 5, 11, 9, 9, 11, 10, - - // Shared edge. - 13, 12, 14, - 12, 17, 14, - 14, 17, 15, - 17, 16, 15, }; -GR_DECLARE_STATIC_UNIQUE_KEY(gHull4AndEdgeIndexBufferKey); +GR_DECLARE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey); /** - * Generates a conservative raster hull around a triangle or curve. For triangles we generate - * additional conservative rasters with coverage ramps around the edges. For curves we - * generate an additional raster with coverage ramps around its shared edge. + * 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. (2) Draw conservative rasters around each edge, with a + * 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 VSCornerImpl. + * into smooth, antialiased ones. * - * Curves are drawn in two steps: (1) Draw a conservative raster around the input points, passing - * coverage=+1 to the Shader. (2) Draw an additional conservative raster around the curve's shared - * edge, using coverage=-1 at bloat vertices that fall outside the input points. This erases what - * the hull just wrote and ramps coverage to zero. + * 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: @@ -294,9 +284,10 @@ public: // Here we generate conservative raster geometry for the input polygon. It is the convex // hull of N pixel-size boxes, one centered on each the input points. Each corner has three // vertices, where one or two may cause degenerate triangles. The vertex data tells us how - // to offset each vertex. Edges are also handled here using the same concept. For more - // details on conservative raster, see: + // to offset each vertex. For more details on conservative raster, see: // https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter42.html + // + // Triangle edges are also handled here using the same concept (see kHull3AndEdgeVertices). v->codeAppendf("float2 corner = %s[clockwise_indices & 3];", hullPts); v->codeAppendf("float2 left = %s[clockwise_indices >> %i];", hullPts, kVertexData_LeftNeighborIdShift); @@ -333,32 +324,29 @@ public: // fallthru. v->codeAppend ("}"); - v->codeAppend ("float2 vertex = corner + bloatdir * bloat;"); - gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex"); - - // The hull has a coverage of +1 all around. - v->codeAppend ("half coverage = +1;"); - + // For triangles, we also emit coverage in order to handle edges and corners. + const char* coverage = nullptr; if (3 == fNumSides) { - v->codeAppendf("if (0 != (%s & %i)) {", // Are we an edge? - proc.getAttrib(kAttribIdx_VertexData).fName, kVertexData_IsEdgeBit); + v->codeAppend ("half coverage;"); Shader::CalcEdgeCoverageAtBloatVertex(v, "left", "corner", "bloatdir", "coverage"); + v->codeAppendf("if (0 != (%s & %i)) {", // Are we the opposite endpoint of an edge? + proc.getAttrib(kAttribIdx_VertexData).fName, + kVertexData_InvertCoverageBit); + v->codeAppend ( "coverage = -1 - coverage;"); v->codeAppend ("}"); - } else { - SkASSERT(4 == fNumSides); - v->codeAppendf("if (0 != (%s & %i)) {", // Are we an edge? - proc.getAttrib(kAttribIdx_VertexData).fName, kVertexData_IsEdgeBit); - v->codeAppend ( "coverage = -1;"); + + v->codeAppendf("if (0 != (%s & %i)) {", // Are we a hull vertex? + proc.getAttrib(kAttribIdx_VertexData).fName, kVertexData_IsHullBit); + v->codeAppend ( "coverage = +1;"); // Hull coverage is +1 all around. v->codeAppend ("}"); + + coverage = "coverage"; } - v->codeAppendf("if (0 != (%s & %i)) {", // Invert coverage? - proc.getAttrib(kAttribIdx_VertexData).fName, - kVertexData_InvertNegativeCoverageBit); - v->codeAppend ( "coverage = -1 - coverage;"); - v->codeAppend ("}"); + v->codeAppend ("float2 vertex = corner + bloatdir * bloat;"); + gpArgs->fPositionVar.set(kFloat2_GrSLType, "vertex"); - return "coverage"; + return coverage; } private: @@ -437,7 +425,31 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { break; } - case RenderPass::kTriangleCorners: { + case RenderPass::kQuadratics: + case RenderPass::kCubics: { + GR_DEFINE_STATIC_UNIQUE_KEY(gHull4VertexBufferKey); + fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType, sizeof(kHull4Vertices), + kHull4Vertices, gHull4VertexBufferKey); + GR_DEFINE_STATIC_UNIQUE_KEY(gHull4IndexBufferKey); + if (caps.usePrimitiveRestart()) { + fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, + sizeof(kHull4IndicesAsStrips), + kHull4IndicesAsStrips, + gHull4IndexBufferKey); + fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull4IndicesAsStrips); + } else { + fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, + sizeof(kHull4IndicesAsTris), + kHull4IndicesAsTris, + gHull4IndexBufferKey); + fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull4IndicesAsTris); + } + break; + } + + case RenderPass::kTriangleCorners: + case RenderPass::kQuadraticCorners: + case RenderPass::kCubicCorners: { GR_DEFINE_STATIC_UNIQUE_KEY(gCornerIndexBufferKey); if (caps.usePrimitiveRestart()) { fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, @@ -452,35 +464,14 @@ void GrCCCoverageProcessor::initVS(GrResourceProvider* rp) { gCornerIndexBufferKey); fNumIndicesPerInstance = SK_ARRAY_COUNT(kCornerIndicesAsTris); } - break; - } - - case RenderPass::kQuadratics: - case RenderPass::kCubics: { - GR_DEFINE_STATIC_UNIQUE_KEY(gHull4AndEdgeVertexBufferKey); - fVertexBuffer = rp->findOrMakeStaticBuffer(kVertex_GrBufferType, - sizeof(kHull4AndEdgeVertices), - kHull4AndEdgeVertices, - gHull4AndEdgeVertexBufferKey); - GR_DEFINE_STATIC_UNIQUE_KEY(gHull4AndEdgeIndexBufferKey); - if (caps.usePrimitiveRestart()) { - fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, - sizeof(kHull4AndEdgeIndicesAsStrips), - kHull4AndEdgeIndicesAsStrips, - gHull4AndEdgeIndexBufferKey); - fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull4AndEdgeIndicesAsStrips); - } else { - fIndexBuffer = rp->findOrMakeStaticBuffer(kIndex_GrBufferType, - sizeof(kHull4AndEdgeIndicesAsTris), - kHull4AndEdgeIndicesAsTris, - gHull4AndEdgeIndexBufferKey); - fNumIndicesPerInstance = SK_ARRAY_COUNT(kHull4AndEdgeIndicesAsTris); + if (RenderPass::kTriangleCorners != fRenderPass) { + fNumIndicesPerInstance = fNumIndicesPerInstance * 2/3; } break; } } - if (RenderPass::kCubics == fRenderPass || WindMethod::kInstanceData == fWindMethod) { + if (RenderPassIsCubic(fRenderPass) || WindMethod::kInstanceData == fWindMethod) { SkASSERT(WindMethod::kCrossProduct == fWindMethod || 3 == this->numInputPoints()); SkASSERT(kAttribIdx_X == this->numAttribs()); @@ -534,11 +525,13 @@ GrGLSLPrimitiveProcessor* GrCCCoverageProcessor::createVSImpl(std::unique_ptr<Sh switch (fRenderPass) { case RenderPass::kTriangles: return new VSHullAndEdgeImpl(std::move(shadr), 3); - case RenderPass::kTriangleCorners: - return new VSCornerImpl(std::move(shadr)); case RenderPass::kQuadratics: case RenderPass::kCubics: return new VSHullAndEdgeImpl(std::move(shadr), 4); + case RenderPass::kTriangleCorners: + case RenderPass::kQuadraticCorners: + case RenderPass::kCubicCorners: + return new VSCornerImpl(std::move(shadr)); } SK_ABORT("Invalid RenderPass"); return nullptr; |