1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_Renderer_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_Renderer_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSpan.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/GraphiteTypes.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkEnumBitMask.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkVx.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Attribute.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/DrawTypes.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceTypes.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Uniform.h"
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker #include <array>
23*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
24*c8dee2aaSAndroid Build Coastguard Worker #include <string>
25*c8dee2aaSAndroid Build Coastguard Worker #include <string_view>
26*c8dee2aaSAndroid Build Coastguard Worker #include <vector>
27*c8dee2aaSAndroid Build Coastguard Worker
28*c8dee2aaSAndroid Build Coastguard Worker enum class SkPathFillType;
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu { enum class MaskFormat; }
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker class DrawWriter;
35*c8dee2aaSAndroid Build Coastguard Worker class DrawParams;
36*c8dee2aaSAndroid Build Coastguard Worker class PipelineDataGatherer;
37*c8dee2aaSAndroid Build Coastguard Worker class Rect;
38*c8dee2aaSAndroid Build Coastguard Worker class ResourceProvider;
39*c8dee2aaSAndroid Build Coastguard Worker class TextureDataBlock;
40*c8dee2aaSAndroid Build Coastguard Worker class Transform;
41*c8dee2aaSAndroid Build Coastguard Worker
42*c8dee2aaSAndroid Build Coastguard Worker struct ResourceBindingRequirements;
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker enum class Coverage { kNone, kSingleChannel, kLCD };
45*c8dee2aaSAndroid Build Coastguard Worker
46*c8dee2aaSAndroid Build Coastguard Worker /**
47*c8dee2aaSAndroid Build Coastguard Worker * The actual technique for rasterizing a high-level draw recorded in a DrawList is handled by a
48*c8dee2aaSAndroid Build Coastguard Worker * specific Renderer. Each technique has an associated singleton Renderer that decomposes the
49*c8dee2aaSAndroid Build Coastguard Worker * technique into a series of RenderSteps that must be executed in the specified order for the draw.
50*c8dee2aaSAndroid Build Coastguard Worker * However, the RenderStep executions for multiple draws can be re-arranged so batches of each
51*c8dee2aaSAndroid Build Coastguard Worker * step can be performed in a larger GPU operation. This re-arranging relies on accurate
52*c8dee2aaSAndroid Build Coastguard Worker * determination of the DisjointStencilIndex for each draw so that stencil steps are not corrupted
53*c8dee2aaSAndroid Build Coastguard Worker * by another draw before its cover step is executed. It also relies on the CompressedPaintersOrder
54*c8dee2aaSAndroid Build Coastguard Worker * for each draw to ensure steps are not re-arranged in a way that violates the original draw order.
55*c8dee2aaSAndroid Build Coastguard Worker *
56*c8dee2aaSAndroid Build Coastguard Worker * Renderer itself is non-virtual since it simply has to point to a list of RenderSteps. RenderSteps
57*c8dee2aaSAndroid Build Coastguard Worker * on the other hand are virtual implement the technique specific functionality. It is entirely
58*c8dee2aaSAndroid Build Coastguard Worker * possible for certain types of steps, e.g. a bounding box cover, to be re-used across different
59*c8dee2aaSAndroid Build Coastguard Worker * Renderers even if the preceeding steps were different.
60*c8dee2aaSAndroid Build Coastguard Worker *
61*c8dee2aaSAndroid Build Coastguard Worker * All Renderers are accessed through the SharedContext's RendererProvider.
62*c8dee2aaSAndroid Build Coastguard Worker */
63*c8dee2aaSAndroid Build Coastguard Worker class RenderStep {
64*c8dee2aaSAndroid Build Coastguard Worker public:
65*c8dee2aaSAndroid Build Coastguard Worker virtual ~RenderStep() = default;
66*c8dee2aaSAndroid Build Coastguard Worker
67*c8dee2aaSAndroid Build Coastguard Worker // The DrawWriter is configured with the vertex and instance strides of the RenderStep, and its
68*c8dee2aaSAndroid Build Coastguard Worker // primitive type. The recorded draws will be executed with a graphics pipeline compatible with
69*c8dee2aaSAndroid Build Coastguard Worker // this RenderStep.
70*c8dee2aaSAndroid Build Coastguard Worker virtual void writeVertices(DrawWriter*, const DrawParams&, skvx::uint2 ssboIndices) const = 0;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker // Write out the uniform values (aligned for the layout), textures, and samplers. The uniform
73*c8dee2aaSAndroid Build Coastguard Worker // values will be de-duplicated across all draws using the RenderStep before uploading to the
74*c8dee2aaSAndroid Build Coastguard Worker // GPU, but it can be assumed the uniforms will be bound before the draws recorded in
75*c8dee2aaSAndroid Build Coastguard Worker // 'writeVertices' are executed.
76*c8dee2aaSAndroid Build Coastguard Worker virtual void writeUniformsAndTextures(const DrawParams&, PipelineDataGatherer*) const = 0;
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker // Returns the body of a vertex function, which must define a float4 devPosition variable and
79*c8dee2aaSAndroid Build Coastguard Worker // must write to an already-defined float2 stepLocalCoords variable. This will be automatically
80*c8dee2aaSAndroid Build Coastguard Worker // set to a varying for the fragment shader if the paint requires local coords. This SkSL has
81*c8dee2aaSAndroid Build Coastguard Worker // access to the variables declared by vertexAttributes(), instanceAttributes(), and uniforms().
82*c8dee2aaSAndroid Build Coastguard Worker // The 'devPosition' variable's z must store the PaintDepth normalized to a float from [0, 1],
83*c8dee2aaSAndroid Build Coastguard Worker // for each processed draw although the RenderStep can choose to upload it in any manner.
84*c8dee2aaSAndroid Build Coastguard Worker //
85*c8dee2aaSAndroid Build Coastguard Worker // NOTE: The above contract is mainly so that the entire SkSL program can be created by just str
86*c8dee2aaSAndroid Build Coastguard Worker // concatenating struct definitions generated from the RenderStep and paint Combination
87*c8dee2aaSAndroid Build Coastguard Worker // and then including the function bodies returned here.
88*c8dee2aaSAndroid Build Coastguard Worker virtual std::string vertexSkSL() const = 0;
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker // Emits code to set up textures and samplers. Should only be defined if hasTextures is true.
texturesAndSamplersSkSL(const ResourceBindingRequirements &,int * nextBindingIndex)91*c8dee2aaSAndroid Build Coastguard Worker virtual std::string texturesAndSamplersSkSL(const ResourceBindingRequirements&,
92*c8dee2aaSAndroid Build Coastguard Worker int* nextBindingIndex) const {
93*c8dee2aaSAndroid Build Coastguard Worker return R"()";
94*c8dee2aaSAndroid Build Coastguard Worker }
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker // Emits code to set up coverage value. Should only be defined if overridesCoverage is true.
97*c8dee2aaSAndroid Build Coastguard Worker // When implemented the returned SkSL fragment should write its coverage into a
98*c8dee2aaSAndroid Build Coastguard Worker // 'half4 outputCoverage' variable (defined in the calling code) with the actual
99*c8dee2aaSAndroid Build Coastguard Worker // coverage splatted out into all four channels.
fragmentCoverageSkSL()100*c8dee2aaSAndroid Build Coastguard Worker virtual const char* fragmentCoverageSkSL() const { return R"()"; }
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker // Emits code to set up a primitive color value. Should only be defined if emitsPrimitiveColor
103*c8dee2aaSAndroid Build Coastguard Worker // is true. When implemented, the returned SkSL fragment should write its color into a
104*c8dee2aaSAndroid Build Coastguard Worker // 'half4 primitiveColor' variable (defined in the calling code).
fragmentColorSkSL()105*c8dee2aaSAndroid Build Coastguard Worker virtual const char* fragmentColorSkSL() const { return R"()"; }
106*c8dee2aaSAndroid Build Coastguard Worker
uniqueID()107*c8dee2aaSAndroid Build Coastguard Worker uint32_t uniqueID() const { return fUniqueID; }
108*c8dee2aaSAndroid Build Coastguard Worker
109*c8dee2aaSAndroid Build Coastguard Worker // Returns a name formatted as "Subclass[variant]", where "Subclass" matches the C++ class name
110*c8dee2aaSAndroid Build Coastguard Worker // and variant is a unique term describing instance's specific configuration.
name()111*c8dee2aaSAndroid Build Coastguard Worker const char* name() const { return fName.c_str(); }
112*c8dee2aaSAndroid Build Coastguard Worker
requiresMSAA()113*c8dee2aaSAndroid Build Coastguard Worker bool requiresMSAA() const { return SkToBool(fFlags & Flags::kRequiresMSAA); }
performsShading()114*c8dee2aaSAndroid Build Coastguard Worker bool performsShading() const { return SkToBool(fFlags & Flags::kPerformsShading); }
hasTextures()115*c8dee2aaSAndroid Build Coastguard Worker bool hasTextures() const { return SkToBool(fFlags & Flags::kHasTextures); }
emitsPrimitiveColor()116*c8dee2aaSAndroid Build Coastguard Worker bool emitsPrimitiveColor() const { return SkToBool(fFlags & Flags::kEmitsPrimitiveColor); }
outsetBoundsForAA()117*c8dee2aaSAndroid Build Coastguard Worker bool outsetBoundsForAA() const { return SkToBool(fFlags & Flags::kOutsetBoundsForAA); }
useNonAAInnerFill()118*c8dee2aaSAndroid Build Coastguard Worker bool useNonAAInnerFill() const { return SkToBool(fFlags & Flags::kUseNonAAInnerFill); }
119*c8dee2aaSAndroid Build Coastguard Worker
coverage()120*c8dee2aaSAndroid Build Coastguard Worker Coverage coverage() const { return RenderStep::GetCoverage(fFlags); }
121*c8dee2aaSAndroid Build Coastguard Worker
primitiveType()122*c8dee2aaSAndroid Build Coastguard Worker PrimitiveType primitiveType() const { return fPrimitiveType; }
vertexStride()123*c8dee2aaSAndroid Build Coastguard Worker size_t vertexStride() const { return fVertexStride; }
instanceStride()124*c8dee2aaSAndroid Build Coastguard Worker size_t instanceStride() const { return fInstanceStride; }
125*c8dee2aaSAndroid Build Coastguard Worker
numUniforms()126*c8dee2aaSAndroid Build Coastguard Worker size_t numUniforms() const { return fUniforms.size(); }
numVertexAttributes()127*c8dee2aaSAndroid Build Coastguard Worker size_t numVertexAttributes() const { return fVertexAttrs.size(); }
numInstanceAttributes()128*c8dee2aaSAndroid Build Coastguard Worker size_t numInstanceAttributes() const { return fInstanceAttrs.size(); }
129*c8dee2aaSAndroid Build Coastguard Worker
130*c8dee2aaSAndroid Build Coastguard Worker // Name of an attribute containing both render step and shading SSBO indices, if used.
ssboIndicesAttribute()131*c8dee2aaSAndroid Build Coastguard Worker static const char* ssboIndicesAttribute() { return "ssboIndices"; }
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker // Name of a varying to pass SSBO indices to fragment shader. Both render step and shading
134*c8dee2aaSAndroid Build Coastguard Worker // indices are passed, because render step uniforms are sometimes used for coverage.
ssboIndicesVarying()135*c8dee2aaSAndroid Build Coastguard Worker static const char* ssboIndicesVarying() { return "ssboIndicesVar"; }
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker // The uniforms of a RenderStep are bound to the kRenderStep slot, the rest of the pipeline
138*c8dee2aaSAndroid Build Coastguard Worker // may still use uniforms bound to other slots.
uniforms()139*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Uniform> uniforms() const { return SkSpan(fUniforms); }
vertexAttributes()140*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Attribute> vertexAttributes() const { return SkSpan(fVertexAttrs); }
instanceAttributes()141*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Attribute> instanceAttributes() const { return SkSpan(fInstanceAttrs); }
varyings()142*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Varying> varyings() const { return SkSpan(fVaryings); }
143*c8dee2aaSAndroid Build Coastguard Worker
depthStencilSettings()144*c8dee2aaSAndroid Build Coastguard Worker const DepthStencilSettings& depthStencilSettings() const { return fDepthStencilSettings; }
145*c8dee2aaSAndroid Build Coastguard Worker
depthStencilFlags()146*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<DepthStencilFlags> depthStencilFlags() const {
147*c8dee2aaSAndroid Build Coastguard Worker return (fDepthStencilSettings.fStencilTestEnabled
148*c8dee2aaSAndroid Build Coastguard Worker ? DepthStencilFlags::kStencil : DepthStencilFlags::kNone) |
149*c8dee2aaSAndroid Build Coastguard Worker (fDepthStencilSettings.fDepthTestEnabled || fDepthStencilSettings.fDepthWriteEnabled
150*c8dee2aaSAndroid Build Coastguard Worker ? DepthStencilFlags::kDepth : DepthStencilFlags::kNone);
151*c8dee2aaSAndroid Build Coastguard Worker }
152*c8dee2aaSAndroid Build Coastguard Worker
153*c8dee2aaSAndroid Build Coastguard Worker // TODO: Actual API to do things
154*c8dee2aaSAndroid Build Coastguard Worker // 6. Some Renderers benefit from being able to share vertices between RenderSteps. Must find a
155*c8dee2aaSAndroid Build Coastguard Worker // way to support that. It may mean that RenderSteps get state per draw.
156*c8dee2aaSAndroid Build Coastguard Worker // - Does Renderer make RenderStepFactories that create steps for each DrawList::Draw?
157*c8dee2aaSAndroid Build Coastguard Worker // - Does DrawList->DrawPass conversion build a separate array of blind data that the
158*c8dee2aaSAndroid Build Coastguard Worker // stateless Renderstep can refer to for {draw,step} pairs?
159*c8dee2aaSAndroid Build Coastguard Worker // - Does each DrawList::Draw have extra space (e.g. 8 bytes) that steps can cache data in?
160*c8dee2aaSAndroid Build Coastguard Worker protected:
161*c8dee2aaSAndroid Build Coastguard Worker enum class Flags : unsigned {
162*c8dee2aaSAndroid Build Coastguard Worker kNone = 0b00000000,
163*c8dee2aaSAndroid Build Coastguard Worker kRequiresMSAA = 0b00000001,
164*c8dee2aaSAndroid Build Coastguard Worker kPerformsShading = 0b00000010,
165*c8dee2aaSAndroid Build Coastguard Worker kHasTextures = 0b00000100,
166*c8dee2aaSAndroid Build Coastguard Worker kEmitsCoverage = 0b00001000,
167*c8dee2aaSAndroid Build Coastguard Worker kLCDCoverage = 0b00010000,
168*c8dee2aaSAndroid Build Coastguard Worker kEmitsPrimitiveColor = 0b00100000,
169*c8dee2aaSAndroid Build Coastguard Worker kOutsetBoundsForAA = 0b01000000,
170*c8dee2aaSAndroid Build Coastguard Worker kUseNonAAInnerFill = 0b10000000,
171*c8dee2aaSAndroid Build Coastguard Worker };
172*c8dee2aaSAndroid Build Coastguard Worker SK_DECL_BITMASK_OPS_FRIENDS(Flags)
173*c8dee2aaSAndroid Build Coastguard Worker
174*c8dee2aaSAndroid Build Coastguard Worker // While RenderStep does not define the full program that's run for a draw, it defines the
175*c8dee2aaSAndroid Build Coastguard Worker // entire vertex layout of the pipeline. This is not allowed to change, so can be provided to
176*c8dee2aaSAndroid Build Coastguard Worker // the RenderStep constructor by subclasses.
177*c8dee2aaSAndroid Build Coastguard Worker RenderStep(std::string_view className,
178*c8dee2aaSAndroid Build Coastguard Worker std::string_view variantName,
179*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<Flags> flags,
180*c8dee2aaSAndroid Build Coastguard Worker std::initializer_list<Uniform> uniforms,
181*c8dee2aaSAndroid Build Coastguard Worker PrimitiveType primitiveType,
182*c8dee2aaSAndroid Build Coastguard Worker DepthStencilSettings depthStencilSettings,
183*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Attribute> vertexAttrs,
184*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Attribute> instanceAttrs,
185*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const Varying> varyings = {});
186*c8dee2aaSAndroid Build Coastguard Worker
187*c8dee2aaSAndroid Build Coastguard Worker private:
188*c8dee2aaSAndroid Build Coastguard Worker friend class Renderer; // for Flags
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker // Cannot copy or move
191*c8dee2aaSAndroid Build Coastguard Worker RenderStep(const RenderStep&) = delete;
192*c8dee2aaSAndroid Build Coastguard Worker RenderStep(RenderStep&&) = delete;
193*c8dee2aaSAndroid Build Coastguard Worker
194*c8dee2aaSAndroid Build Coastguard Worker static Coverage GetCoverage(SkEnumBitMask<Flags>);
195*c8dee2aaSAndroid Build Coastguard Worker
196*c8dee2aaSAndroid Build Coastguard Worker uint32_t fUniqueID;
197*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<Flags> fFlags;
198*c8dee2aaSAndroid Build Coastguard Worker PrimitiveType fPrimitiveType;
199*c8dee2aaSAndroid Build Coastguard Worker
200*c8dee2aaSAndroid Build Coastguard Worker DepthStencilSettings fDepthStencilSettings;
201*c8dee2aaSAndroid Build Coastguard Worker
202*c8dee2aaSAndroid Build Coastguard Worker // TODO: When we always use C++17 for builds, we should be able to just let subclasses declare
203*c8dee2aaSAndroid Build Coastguard Worker // constexpr arrays and point to those, but we need explicit storage for C++14.
204*c8dee2aaSAndroid Build Coastguard Worker // Alternatively, if we imposed a max attr count, similar to Renderer's num render steps, we
205*c8dee2aaSAndroid Build Coastguard Worker // could just have this be std::array and keep all attributes inline with the RenderStep memory.
206*c8dee2aaSAndroid Build Coastguard Worker // On the other hand, the attributes are only needed when creating a new pipeline so it's not
207*c8dee2aaSAndroid Build Coastguard Worker // that performance sensitive.
208*c8dee2aaSAndroid Build Coastguard Worker std::vector<Uniform> fUniforms;
209*c8dee2aaSAndroid Build Coastguard Worker std::vector<Attribute> fVertexAttrs;
210*c8dee2aaSAndroid Build Coastguard Worker std::vector<Attribute> fInstanceAttrs;
211*c8dee2aaSAndroid Build Coastguard Worker std::vector<Varying> fVaryings;
212*c8dee2aaSAndroid Build Coastguard Worker
213*c8dee2aaSAndroid Build Coastguard Worker size_t fVertexStride; // derived from vertex attribute set
214*c8dee2aaSAndroid Build Coastguard Worker size_t fInstanceStride; // derived from instance attribute set
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker std::string fName;
217*c8dee2aaSAndroid Build Coastguard Worker };
SK_MAKE_BITMASK_OPS(RenderStep::Flags)218*c8dee2aaSAndroid Build Coastguard Worker SK_MAKE_BITMASK_OPS(RenderStep::Flags)
219*c8dee2aaSAndroid Build Coastguard Worker
220*c8dee2aaSAndroid Build Coastguard Worker class Renderer {
221*c8dee2aaSAndroid Build Coastguard Worker using StepFlags = RenderStep::Flags;
222*c8dee2aaSAndroid Build Coastguard Worker public:
223*c8dee2aaSAndroid Build Coastguard Worker // The maximum number of render steps that any Renderer is allowed to have.
224*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kMaxRenderSteps = 4;
225*c8dee2aaSAndroid Build Coastguard Worker
226*c8dee2aaSAndroid Build Coastguard Worker const RenderStep& step(int i) const {
227*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(i >= 0 && i < fStepCount);
228*c8dee2aaSAndroid Build Coastguard Worker return *fSteps[i];
229*c8dee2aaSAndroid Build Coastguard Worker }
230*c8dee2aaSAndroid Build Coastguard Worker SkSpan<const RenderStep* const> steps() const {
231*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fStepCount > 0); // steps() should only be called on valid Renderers.
232*c8dee2aaSAndroid Build Coastguard Worker return {fSteps.data(), static_cast<size_t>(fStepCount) };
233*c8dee2aaSAndroid Build Coastguard Worker }
234*c8dee2aaSAndroid Build Coastguard Worker
235*c8dee2aaSAndroid Build Coastguard Worker const char* name() const { return fName.c_str(); }
236*c8dee2aaSAndroid Build Coastguard Worker DrawTypeFlags drawTypes() const { return fDrawTypes; }
237*c8dee2aaSAndroid Build Coastguard Worker int numRenderSteps() const { return fStepCount; }
238*c8dee2aaSAndroid Build Coastguard Worker
239*c8dee2aaSAndroid Build Coastguard Worker bool requiresMSAA() const {
240*c8dee2aaSAndroid Build Coastguard Worker return SkToBool(fStepFlags & StepFlags::kRequiresMSAA);
241*c8dee2aaSAndroid Build Coastguard Worker }
242*c8dee2aaSAndroid Build Coastguard Worker bool emitsPrimitiveColor() const {
243*c8dee2aaSAndroid Build Coastguard Worker return SkToBool(fStepFlags & StepFlags::kEmitsPrimitiveColor);
244*c8dee2aaSAndroid Build Coastguard Worker }
245*c8dee2aaSAndroid Build Coastguard Worker bool outsetBoundsForAA() const {
246*c8dee2aaSAndroid Build Coastguard Worker return SkToBool(fStepFlags & StepFlags::kOutsetBoundsForAA);
247*c8dee2aaSAndroid Build Coastguard Worker }
248*c8dee2aaSAndroid Build Coastguard Worker bool useNonAAInnerFill() const {
249*c8dee2aaSAndroid Build Coastguard Worker return SkToBool(fStepFlags & StepFlags::kUseNonAAInnerFill);
250*c8dee2aaSAndroid Build Coastguard Worker }
251*c8dee2aaSAndroid Build Coastguard Worker
252*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<DepthStencilFlags> depthStencilFlags() const { return fDepthStencilFlags; }
253*c8dee2aaSAndroid Build Coastguard Worker
254*c8dee2aaSAndroid Build Coastguard Worker Coverage coverage() const { return RenderStep::GetCoverage(fStepFlags); }
255*c8dee2aaSAndroid Build Coastguard Worker
256*c8dee2aaSAndroid Build Coastguard Worker private:
257*c8dee2aaSAndroid Build Coastguard Worker friend class RendererProvider; // for ctors
258*c8dee2aaSAndroid Build Coastguard Worker
259*c8dee2aaSAndroid Build Coastguard Worker // Max render steps is 4, so just spell the options out for now...
260*c8dee2aaSAndroid Build Coastguard Worker Renderer(std::string_view name, DrawTypeFlags drawTypes, const RenderStep* s1)
261*c8dee2aaSAndroid Build Coastguard Worker : Renderer(name, drawTypes, std::array<const RenderStep*, 1>{s1}) {}
262*c8dee2aaSAndroid Build Coastguard Worker
263*c8dee2aaSAndroid Build Coastguard Worker Renderer(std::string_view name, DrawTypeFlags drawTypes,
264*c8dee2aaSAndroid Build Coastguard Worker const RenderStep* s1, const RenderStep* s2)
265*c8dee2aaSAndroid Build Coastguard Worker : Renderer(name, drawTypes, std::array<const RenderStep*, 2>{s1, s2}) {}
266*c8dee2aaSAndroid Build Coastguard Worker
267*c8dee2aaSAndroid Build Coastguard Worker Renderer(std::string_view name, DrawTypeFlags drawTypes,
268*c8dee2aaSAndroid Build Coastguard Worker const RenderStep* s1, const RenderStep* s2, const RenderStep* s3)
269*c8dee2aaSAndroid Build Coastguard Worker : Renderer(name, drawTypes, std::array<const RenderStep*, 3>{s1, s2, s3}) {}
270*c8dee2aaSAndroid Build Coastguard Worker
271*c8dee2aaSAndroid Build Coastguard Worker Renderer(std::string_view name, DrawTypeFlags drawTypes,
272*c8dee2aaSAndroid Build Coastguard Worker const RenderStep* s1, const RenderStep* s2, const RenderStep* s3, const RenderStep* s4)
273*c8dee2aaSAndroid Build Coastguard Worker : Renderer(name, drawTypes, std::array<const RenderStep*, 4>{s1, s2, s3, s4}) {}
274*c8dee2aaSAndroid Build Coastguard Worker
275*c8dee2aaSAndroid Build Coastguard Worker template<size_t N>
276*c8dee2aaSAndroid Build Coastguard Worker Renderer(std::string_view name, DrawTypeFlags drawTypes, std::array<const RenderStep*, N> steps)
277*c8dee2aaSAndroid Build Coastguard Worker : fName(name)
278*c8dee2aaSAndroid Build Coastguard Worker , fDrawTypes(drawTypes)
279*c8dee2aaSAndroid Build Coastguard Worker , fStepCount(SkTo<int>(N)) {
280*c8dee2aaSAndroid Build Coastguard Worker static_assert(N <= kMaxRenderSteps);
281*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0 ; i < fStepCount; ++i) {
282*c8dee2aaSAndroid Build Coastguard Worker fSteps[i] = steps[i];
283*c8dee2aaSAndroid Build Coastguard Worker fStepFlags |= fSteps[i]->fFlags;
284*c8dee2aaSAndroid Build Coastguard Worker fDepthStencilFlags |= fSteps[i]->depthStencilFlags();
285*c8dee2aaSAndroid Build Coastguard Worker }
286*c8dee2aaSAndroid Build Coastguard Worker // At least one step needs to actually shade.
287*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fStepFlags & RenderStep::Flags::kPerformsShading);
288*c8dee2aaSAndroid Build Coastguard Worker // A render step using non-AA inner fills with a second draw should not also be part of a
289*c8dee2aaSAndroid Build Coastguard Worker // multi-step renderer (to keep reasoning simple) and must use the GREATER depth test.
290*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->useNonAAInnerFill() ||
291*c8dee2aaSAndroid Build Coastguard Worker (fStepCount == 1 && fSteps[0]->depthStencilSettings().fDepthTestEnabled &&
292*c8dee2aaSAndroid Build Coastguard Worker fSteps[0]->depthStencilSettings().fDepthCompareOp == CompareOp::kGreater));
293*c8dee2aaSAndroid Build Coastguard Worker }
294*c8dee2aaSAndroid Build Coastguard Worker
295*c8dee2aaSAndroid Build Coastguard Worker // For RendererProvider to manage initialization; it will never expose a Renderer that is only
296*c8dee2aaSAndroid Build Coastguard Worker // default-initialized and not replaced because it's algorithm is disabled by caps/options.
297*c8dee2aaSAndroid Build Coastguard Worker Renderer() : fSteps(), fName(""), fStepCount(0) {}
298*c8dee2aaSAndroid Build Coastguard Worker Renderer& operator=(Renderer&&) = default;
299*c8dee2aaSAndroid Build Coastguard Worker
300*c8dee2aaSAndroid Build Coastguard Worker std::array<const RenderStep*, kMaxRenderSteps> fSteps;
301*c8dee2aaSAndroid Build Coastguard Worker std::string fName;
302*c8dee2aaSAndroid Build Coastguard Worker DrawTypeFlags fDrawTypes = DrawTypeFlags::kNone;
303*c8dee2aaSAndroid Build Coastguard Worker int fStepCount;
304*c8dee2aaSAndroid Build Coastguard Worker
305*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<StepFlags> fStepFlags = StepFlags::kNone;
306*c8dee2aaSAndroid Build Coastguard Worker SkEnumBitMask<DepthStencilFlags> fDepthStencilFlags = DepthStencilFlags::kNone;
307*c8dee2aaSAndroid Build Coastguard Worker };
308*c8dee2aaSAndroid Build Coastguard Worker
309*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
310*c8dee2aaSAndroid Build Coastguard Worker
311*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_Renderer_DEFINED
312