diff options
Diffstat (limited to 'src/gpu/ccpr/GrCCCoverageProcessor.h')
-rw-r--r-- | src/gpu/ccpr/GrCCCoverageProcessor.h | 130 |
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"; } |