Line data Source code
1 : /*
2 : * Copyright 2015 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef GrMeshDrawOp_DEFINED
9 : #define GrMeshDrawOp_DEFINED
10 :
11 : #include "GrDrawOp.h"
12 : #include "GrGeometryProcessor.h"
13 : #include "GrMesh.h"
14 : #include "GrPendingProgramElement.h"
15 : #include "GrPipelineBuilder.h"
16 :
17 : #include "SkTLList.h"
18 :
19 : class GrCaps;
20 : class GrOpFlushState;
21 :
22 : /**
23 : * Base class for mesh-drawing GrDrawOps.
24 : */
25 0 : class GrMeshDrawOp : public GrDrawOp {
26 : public:
27 : class Target;
28 :
29 : protected:
30 : GrMeshDrawOp(uint32_t classID);
31 :
32 : /** Helper for rendering instances using an instanced index buffer. This class creates the space
33 : for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
34 0 : class InstancedHelper {
35 : public:
36 0 : InstancedHelper() {}
37 : /** Returns the allocated storage for the vertices. The caller should populate the vertices
38 : before calling recordDraws(). */
39 : void* init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
40 : int verticesPerInstance, int indicesPerInstance, int instancesToDraw);
41 :
42 : /** Call after init() to issue draws to the GrMeshDrawOp::Target.*/
43 : void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*);
44 :
45 : private:
46 : GrMesh fMesh;
47 : };
48 :
49 : static const int kVerticesPerQuad = 4;
50 : static const int kIndicesPerQuad = 6;
51 :
52 : /** A specialization of InstanceHelper for quad rendering. */
53 0 : class QuadHelper : private InstancedHelper {
54 : public:
55 0 : QuadHelper() : INHERITED() {}
56 : /** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure
57 : and on success a pointer to the vertex data that the caller should populate before
58 : calling recordDraws(). */
59 : void* init(Target*, size_t vertexStride, int quadsToDraw);
60 :
61 : using InstancedHelper::recordDraw;
62 :
63 : private:
64 : typedef InstancedHelper INHERITED;
65 : };
66 :
67 : private:
68 : void onPrepare(GrOpFlushState* state) final;
69 : void onExecute(GrOpFlushState* state) final;
70 :
71 : virtual void onPrepareDraws(Target*) const = 0;
72 :
73 : // A set of contiguous draws that share a draw token and primitive processor. The draws all use
74 : // the op's pipeline. The meshes for the draw are stored in the fMeshes array and each
75 : // Queued draw uses fMeshCnt meshes from the fMeshes array. The reason for coallescing meshes
76 : // that share a primitive processor into a QueuedDraw is that it allows the Gpu object to setup
77 : // the shared state once and then issue draws for each mesh.
78 0 : struct QueuedDraw {
79 : int fMeshCnt = 0;
80 : GrPendingProgramElement<const GrGeometryProcessor> fGeometryProcessor;
81 : const GrPipeline* fPipeline;
82 : };
83 :
84 : // All draws in all the GrMeshDrawOps have implicit tokens based on the order they are enqueued
85 : // globally across all ops. This is the offset of the first entry in fQueuedDraws.
86 : // fQueuedDraws[i]'s token is fBaseDrawToken + i.
87 : GrDrawOpUploadToken fBaseDrawToken;
88 : SkSTArray<4, GrMesh> fMeshes;
89 : SkSTArray<4, QueuedDraw, true> fQueuedDraws;
90 :
91 : typedef GrDrawOp INHERITED;
92 : };
93 :
94 : /**
95 : * Many of our ops derive from this class which initializes a GrPipeline just before being recorded.
96 : * We are migrating away from use of this class.
97 : */
98 0 : class GrLegacyMeshDrawOp : public GrMeshDrawOp {
99 : public:
100 : /**
101 : * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
102 : * initial color and coverage from this op's geometry processor.
103 : */
104 0 : GrProcessorSet::Analysis analyzeUpdateAndRecordProcessors(GrPipelineBuilder* pipelineBuilder,
105 : const GrAppliedClip* appliedClip,
106 : bool isMixedSamples,
107 : const GrCaps& caps,
108 : GrColor* overrideColor) const {
109 0 : GrProcessorAnalysisColor inputColor;
110 : GrProcessorAnalysisCoverage inputCoverage;
111 0 : this->getProcessorAnalysisInputs(&inputColor, &inputCoverage);
112 : return pipelineBuilder->finalizeProcessors(inputColor, inputCoverage, appliedClip,
113 0 : isMixedSamples, caps, overrideColor);
114 : }
115 :
116 0 : void initPipeline(const GrPipeline::InitArgs& args, const GrProcessorSet::Analysis& analysis,
117 : GrColor overrideColor) {
118 0 : fPipeline.init(args);
119 0 : this->applyPipelineOptimizations(PipelineOptimizations(analysis, overrideColor));
120 0 : }
121 :
122 : /**
123 : * Mesh draw ops use a legacy system in GrRenderTargetContext where the pipeline is created when
124 : * the op is recorded. These methods are unnecessary as this information is in the pipeline.
125 : */
126 0 : FixedFunctionFlags fixedFunctionFlags() const override {
127 0 : SkFAIL("This should never be called for legacy mesh draw ops.");
128 0 : return FixedFunctionFlags::kNone;
129 : }
130 0 : bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override {
131 0 : SkFAIL("Should never be called for legacy mesh draw ops.");
132 0 : return false;
133 : }
134 :
135 : protected:
136 0 : GrLegacyMeshDrawOp(uint32_t classID) : INHERITED(classID) {}
137 : /**
138 : * This is a legacy class only used by GrLegacyMeshDrawOp and will be removed. It presents some
139 : * aspects of GrProcessorSet::Analysis to GrLegacyMeshDrawOp subclasses.
140 : */
141 : class PipelineOptimizations {
142 : public:
143 0 : PipelineOptimizations(const GrProcessorSet::Analysis& analysis, GrColor overrideColor) {
144 0 : fFlags = 0;
145 0 : if (analysis.inputColorIsOverridden()) {
146 0 : fFlags |= kUseOverrideColor_Flag;
147 0 : fOverrideColor = overrideColor;
148 : }
149 0 : if (analysis.usesLocalCoords()) {
150 0 : fFlags |= kReadsLocalCoords_Flag;
151 : }
152 0 : if (analysis.isCompatibleWithCoverageAsAlpha()) {
153 0 : fFlags |= kCanTweakAlphaForCoverage_Flag;
154 : }
155 0 : }
156 :
157 : /** Does the pipeline require access to (implicit or explicit) local coordinates? */
158 0 : bool readsLocalCoords() const { return SkToBool(kReadsLocalCoords_Flag & fFlags); }
159 :
160 : /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
161 : color output ? */
162 0 : bool canTweakAlphaForCoverage() const {
163 0 : return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
164 : }
165 :
166 : /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
167 : so get the color)? */
168 0 : bool getOverrideColorIfSet(GrColor* overrideColor) const {
169 0 : if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
170 0 : if (overrideColor) {
171 0 : *overrideColor = fOverrideColor;
172 : }
173 0 : return true;
174 : }
175 0 : return false;
176 : }
177 :
178 : private:
179 : enum {
180 : // If this is not set the primitive processor need not produce local coordinates
181 : kReadsLocalCoords_Flag = 0x1,
182 : // If this flag is set then the primitive processor may produce color*coverage as
183 : // its color output (and not output a separate coverage).
184 : kCanTweakAlphaForCoverage_Flag = 0x2,
185 : // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
186 : // output color. If not set fOverrideColor is to be ignored.
187 : kUseOverrideColor_Flag = 0x4,
188 : };
189 :
190 : uint32_t fFlags;
191 : GrColor fOverrideColor;
192 : };
193 :
194 0 : const GrPipeline* pipeline() const {
195 0 : SkASSERT(fPipeline.isInitialized());
196 0 : return &fPipeline;
197 : }
198 :
199 : private:
200 : /**
201 : * Provides information about the GrPrimitiveProccesor color and coverage outputs which become
202 : * inputs to the first color and coverage fragment processors.
203 : */
204 : virtual void getProcessorAnalysisInputs(GrProcessorAnalysisColor*,
205 : GrProcessorAnalysisCoverage*) const = 0;
206 :
207 : /**
208 : * After processor analysis is complete this is called so that the op can use the analysis
209 : * results when constructing its GrPrimitiveProcessor.
210 : */
211 : virtual void applyPipelineOptimizations(const PipelineOptimizations&) = 0;
212 :
213 : GrPipeline fPipeline;
214 :
215 : typedef GrMeshDrawOp INHERITED;
216 : };
217 :
218 : #endif
|