aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-03-08 15:55:58 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-08 15:56:02 +0000
commitbaf3e78092243210ca4489e51134df6fc8a90eee (patch)
tree41d16430ad639f72787a148f04476ee079e9ad56 /src/gpu/ccpr/GrCCCoverageProcessor_VSImpl.cpp
parentfe462efbcb105914e4c4bbf689525b530a438773 (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.cpp199
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;