xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h (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 
8 #ifndef GrSimpleMeshDrawOpHelper_DEFINED
9 #define GrSimpleMeshDrawOpHelper_DEFINED
10 
11 #include "include/core/SkString.h"
12 #include "include/private/SkColorData.h"
13 #include "include/private/base/SkAssert.h"
14 #include "include/private/base/SkDebug.h"
15 #include "include/private/base/SkMacros.h"
16 #include "include/private/gpu/ganesh/GrTypesPriv.h"
17 #include "src/gpu/ganesh/GrCaps.h"
18 #include "src/gpu/ganesh/GrPaint.h"
19 #include "src/gpu/ganesh/GrPipeline.h"
20 #include "src/gpu/ganesh/GrProcessorSet.h"
21 #include "src/gpu/ganesh/GrUserStencilSettings.h"
22 #include "src/gpu/ganesh/ops/GrDrawOp.h"
23 #include "src/gpu/ganesh/ops/GrOp.h"
24 
25 #include <cstdint>
26 #include <new>
27 #include <utility>
28 
29 class GrAppliedClip;
30 class GrDstProxyView;
31 class GrGeometryProcessor;
32 class GrOpFlushState;
33 class GrProcessorAnalysisColor;
34 class GrProgramInfo;
35 class GrRecordingContext;
36 class GrSurfaceProxyView;
37 class SkArenaAlloc;
38 enum class GrProcessorAnalysisCoverage;
39 enum class GrXferBarrierFlags;
40 namespace skgpu {
41 class Swizzle;
42 }
43 struct SkRect;
44 
45 /**
46  * This class can be used to help implement simple mesh draw ops. It reduces the amount of
47  * boilerplate code to type and also provides a mechanism for optionally allocating space for a
48  * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
49  * GrPipeline for a uniform primitive color and a GrPaint.
50  */
51 class GrSimpleMeshDrawOpHelper {
52 public:
53     /**
54      * This can be used by a Op class to perform allocation and initialization such that a
55      * GrProcessorSet (if required) is allocated as part of the the same allocation that as
56      * the Op instance. It requires that Op implements a constructor of the form:
57      *      Op(ProcessorSet*, GrColor, OpArgs...).
58      */
59     template <typename Op, typename... OpArgs>
60     static GrOp::Owner FactoryHelper(GrRecordingContext*, GrPaint&&, OpArgs&&...);
61 
62     // Here we allow callers to specify a subset of the GrPipeline::InputFlags upon creation.
63     enum class InputFlags : uint8_t {
64         kNone = 0,
65         kSnapVerticesToPixelCenters = (uint8_t)GrPipeline::InputFlags::kSnapVerticesToPixelCenters,
66         kConservativeRaster = (uint8_t)GrPipeline::InputFlags::kConservativeRaster,
67     };
68     SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(InputFlags);
69 
70     GrSimpleMeshDrawOpHelper(GrProcessorSet*, GrAAType, InputFlags = InputFlags::kNone);
71     ~GrSimpleMeshDrawOpHelper();
72 
73     GrSimpleMeshDrawOpHelper() = delete;
74     GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
75     GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
76 
77     GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
78 
79     // ignoreAAType should be set to true if the op already knows the AA settings are acceptible
80     bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
81                       const SkRect& thatBounds, bool ignoreAAType = false) const;
82 
83     /**
84      * Finalizes the processor set and determines whether the destination must be provided
85      * to the fragment shader as a texture for blending.
86      *
87      * @param geometryCoverage Describes the coverage output of the op's geometry processor
88      * @param geometryColor An in/out param. As input this informs processor analysis about the
89      *                      color the op expects to output from its geometry processor. As output
90      *                      this may be set to a known color in which case the op must output this
91      *                      color from its geometry processor instead.
92      */
finalizeProcessors(const GrCaps & caps,const GrAppliedClip * clip,GrClampType clampType,GrProcessorAnalysisCoverage geometryCoverage,GrProcessorAnalysisColor * geometryColor)93     GrProcessorSet::Analysis finalizeProcessors(const GrCaps& caps, const GrAppliedClip* clip,
94                                                 GrClampType clampType,
95                                                 GrProcessorAnalysisCoverage geometryCoverage,
96                                                 GrProcessorAnalysisColor* geometryColor) {
97         return this->finalizeProcessors(caps, clip, &GrUserStencilSettings::kUnused, clampType,
98                                         geometryCoverage, geometryColor);
99     }
100 
101     /**
102      * Version of above that can be used by ops that have a constant color geometry processor
103      * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
104      * changed the op must override its geometry processor color output with the new color.
105      */
106     GrProcessorSet::Analysis finalizeProcessors(const GrCaps&, const GrAppliedClip*, GrClampType,
107                                                 GrProcessorAnalysisCoverage geometryCoverage,
108                                                 SkPMColor4f* geometryColor, bool* wideColor);
109 
isTrivial()110     bool isTrivial() const {
111       return fProcessors == nullptr;
112     }
113 
usesLocalCoords()114     bool usesLocalCoords() const {
115         SkASSERT(fDidAnalysis);
116         return fUsesLocalCoords;
117     }
118 
compatibleWithCoverageAsAlpha()119     bool compatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
120 
visitProxies(const GrVisitProxyFunc & func)121     void visitProxies(const GrVisitProxyFunc& func) const {
122         if (fProcessors) {
123             fProcessors->visitProxies(func);
124         }
125     }
126 
127 #if defined(GPU_TEST_UTILS)
128     SkString dumpInfo() const;
129 #endif
aaType()130     GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
131 
setAAType(GrAAType aaType)132     void setAAType(GrAAType aaType) {
133         fAAType = static_cast<unsigned>(aaType);
134     }
135 
136     static const GrPipeline* CreatePipeline(const GrCaps*,
137                                             SkArenaAlloc*,
138                                             skgpu::Swizzle writeViewSwizzle,
139                                             GrAppliedClip&&,
140                                             const GrDstProxyView&,
141                                             GrProcessorSet&&,
142                                             GrPipeline::InputFlags pipelineFlags);
143 
144     static const GrPipeline* CreatePipeline(GrOpFlushState*,
145                                             GrProcessorSet&&,
146                                             GrPipeline::InputFlags pipelineFlags);
147 
148     const GrPipeline* createPipeline(GrOpFlushState* flushState);
149 
150     const GrPipeline* createPipeline(const GrCaps*,
151                                      SkArenaAlloc*,
152                                      skgpu::Swizzle writeViewSwizzle,
153                                      GrAppliedClip&&,
154                                      const GrDstProxyView&);
155 
156     static GrProgramInfo* CreateProgramInfo(const GrCaps*,
157                                             SkArenaAlloc*,
158                                             const GrPipeline*,
159                                             const GrSurfaceProxyView& writeView,
160                                             bool usesMSAASurface,
161                                             GrGeometryProcessor*,
162                                             GrPrimitiveType,
163                                             GrXferBarrierFlags renderPassXferBarriers,
164                                             GrLoadOp colorLoadOp,
165                                             const GrUserStencilSettings*
166                                                                 = &GrUserStencilSettings::kUnused);
167 
168     // Create a programInfo with the following properties:
169     //     its primitive processor uses no textures
170     //     it has no dynamic state besides the scissor clip
171     static GrProgramInfo* CreateProgramInfo(const GrCaps*,
172                                             SkArenaAlloc*,
173                                             const GrSurfaceProxyView& writeView,
174                                             bool usesMSAASurface,
175                                             GrAppliedClip&&,
176                                             const GrDstProxyView&,
177                                             GrGeometryProcessor*,
178                                             GrProcessorSet&&,
179                                             GrPrimitiveType,
180                                             GrXferBarrierFlags renderPassXferBarriers,
181                                             GrLoadOp colorLoadOp,
182                                             GrPipeline::InputFlags pipelineFlags
183                                                                 = GrPipeline::InputFlags::kNone,
184                                             const GrUserStencilSettings*
185                                                                 = &GrUserStencilSettings::kUnused);
186 
187     GrProgramInfo* createProgramInfo(const GrCaps*,
188                                      SkArenaAlloc*,
189                                      const GrSurfaceProxyView& writeView,
190                                      bool usesMSAASurface,
191                                      GrAppliedClip&&,
192                                      const GrDstProxyView&,
193                                      GrGeometryProcessor*,
194                                      GrPrimitiveType,
195                                      GrXferBarrierFlags renderPassXferBarriers,
196                                      GrLoadOp colorLoadOp);
197 
detachProcessorSet()198     GrProcessorSet detachProcessorSet() {
199         return fProcessors ? std::move(*fProcessors) : GrProcessorSet::MakeEmptySet();
200     }
201 
pipelineFlags()202     GrPipeline::InputFlags pipelineFlags() const { return fPipelineFlags; }
203 
204 protected:
205     GrProcessorSet::Analysis finalizeProcessors(const GrCaps& caps, const GrAppliedClip*,
206                                                 const GrUserStencilSettings*, GrClampType,
207                                                 GrProcessorAnalysisCoverage geometryCoverage,
208                                                 GrProcessorAnalysisColor* geometryColor);
209 
210     GrProcessorSet* fProcessors;
211     GrPipeline::InputFlags fPipelineFlags;
212     unsigned fAAType : 2;
213     unsigned fUsesLocalCoords : 1;
214     unsigned fCompatibleWithCoverageAsAlpha : 1;
215     SkDEBUGCODE(unsigned fMadePipeline : 1;)
216     SkDEBUGCODE(unsigned fDidAnalysis : 1;)
217 };
218 
219 template<typename Op, typename... Args>
MakeWithProcessorSet(GrRecordingContext * context,const SkPMColor4f & color,GrPaint && paint,Args &&...args)220 GrOp::Owner GrOp::MakeWithProcessorSet(
221         GrRecordingContext* context, const SkPMColor4f& color,
222         GrPaint&& paint, Args&&... args) {
223     char* bytes = (char*)::operator new(sizeof(Op) + sizeof(GrProcessorSet));
224     char* setMem = bytes + sizeof(Op);
225     GrProcessorSet* processorSet = new (setMem) GrProcessorSet{std::move(paint)};
226     return Owner{new (bytes) Op(processorSet, color, std::forward<Args>(args)...)};
227 }
228 
229 template <typename Op, typename... OpArgs>
FactoryHelper(GrRecordingContext * context,GrPaint && paint,OpArgs &&...opArgs)230 GrOp::Owner GrSimpleMeshDrawOpHelper::FactoryHelper(GrRecordingContext* context,
231                                                     GrPaint&& paint,
232                                                     OpArgs&& ... opArgs) {
233     auto color = paint.getColor4f();
234     if (paint.isTrivial()) {
235         return GrOp::Make<Op>(context, nullptr, color, std::forward<OpArgs>(opArgs)...);
236     } else {
237         return GrOp::MakeWithProcessorSet<Op>(
238                 context, color, std::move(paint), std::forward<OpArgs>(opArgs)...);
239     }
240 }
241 
242 SK_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::InputFlags)
243 
244 #endif
245