• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2017 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 #include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
9 
10 #include "src/gpu/ganesh/GrAppliedClip.h"
11 #include "src/gpu/ganesh/GrProcessorSet.h"
12 #include "src/gpu/ganesh/GrProgramInfo.h"
13 #include "src/gpu/ganesh/GrUserStencilSettings.h"
14 #include "src/gpu/ganesh/SkGr.h"
15 #include "src/gpu/ganesh/geometry/GrRect.h"
16 
GrSimpleMeshDrawOpHelper(GrProcessorSet * processorSet,GrAAType aaType,InputFlags inputFlags)17 GrSimpleMeshDrawOpHelper::GrSimpleMeshDrawOpHelper(GrProcessorSet* processorSet,
18                                                    GrAAType aaType,
19                                                    InputFlags inputFlags)
20         : fProcessors(processorSet)
21         , fPipelineFlags((GrPipeline::InputFlags)inputFlags)
22         , fAAType((int)aaType)
23         , fUsesLocalCoords(false)
24         , fCompatibleWithCoverageAsAlpha(false) {
25     SkDEBUGCODE(fDidAnalysis = false);
26     SkDEBUGCODE(fMadePipeline = false);
27 }
28 
~GrSimpleMeshDrawOpHelper()29 GrSimpleMeshDrawOpHelper::~GrSimpleMeshDrawOpHelper() {
30     if (fProcessors) {
31         fProcessors->~GrProcessorSet();
32     }
33 }
34 
fixedFunctionFlags() const35 GrDrawOp::FixedFunctionFlags GrSimpleMeshDrawOpHelper::fixedFunctionFlags() const {
36     return GrAATypeIsHW(this->aaType()) ? GrDrawOp::FixedFunctionFlags::kUsesHWAA
37                                         : GrDrawOp::FixedFunctionFlags::kNone;
38 }
39 
isCompatible(const GrSimpleMeshDrawOpHelper & that,const GrCaps & caps,const SkRect & thisBounds,const SkRect & thatBounds,bool ignoreAAType) const40 bool GrSimpleMeshDrawOpHelper::isCompatible(const GrSimpleMeshDrawOpHelper& that,
41                                             const GrCaps& caps, const SkRect& thisBounds,
42                                             const SkRect& thatBounds, bool ignoreAAType) const {
43     if (SkToBool(fProcessors) != SkToBool(that.fProcessors)) {
44         return false;
45     }
46     if (fProcessors) {
47         if (*fProcessors != *that.fProcessors) {
48             return false;
49         }
50     }
51 
52 #ifdef SK_DEBUG
53     if (ignoreAAType) {
54         // If we're ignoring AA it should be bc we already know they are the same or that
55         // the are different but are compatible (i.e., one is AA and the other is None)
56         SkASSERT(fAAType == that.fAAType ||
57                  GrMeshDrawOp::CanUpgradeAAOnMerge(this->aaType(), that.aaType()));
58     }
59 #endif
60 
61     bool result = fPipelineFlags == that.fPipelineFlags &&
62                   (ignoreAAType || fAAType == that.fAAType);
63     SkASSERT(!result || fCompatibleWithCoverageAsAlpha == that.fCompatibleWithCoverageAsAlpha);
64     SkASSERT(!result || fUsesLocalCoords == that.fUsesLocalCoords);
65     return result;
66 }
67 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,GrClampType clampType,GrProcessorAnalysisCoverage geometryCoverage,SkPMColor4f * geometryColor,bool * wideColor)68 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
69         const GrCaps& caps, const GrAppliedClip* clip, GrClampType clampType,
70         GrProcessorAnalysisCoverage geometryCoverage, SkPMColor4f* geometryColor, bool* wideColor) {
71     GrProcessorAnalysisColor color = *geometryColor;
72     auto result = this->finalizeProcessors(caps, clip, clampType, geometryCoverage, &color);
73     color.isConstant(geometryColor);
74     if (wideColor) {
75         *wideColor = !geometryColor->fitsInBytes();
76     }
77     return result;
78 }
79 
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,const GrUserStencilSettings * userStencil,GrClampType clampType,GrProcessorAnalysisCoverage geometryCoverage,GrProcessorAnalysisColor * geometryColor)80 GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors(
81         const GrCaps& caps, const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
82         GrClampType clampType, GrProcessorAnalysisCoverage geometryCoverage,
83         GrProcessorAnalysisColor* geometryColor) {
84     SkDEBUGCODE(fDidAnalysis = true);
85     GrProcessorSet::Analysis analysis;
86     if (fProcessors) {
87         GrProcessorAnalysisCoverage coverage = geometryCoverage;
88         if (GrProcessorAnalysisCoverage::kNone == coverage) {
89             coverage = (clip && clip->hasCoverageFragmentProcessor())
90                                ? GrProcessorAnalysisCoverage::kSingleChannel
91                                : GrProcessorAnalysisCoverage::kNone;
92         }
93         SkPMColor4f overrideColor;
94         analysis = fProcessors->finalize(*geometryColor, coverage, clip, userStencil, caps,
95                                          clampType, &overrideColor);
96         if (analysis.inputColorIsOverridden()) {
97             *geometryColor = overrideColor;
98         }
99     } else {
100         analysis = GrProcessorSet::EmptySetAnalysis();
101     }
102     fUsesLocalCoords = analysis.usesLocalCoords();
103     fCompatibleWithCoverageAsAlpha = analysis.isCompatibleWithCoverageAsAlpha();
104     return analysis;
105 }
106 
CreatePipeline(const GrCaps * caps,SkArenaAlloc * arena,skgpu::Swizzle writeViewSwizzle,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrProcessorSet && processorSet,GrPipeline::InputFlags pipelineFlags)107 const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(const GrCaps* caps,
108                                                            SkArenaAlloc* arena,
109                                                            skgpu::Swizzle writeViewSwizzle,
110                                                            GrAppliedClip&& appliedClip,
111                                                            const GrDstProxyView& dstProxyView,
112                                                            GrProcessorSet&& processorSet,
113                                                            GrPipeline::InputFlags pipelineFlags) {
114     GrPipeline::InitArgs pipelineArgs;
115 
116     pipelineArgs.fInputFlags = pipelineFlags;
117     pipelineArgs.fCaps = caps;
118     pipelineArgs.fDstProxyView = dstProxyView;
119     pipelineArgs.fWriteSwizzle = writeViewSwizzle;
120 
121     return arena->make<GrPipeline>(pipelineArgs,
122                                    std::move(processorSet),
123                                    std::move(appliedClip));
124 }
125 
CreatePipeline(GrOpFlushState * flushState,GrProcessorSet && processorSet,GrPipeline::InputFlags pipelineFlags)126 const GrPipeline* GrSimpleMeshDrawOpHelper::CreatePipeline(GrOpFlushState* flushState,
127                                                            GrProcessorSet&& processorSet,
128                                                            GrPipeline::InputFlags pipelineFlags) {
129     return CreatePipeline(&flushState->caps(),
130                           flushState->allocator(),
131                           flushState->writeView().swizzle(),
132                           flushState->detachAppliedClip(),
133                           flushState->dstProxyView(),
134                           std::move(processorSet),
135                           pipelineFlags);
136 }
137 
createPipeline(GrOpFlushState * flushState)138 const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(GrOpFlushState* flushState) {
139     return CreatePipeline(&flushState->caps(),
140                           flushState->allocator(),
141                           flushState->writeView().swizzle(),
142                           flushState->detachAppliedClip(),
143                           flushState->dstProxyView(),
144                           this->detachProcessorSet(),
145                           this->pipelineFlags());
146 }
147 
createPipeline(const GrCaps * caps,SkArenaAlloc * arena,skgpu::Swizzle writeViewSwizzle,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView)148 const GrPipeline* GrSimpleMeshDrawOpHelper::createPipeline(const GrCaps* caps,
149                                                            SkArenaAlloc* arena,
150                                                            skgpu::Swizzle writeViewSwizzle,
151                                                            GrAppliedClip&& appliedClip,
152                                                            const GrDstProxyView& dstProxyView) {
153     return GrSimpleMeshDrawOpHelper::CreatePipeline(caps,
154                                                     arena,
155                                                     writeViewSwizzle,
156                                                     std::move(appliedClip),
157                                                     dstProxyView,
158                                                     this->detachProcessorSet(),
159                                                     this->pipelineFlags());
160 }
161 
CreateProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrGeometryProcessor * geometryProcessor,GrProcessorSet && processorSet,GrPrimitiveType primitiveType,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp,GrPipeline::InputFlags pipelineFlags,const GrUserStencilSettings * stencilSettings)162 GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(
163             const GrCaps* caps,
164             SkArenaAlloc* arena,
165             const GrSurfaceProxyView& writeView,
166             bool usesMSAASurface,
167             GrAppliedClip&& appliedClip,
168             const GrDstProxyView& dstProxyView,
169             GrGeometryProcessor* geometryProcessor,
170             GrProcessorSet&& processorSet,
171             GrPrimitiveType primitiveType,
172             GrXferBarrierFlags renderPassXferBarriers,
173             GrLoadOp colorLoadOp,
174             GrPipeline::InputFlags pipelineFlags,
175             const GrUserStencilSettings* stencilSettings) {
176     auto pipeline = CreatePipeline(caps,
177                                    arena,
178                                    writeView.swizzle(),
179                                    std::move(appliedClip),
180                                    dstProxyView,
181                                    std::move(processorSet),
182                                    pipelineFlags);
183 
184     return CreateProgramInfo(caps, arena, pipeline, writeView, usesMSAASurface, geometryProcessor,
185                              primitiveType, renderPassXferBarriers, colorLoadOp, stencilSettings);
186 }
187 
CreateProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrPipeline * pipeline,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrGeometryProcessor * geometryProcessor,GrPrimitiveType primitiveType,GrXferBarrierFlags xferBarrierFlags,GrLoadOp colorLoadOp,const GrUserStencilSettings * stencilSettings)188 GrProgramInfo* GrSimpleMeshDrawOpHelper::CreateProgramInfo(const GrCaps* caps,
189                                                            SkArenaAlloc* arena,
190                                                            const GrPipeline* pipeline,
191                                                            const GrSurfaceProxyView& writeView,
192                                                            bool usesMSAASurface,
193                                                            GrGeometryProcessor* geometryProcessor,
194                                                            GrPrimitiveType primitiveType,
195                                                            GrXferBarrierFlags xferBarrierFlags,
196                                                            GrLoadOp colorLoadOp,
197                                                            const GrUserStencilSettings* stencilSettings) {
198     auto tmp = arena->make<GrProgramInfo>(*caps,
199                                           writeView,
200                                           usesMSAASurface,
201                                           pipeline,
202                                           stencilSettings,
203                                           geometryProcessor,
204                                           primitiveType,
205                                           xferBarrierFlags,
206                                           colorLoadOp);
207     return tmp;
208 }
209 
createProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrGeometryProcessor * gp,GrPrimitiveType primType,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)210 GrProgramInfo* GrSimpleMeshDrawOpHelper::createProgramInfo(
211                                             const GrCaps* caps,
212                                             SkArenaAlloc* arena,
213                                             const GrSurfaceProxyView& writeView,
214                                             bool usesMSAASurface,
215                                             GrAppliedClip&& appliedClip,
216                                             const GrDstProxyView& dstProxyView,
217                                             GrGeometryProcessor* gp,
218                                             GrPrimitiveType primType,
219                                             GrXferBarrierFlags renderPassXferBarriers,
220                                             GrLoadOp colorLoadOp) {
221     return CreateProgramInfo(caps,
222                              arena,
223                              writeView,
224                              usesMSAASurface,
225                              std::move(appliedClip),
226                              dstProxyView,
227                              gp,
228                              this->detachProcessorSet(),
229                              primType,
230                              renderPassXferBarriers,
231                              colorLoadOp,
232                              this->pipelineFlags());
233 }
234 
235 #if defined(GR_TEST_UTILS)
dump_pipeline_flags(GrPipeline::InputFlags flags,SkString * result)236 static void dump_pipeline_flags(GrPipeline::InputFlags flags, SkString* result) {
237     if (GrPipeline::InputFlags::kNone != flags) {
238         if (flags & GrPipeline::InputFlags::kSnapVerticesToPixelCenters) {
239             result->append("Snap vertices to pixel center.\n");
240         }
241         if (flags & GrPipeline::InputFlags::kWireframe) {
242             result->append("Wireframe enabled.\n");
243         }
244         if (flags & GrPipeline::InputFlags::kConservativeRaster) {
245             result->append("Conservative raster enabled.\n");
246         }
247         return;
248     }
249     result->append("No pipeline flags\n");
250 }
251 
dumpInfo() const252 SkString GrSimpleMeshDrawOpHelper::dumpInfo() const {
253     const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
254     SkString result = processors.dumpProcessors();
255     result.append("AA Type: ");
256     switch (this->aaType()) {
257         case GrAAType::kNone:
258             result.append(" none\n");
259             break;
260         case GrAAType::kCoverage:
261             result.append(" coverage\n");
262             break;
263         case GrAAType::kMSAA:
264             result.append(" msaa\n");
265             break;
266     }
267     dump_pipeline_flags(fPipelineFlags, &result);
268     return result;
269 }
270 #endif
271