aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCCoverageProcessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor.h')
-rw-r--r--src/gpu/ccpr/GrCCCoverageProcessor.h130
1 files changed, 79 insertions, 51 deletions
diff --git a/src/gpu/ccpr/GrCCCoverageProcessor.h b/src/gpu/ccpr/GrCCCoverageProcessor.h
index 7db424e219..a8ad18ce55 100644
--- a/src/gpu/ccpr/GrCCCoverageProcessor.h
+++ b/src/gpu/ccpr/GrCCCoverageProcessor.h
@@ -10,6 +10,7 @@
#include "GrCaps.h"
#include "GrGeometryProcessor.h"
+#include "GrPipeline.h"
#include "GrShaderCaps.h"
#include "SkNx.h"
#include "glsl/GrGLSLGeometryProcessor.h"
@@ -18,6 +19,7 @@
class GrGLSLFPFragmentBuilder;
class GrGLSLVertexGeoBuilder;
class GrMesh;
+class GrOpFlushState;
/**
* This is the geometry processor for the simple convex primitive shapes (triangles and closed,
@@ -54,11 +56,9 @@ public:
void set(const SkPoint&, const SkPoint&, const SkPoint&, const Sk2f& trans, float w);
};
// Here we enumerate every render pass needed in order to produce a complete coverage count
- // mask. Triangles require two render passes: One to draw a rough outline, and a second pass to
- // touch up the corners. This is an exhaustive list of all ccpr coverage shaders.
+ // mask. This is an exhaustive list of all ccpr coverage shaders.
enum class RenderPass {
kTriangles,
- kTriangleCorners,
kQuadratics,
kCubics,
};
@@ -83,18 +83,6 @@ public:
}
}
- // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array
- // of either TriPointInstance or QuadPointInstance, depending on this processor's RendererPass,
- // with coordinates in the desired shape's final atlas-space position.
- void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
- SkTArray<GrMesh>* out) {
- if (Impl::kGeometryShader == fImpl) {
- this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out);
- } else {
- this->appendVSMesh(instanceBuffer, instanceCount, baseInstance, out);
- }
- }
-
// GrPrimitiveProcessor overrides.
const char* name() const override { return RenderPassName(fRenderPass); }
SkString dumpInfo() const override {
@@ -111,39 +99,39 @@ public:
float debugBloat() const { SkASSERT(this->debugVisualizationsEnabled()); return fDebugBloat; }
#endif
- // The Shader provides code to calculate each pixel's coverage in a RenderPass. It also
- // provides details about shape-specific geometry.
- class Shader {
- public:
- union GeometryVars {
- struct {
- const char* fAlternatePoints; // floatNx2 (if left null, will use input points).
- } fHullVars;
-
- struct {
- const char* fPoint; // float2
- } fCornerVars;
+ // Appends a GrMesh that will draw the provided instances. The instanceBuffer must be an array
+ // of either TriPointInstance or QuadPointInstance, depending on this processor's RendererPass,
+ // with coordinates in the desired shape's final atlas-space position.
+ void appendMesh(GrBuffer* instanceBuffer, int instanceCount, int baseInstance,
+ SkTArray<GrMesh>* out) const {
+ if (Impl::kGeometryShader == fImpl) {
+ this->appendGSMesh(instanceBuffer, instanceCount, baseInstance, out);
+ } else {
+ this->appendVSMesh(instanceBuffer, instanceCount, baseInstance, out);
+ }
+ }
- GeometryVars() { memset(this, 0, sizeof(*this)); }
- };
+ void draw(GrOpFlushState*, const GrPipeline&, const GrMesh[], const GrPipeline::DynamicState[],
+ int meshCount, const SkRect& drawBounds) const;
- // 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).
+ // The Shader provides code to calculate a pixel's coverage.
+ class Shader {
+ public:
+ // Called before generating geometry. Subclasses may use this opportunity to setup internal
+ // member variables that will be needed during onEmitVaryings (e.g. transformation
+ // matrices).
//
- // 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* varyingHandler, GrGLSLVarying::Scope scope,
- SkString* code, const char* position, const char* inputCoverage,
- const char* wind) {
- SkASSERT(GrGLSLVarying::Scope::kVertToGeo != scope);
- this->onEmitVaryings(varyingHandler, scope, code, position, inputCoverage, wind);
+ // Returns the name of a newly defined list of points around which the Impl should generate
+ // its geometry, or null if it should just use the input points. (Regardless, the size of
+ // whatever list of points indicated should match the size expected by the Impl: 3 points
+ // for triangles, and 4 for quadratics and cubics.)
+ virtual const char* emitSetupCode(GrGLSLVertexGeoBuilder*, const char* pts) const {
+ return nullptr;
}
+ void emitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope, SkString* code,
+ const char* position, const char* coverage, const char* wind);
+
void emitFragmentCode(const GrCCCoverageProcessor&, GrGLSLFPFragmentBuilder*,
const char* skOutputColor, const char* skOutputCoverage) const;
@@ -157,20 +145,37 @@ public:
const char* rightPt, const char* rasterVertexDir,
const char* outputCoverage);
+ // Calculates an edge's coverage at two conservative raster vertices.
+ // (See CalcEdgeCoverageAtBloatVertex).
+ static void CalcEdgeCoveragesAtBloatVertices(GrGLSLVertexGeoBuilder*, const char* leftPt,
+ const char* rightPt, const char* bloatDir1,
+ const char* bloatDir2,
+ const char* outputCoverages);
+
virtual ~Shader() {}
protected:
+ enum class CoverageHandling : bool {
+ kHandled,
+ kNotHandled
+ };
+
// 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.
+ // initialize those varyings from a given position and coverage/wind.
//
- // 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;
+ // Returns whether the subclass will handle coverage modulation or if this base class should
+ // take charge of multiplying the final coverage output by 'coverageTimesWind'.
+ virtual CoverageHandling onEmitVaryings(GrGLSLVaryingHandler*, GrGLSLVarying::Scope,
+ SkString* code, const char* position,
+ const char* coverageTimesWind) {
+ return CoverageHandling::kNotHandled;
+ }
- // Emits the fragment code that calculates a pixel's signed coverage value.
+ // Emits the fragment code that calculates a pixel's coverage value. If using
+ // CoverageHandling::kHandled, this value must be signed and modulated appropriately by
+ // coverage.
virtual void onEmitFragmentCode(const GrCCCoverageProcessor&, GrGLSLFPFragmentBuilder*,
- const char* outputCoverage) const = 0;
+ const char* outputCoverage) const {}
// Returns the name of a Shader's internal varying at the point where where its value is
// assigned. This is intended to work whether called for a vertex or a geometry shader.
@@ -179,6 +184,9 @@ public:
SkASSERT(Scope::kVertToGeo != varying.scope());
return Scope::kGeoToFrag == varying.scope() ? varying.gsOut() : varying.vsOut();
}
+
+ private:
+ GrGLSLVarying fCoverageTimesWind;
};
class GSImpl;
@@ -197,6 +205,24 @@ private:
kVertexShader
};
+ // Geometry shader backend draws triangles in two subpasses.
+ enum class GSTriangleSubpass : bool {
+ kHullsAndEdges,
+ kCorners
+ };
+
+ GrCCCoverageProcessor(const GrCCCoverageProcessor& proc, GSTriangleSubpass subpass)
+ : INHERITED(kGrCCCoverageProcessor_ClassID)
+ , fRenderPass(RenderPass::kTriangles)
+ , fWindMethod(proc.fWindMethod)
+ , fImpl(Impl::kGeometryShader)
+ SkDEBUGCODE(, fDebugBloat(proc.fDebugBloat))
+ , fGSTriangleSubpass(subpass) {
+ SkASSERT(RenderPass::kTriangles == proc.fRenderPass);
+ SkASSERT(Impl::kGeometryShader == proc.fImpl);
+ this->initGS();
+ }
+
void initGS();
void initVS(GrResourceProvider*);
@@ -213,6 +239,9 @@ private:
const Impl fImpl;
SkDEBUGCODE(float fDebugBloat = 0);
+ // Used by GSImpl.
+ const GSTriangleSubpass fGSTriangleSubpass = GSTriangleSubpass::kHullsAndEdges;
+
// Used by VSImpl.
sk_sp<const GrBuffer> fVertexBuffer;
sk_sp<const GrBuffer> fIndexBuffer;
@@ -254,7 +283,6 @@ inline void GrCCCoverageProcessor::QuadPointInstance::set(const SkPoint& p0, con
inline const char* GrCCCoverageProcessor::RenderPassName(RenderPass pass) {
switch (pass) {
case RenderPass::kTriangles: return "kTriangles";
- case RenderPass::kTriangleCorners: return "kTriangleCorners";
case RenderPass::kQuadratics: return "kQuadratics";
case RenderPass::kCubics: return "kCubics";
}