aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCPRCoverageProcessor.h
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-12-12 12:48:47 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-13 14:29:42 +0000
commit1fbdb61f1389f01ce1cf1b7950e03a84811a9f38 (patch)
treef2e952f809e3987f9e568b3e7d50374364b43fea /src/gpu/ccpr/GrCCPRCoverageProcessor.h
parent250e6e880f26840b200c46396af8d50facf1f2ae (diff)
CCPR: Optimize Hull geometry
Conceptualizes hulls a as single entity, rather than a set of "wedges" fanned around the midpoint. Optimizes GSImpl hulls to use less, better triangles and not use the midpoint. This refactoring also paves the way for VSImpl hulls. Bug: skia: Change-Id: I6a03c7b64811edfd1589f11a5d102e6ee56ea2d2 Reviewed-on: https://skia-review.googlesource.com/83962 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/ccpr/GrCCPRCoverageProcessor.h')
-rw-r--r--src/gpu/ccpr/GrCCPRCoverageProcessor.h116
1 files changed, 50 insertions, 66 deletions
diff --git a/src/gpu/ccpr/GrCCPRCoverageProcessor.h b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
index dfd2e249c4..6bc3fadf29 100644
--- a/src/gpu/ccpr/GrCCPRCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCPRCoverageProcessor.h
@@ -14,13 +14,13 @@
#include "glsl/GrGLSLVarying.h"
class GrGLSLPPFragmentBuilder;
-class GrGLSLShaderBuilder;
+class GrGLSLVertexGeoBuilder;
class GrMesh;
/**
- * This is the geometry processor for the simple convex primitive shapes (triangles and closed curve
- * segments) from which ccpr paths are composed. The output is a single-channel alpha value,
- * positive for clockwise shapes and negative for counter-clockwise, that indicates coverage.
+ * This is the geometry processor for the simple convex primitive shapes (triangles and closed,
+ * convex bezier curves) from which ccpr paths are composed. The output is a single-channel alpha
+ * value, positive for clockwise shapes and negative for counter-clockwise, that indicates coverage.
*
* The caller is responsible to execute all render passes for all applicable primitives into a
* cleared, floating point, alpha-only render target using SkBlendMode::kPlus (see RenderPass
@@ -48,21 +48,36 @@ public:
void set(const SkPoint[4], float dx, float dy);
};
- // All primitive shapes (triangles and convex closed curve segments) require more than one
+ // 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
// coverage count mask. This is an exhaustive list of all ccpr coverage shaders.
+ //
+ // During a render pass, the "Impl" (currently only GSImpl) generates conservative geometry for
+ // rasterization, and the Shader decides the coverage value at each pixel.
enum class RenderPass {
- // Triangles.
+ // 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 +1 all
+ // around. 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 initial
+ // 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.
kTriangleEdges,
- kTriangleCorners,
- // Quadratics.
- kQuadraticHulls,
+ // 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. The initial coverage values sent to the Shader at each pixel are
+ // +1 all around.
+ kTriangleCorners,
kQuadraticCorners,
-
- // Cubics.
- kCubicHulls,
kCubicCorners
};
static bool RenderPassIsCubic(RenderPass);
@@ -100,46 +115,13 @@ public:
float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; }
#endif
- // This serves as the base class for each RenderPass's Shader. It indicates what type of
- // geometry the Impl should generate and provides implementation-independent code to process the
- // inputs and calculate coverage in the fragment Shader.
+ // The Shader provides code to calculate each pixel's coverage in a RenderPass. It also
+ // provides details about shape-specific geometry.
class Shader {
public:
- using TexelBufferHandle = GrGLSLGeometryProcessor::TexelBufferHandle;
-
- // This enum specifies the type of geometry that should be generated for a Shader instance.
- // Subclasses are limited to three built-in types of geometry to choose from:
- enum class GeometryType {
- // 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.
- // Coverage is +1 all around.
- //
- // Logically, the conservative raster hull is equivalent to the convex hull of pixel
- // size boxes centered around each input point.
- kHull,
-
- // Generates the conservative rasters of the input edges (i.e. convex hull of two
- // pixel-size boxes centered on both endpoints). Coverage is -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 points. It effectively converts a jagged conservative
- // raster edge into a smooth antialiased edge.
- kEdges,
-
- // Generates the conservative rasters of the corners specified by the geometry provider
- // (i.e. pixel-size box centered on the corner point). Coverage is +1 all around.
- kCorners
- };
-
- virtual GeometryType getGeometryType() const = 0;
-
- // Returns the number of independent geometric segments to generate for the render pass
- // (number of wedges for a hull, number of edges, or number of corners.)
- virtual int getNumSegments() const = 0;
-
union GeometryVars {
struct {
const char* fAlternatePoints; // floatNx2 (if left null, will use input points).
- const char* fAlternateMidpoint; // float2 (if left null, finds euclidean midpoint).
} fHullVars;
struct {
@@ -152,8 +134,12 @@ public:
// Called before generating geometry. Subclasses must fill out the applicable fields in
// GeometryVars (if any), and may also use this opportunity to setup internal member
// variables that will be needed during onEmitVaryings (e.g. transformation matrices).
- virtual void emitSetupCode(GrGLSLShaderBuilder*, const char* pts, const char* segmentId,
- const char* wind, GeometryVars*) const {}
+ //
+ // repetitionID is a 0-based index and indicates which edge or corner is being generated.
+ // It will be null when generating a hull.
+ virtual void emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts,
+ const char* repetitionID, const char* wind,
+ GeometryVars*) const {}
void emitVaryings(GrGLSLVaryingHandler*, SkString* code, const char* position,
const char* coverage, const char* wind);
@@ -164,16 +150,10 @@ public:
// Defines an equation ("dot(float3(pt, 1), distance_equation)") that is -1 on the outside
// border of a conservative raster edge and 0 on the inside. 'leftPt' and 'rightPt' must be
// ordered clockwise.
- static void EmitEdgeDistanceEquation(GrGLSLShaderBuilder*, const char* leftPt,
+ static void EmitEdgeDistanceEquation(GrGLSLVertexGeoBuilder*, const char* leftPt,
const char* rightPt,
const char* outputDistanceEquation);
- // Defines a global float2 array that contains MSAA sample locations as offsets from pixel
- // center. Subclasses can use this for software multisampling.
- //
- // Returns the number of samples.
- static int DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f, const char* samplesName);
-
virtual ~Shader() {}
protected:
@@ -188,7 +168,7 @@ public:
// 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 GeometryType).
+ // NOTE: the coverage parameter is only relevant for edges (see comments in RenderPass).
// Otherwise it is +1 all around.
virtual WindHandling onEmitVaryings(GrGLSLVaryingHandler*, SkString* code,
const char* position, const char* coverage,
@@ -199,6 +179,12 @@ public:
virtual void onEmitFragmentCode(GrGLSLPPFragmentBuilder*,
const char* outputCoverage) const = 0;
+ // Defines a global float2 array that contains MSAA sample locations as offsets from pixel
+ // center. Subclasses can use this for software multisampling.
+ //
+ // Returns the number of samples.
+ static int DefineSoftSampleLocations(GrGLSLPPFragmentBuilder* f, const char* samplesName);
+
private:
GrGLSLVarying fWind{kHalf_GrSLType, GrGLSLVarying::Scope::kGeoToFrag};
};
@@ -210,15 +196,13 @@ private:
// accidentally bleed into neighbor pixels.
static constexpr float kAABloatRadius = 0.491111f;
+ // Number of bezier points for curves, or 3 for triangles.
+ int numInputPoints() const { return RenderPassIsCubic(fRenderPass) ? 4 : 3; }
+
void initGS();
void appendGSMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
- SkTArray<GrMesh, true>* out);
-
- int numInputPoints() const {
- return RenderPassIsCubic(fRenderPass) ? 4 : 3;
- }
-
- static GrGLSLPrimitiveProcessor* CreateGSImpl(std::unique_ptr<Shader>);
+ SkTArray<GrMesh, true>* out) const;
+ GrGLSLPrimitiveProcessor* createGSImpl(std::unique_ptr<Shader>) const;
const RenderPass fRenderPass;
SkDEBUGCODE(float fDebugBloat = 0;)
@@ -257,7 +241,7 @@ inline bool GrCCPRCoverageProcessor::RenderPassIsCubic(RenderPass pass) {
case RenderPass::kCubicCorners:
return true;
}
- SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass");
+ SK_ABORT("Invalid RenderPass");
return false;
}
@@ -271,7 +255,7 @@ inline const char* GrCCPRCoverageProcessor::RenderPassName(RenderPass pass) {
case RenderPass::kCubicHulls: return "kCubicHulls";
case RenderPass::kCubicCorners: return "kCubicCorners";
}
- SK_ABORT("Invalid GrCCPRCoverageProcessor::RenderPass");
+ SK_ABORT("Invalid RenderPass");
return "";
}