blob: a8da29a39f9604a56ac8cef09886b05abc71c2be [file] [log] [blame]
bsalomon16b99132015-08-13 14:55:50 -07001/*
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
Brian Salomon53e4c3c2016-12-21 11:38:53 -05008#ifndef GrMeshDrawOp_DEFINED
9#define GrMeshDrawOp_DEFINED
bsalomon16b99132015-08-13 14:55:50 -070010
Brian Salomon9afd3712016-12-01 10:59:09 -050011#include "GrDrawOp.h"
bsalomon342bfc22016-04-01 06:06:20 -070012#include "GrGeometryProcessor.h"
egdaniel0e1853c2016-03-17 11:35:45 -070013#include "GrMesh.h"
bsalomon75398562015-08-17 12:55:38 -070014#include "GrPendingProgramElement.h"
bsalomon75398562015-08-17 12:55:38 -070015
16#include "SkTLList.h"
17
Brian Salomon54d212e2017-03-21 14:22:38 -040018class GrCaps;
Brian Salomon742e31d2016-12-07 17:06:19 -050019class GrOpFlushState;
bsalomon16b99132015-08-13 14:55:50 -070020
21/**
Brian Salomondad29232016-12-01 16:40:24 -050022 * Base class for mesh-drawing GrDrawOps.
bsalomon16b99132015-08-13 14:55:50 -070023 */
Brian Salomondad29232016-12-01 16:40:24 -050024class GrMeshDrawOp : public GrDrawOp {
bsalomon16b99132015-08-13 14:55:50 -070025public:
bsalomon75398562015-08-17 12:55:38 -070026 class Target;
27
Brian Salomon54d212e2017-03-21 14:22:38 -040028 /**
29 * Performs analysis of the fragment processors in GrProcessorSet and GrAppliedClip using the
30 * initial color and coverage from this op's geometry processor.
31 */
Brian Salomona811b122017-03-30 08:21:32 -040032 void analyzeProcessors(GrProcessorSet::Analysis* analysis,
Brian Salomon54d212e2017-03-21 14:22:38 -040033 const GrProcessorSet& processors,
34 const GrAppliedClip* appliedClip,
35 const GrCaps& caps) const {
Brian Salomona811b122017-03-30 08:21:32 -040036 GrProcessorAnalysisColor inputColor;
37 GrProcessorAnalysisCoverage inputCoverage;
38 this->getProcessorAnalysisInputs(&inputColor, &inputCoverage);
Brian Salomonc0b642c2017-03-27 13:09:36 -040039 analysis->init(inputColor, inputCoverage, processors, appliedClip, caps);
Brian Salomon54d212e2017-03-21 14:22:38 -040040 }
41
42 void initPipeline(const GrPipeline::InitArgs& args) {
Brian Salomone7d30482017-03-29 12:09:15 -040043 fPipeline.init(args);
44 this->applyPipelineOptimizations(PipelineOptimizations(*args.fAnalysis));
Brian Salomon54d212e2017-03-21 14:22:38 -040045 }
46
47 /**
48 * Mesh draw ops use a legacy system in GrRenderTargetContext where the pipeline is created when
49 * the op is recorded. These methods are unnecessary as this information is in the pipeline.
50 */
51 FixedFunctionFlags fixedFunctionFlags() const override {
52 SkFAIL("This should never be called for mesh draw ops.");
53 return FixedFunctionFlags::kNone;
54 }
55 bool xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*) override {
56 SkFAIL("Should never be called for mesh draw ops.");
57 return false;
58 }
Brian Salomon2bf4b3a2017-03-16 14:19:07 -040059
Brian Salomonc48af932017-03-16 19:51:42 +000060protected:
Brian Salomon54d212e2017-03-21 14:22:38 -040061 GrMeshDrawOp(uint32_t classID);
Brian Salomone7d30482017-03-29 12:09:15 -040062 /**
63 * This is a legacy class only used by GrMeshDrawOp and will be removed. It presents some
Brian Salomona811b122017-03-30 08:21:32 -040064 * aspects of GrProcessorSet::Analysis to GrMeshDrawOp subclasses.
Brian Salomone7d30482017-03-29 12:09:15 -040065 */
66 class PipelineOptimizations {
67 public:
Brian Salomona811b122017-03-30 08:21:32 -040068 PipelineOptimizations(const GrProcessorSet::Analysis& analysis) {
Brian Salomone7d30482017-03-29 12:09:15 -040069 fFlags = 0;
70 if (analysis.getInputColorOverrideAndColorProcessorEliminationCount(&fOverrideColor) >=
71 0) {
72 fFlags |= kUseOverrideColor_Flag;
73 }
74 if (analysis.usesLocalCoords()) {
75 fFlags |= kReadsLocalCoords_Flag;
76 }
77 if (analysis.isCompatibleWithCoverageAsAlpha()) {
78 fFlags |= kCanTweakAlphaForCoverage_Flag;
79 }
80 }
81
82 /** Does the pipeline require access to (implicit or explicit) local coordinates? */
83 bool readsLocalCoords() const { return SkToBool(kReadsLocalCoords_Flag & fFlags); }
84
85 /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
86 color output ? */
87 bool canTweakAlphaForCoverage() const {
88 return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
89 }
90
91 /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
92 so get the color)? */
93 bool getOverrideColorIfSet(GrColor* overrideColor) const {
94 if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
95 if (overrideColor) {
96 *overrideColor = fOverrideColor;
97 }
98 return true;
99 }
100 return false;
101 }
102
103 private:
104 enum {
105 // If this is not set the primitive processor need not produce local coordinates
106 kReadsLocalCoords_Flag = 0x1,
107 // If this flag is set then the primitive processor may produce color*coverage as
108 // its color output (and not output a separate coverage).
109 kCanTweakAlphaForCoverage_Flag = 0x2,
110 // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
111 // output color. If not set fOverrideColor is to be ignored.
112 kUseOverrideColor_Flag = 0x4,
113 };
114
115 uint32_t fFlags;
116 GrColor fOverrideColor;
117 };
Brian Salomon54d212e2017-03-21 14:22:38 -0400118
bsalomon16b99132015-08-13 14:55:50 -0700119 /** Helper for rendering instances using an instanced index index buffer. This class creates the
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500120 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
Brian Salomondad29232016-12-01 16:40:24 -0500121 class InstancedHelper {
122 public:
bsalomon16b99132015-08-13 14:55:50 -0700123 InstancedHelper() {}
bsalomon342bfc22016-04-01 06:06:20 -0700124 /** Returns the allocated storage for the vertices. The caller should populate the vertices
125 before calling recordDraws(). */
Brian Salomondad29232016-12-01 16:40:24 -0500126 void* init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
127 int verticesPerInstance, int indicesPerInstance, int instancesToDraw);
bsalomon16b99132015-08-13 14:55:50 -0700128
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500129 /** Call after init() to issue draws to the GrMeshDrawOp::Target.*/
bsalomon342bfc22016-04-01 06:06:20 -0700130 void recordDraw(Target*, const GrGeometryProcessor*);
Brian Salomondad29232016-12-01 16:40:24 -0500131
bsalomon16b99132015-08-13 14:55:50 -0700132 private:
bsalomon342bfc22016-04-01 06:06:20 -0700133 GrMesh fMesh;
bsalomon16b99132015-08-13 14:55:50 -0700134 };
135
136 static const int kVerticesPerQuad = 4;
137 static const int kIndicesPerQuad = 6;
138
139 /** A specialization of InstanceHelper for quad rendering. */
140 class QuadHelper : private InstancedHelper {
141 public:
142 QuadHelper() : INHERITED() {}
halcanary96fcdcc2015-08-27 07:41:13 -0700143 /** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure
bsalomon342bfc22016-04-01 06:06:20 -0700144 and on success a pointer to the vertex data that the caller should populate before
145 calling recordDraws(). */
146 void* init(Target*, size_t vertexStride, int quadsToDraw);
bsalomon16b99132015-08-13 14:55:50 -0700147
bsalomon75398562015-08-17 12:55:38 -0700148 using InstancedHelper::recordDraw;
Brian Salomondad29232016-12-01 16:40:24 -0500149
bsalomon16b99132015-08-13 14:55:50 -0700150 private:
151 typedef InstancedHelper INHERITED;
152 };
153
Brian Salomon54d212e2017-03-21 14:22:38 -0400154 const GrPipeline* pipeline() const {
155 SkASSERT(fPipeline.isInitialized());
156 return &fPipeline;
157 }
158
bsalomon16b99132015-08-13 14:55:50 -0700159private:
Brian Salomon54d212e2017-03-21 14:22:38 -0400160 /**
161 * Provides information about the GrPrimitiveProccesor color and coverage outputs which become
162 * inputs to the first color and coverage fragment processors.
163 */
Brian Salomona811b122017-03-30 08:21:32 -0400164 virtual void getProcessorAnalysisInputs(GrProcessorAnalysisColor*,
165 GrProcessorAnalysisCoverage*) const = 0;
Brian Salomon54d212e2017-03-21 14:22:38 -0400166
167 /**
Brian Salomona811b122017-03-30 08:21:32 -0400168 * After processor analysis is complete this is called so that the op can use the analysis
Brian Salomon54d212e2017-03-21 14:22:38 -0400169 * results when constructing its GrPrimitiveProcessor.
170 */
Brian Salomone7d30482017-03-29 12:09:15 -0400171 virtual void applyPipelineOptimizations(const PipelineOptimizations&) = 0;
Brian Salomon54d212e2017-03-21 14:22:38 -0400172
Brian Salomon742e31d2016-12-07 17:06:19 -0500173 void onPrepare(GrOpFlushState* state) final;
Brian Salomon9e50f7b2017-03-06 12:02:34 -0500174 void onExecute(GrOpFlushState* state) final;
bsalomon53469832015-08-18 09:20:09 -0700175
joshualitt144c3c82015-11-30 12:30:13 -0800176 virtual void onPrepareDraws(Target*) const = 0;
bsalomon75398562015-08-17 12:55:38 -0700177
bsalomon342bfc22016-04-01 06:06:20 -0700178 // A set of contiguous draws that share a draw token and primitive processor. The draws all use
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500179 // the op's pipeline. The meshes for the draw are stored in the fMeshes array and each
bsalomon342bfc22016-04-01 06:06:20 -0700180 // Queued draw uses fMeshCnt meshes from the fMeshes array. The reason for coallescing meshes
181 // that share a primitive processor into a QueuedDraw is that it allows the Gpu object to setup
182 // the shared state once and then issue draws for each mesh.
183 struct QueuedDraw {
184 int fMeshCnt = 0;
185 GrPendingProgramElement<const GrGeometryProcessor> fGeometryProcessor;
bsalomon75398562015-08-17 12:55:38 -0700186 };
187
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500188 // All draws in all the GrMeshDrawOps have implicit tokens based on the order they are enqueued
189 // globally across all ops. This is the offset of the first entry in fQueuedDraws.
bsalomon342bfc22016-04-01 06:06:20 -0700190 // fQueuedDraws[i]'s token is fBaseDrawToken + i.
Brian Salomon9afd3712016-12-01 10:59:09 -0500191 GrDrawOpUploadToken fBaseDrawToken;
Brian Salomon54d212e2017-03-21 14:22:38 -0400192 GrPipeline fPipeline;
Brian Salomondad29232016-12-01 16:40:24 -0500193 SkSTArray<4, GrMesh> fMeshes;
bsalomon342bfc22016-04-01 06:06:20 -0700194 SkSTArray<4, QueuedDraw, true> fQueuedDraws;
bsalomon75398562015-08-17 12:55:38 -0700195
Brian Salomon9afd3712016-12-01 10:59:09 -0500196 typedef GrDrawOp INHERITED;
bsalomon16b99132015-08-13 14:55:50 -0700197};
198
199#endif