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