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