• 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 #ifndef GrSimpleMeshDrawOpHelper_DEFINED
9 #define GrSimpleMeshDrawOpHelper_DEFINED
10 
11 #include "GrMeshDrawOp.h"
12 #include "GrOpFlushState.h"
13 #include "GrPipeline.h"
14 
15 struct SkRect;
16 
17 /**
18  * This class can be used to help implement simple mesh draw ops. It reduces the amount of
19  * boilerplate code to type and also provides a mechanism for optionally allocating space for a
20  * GrProcessorSet based on a GrPaint. It is intended to be used by ops that construct a single
21  * GrPipeline for a uniform primitive color and a GrPaint.
22  */
23 class GrSimpleMeshDrawOpHelper {
24 public:
25     struct MakeArgs;
26 
27     /**
28      * This can be used by a Op class to perform allocation and initialization such that a
29      * GrProcessorSet (if required) is allocated as part of the the same allocation that as
30      * the Op instance. It requires that Op implements a constructor of the form:
31      *      Op(MakeArgs, GrColor, OpArgs...)
32      * which is public or made accessible via 'friend'.
33      */
34     template <typename Op, typename... OpArgs>
35     static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs);
36 
37     enum class Flags : uint32_t {
38         kNone = 0x0,
39         kSnapVerticesToPixelCenters = 0x1,
40     };
41     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
42 
43     GrSimpleMeshDrawOpHelper(const MakeArgs&, GrAAType, Flags = Flags::kNone);
44     ~GrSimpleMeshDrawOpHelper();
45 
46     GrSimpleMeshDrawOpHelper() = delete;
47     GrSimpleMeshDrawOpHelper(const GrSimpleMeshDrawOpHelper&) = delete;
48     GrSimpleMeshDrawOpHelper& operator=(const GrSimpleMeshDrawOpHelper&) = delete;
49 
50     GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
51 
52     bool isCompatible(const GrSimpleMeshDrawOpHelper& that, const GrCaps&, const SkRect& thisBounds,
53                       const SkRect& thatBounds) const;
54 
55     /**
56      * Finalizes the processor set and determines whether the destination must be provided
57      * to the fragment shader as a texture for blending.
58      *
59      * @param geometryCoverage Describes the coverage output of the op's geometry processor
60      * @param geometryColor An in/out param. As input this informs processor analysis about the
61      *                      color the op expects to output from its geometry processor. As output
62      *                      this may be set to a known color in which case the op must output this
63      *                      color from its geometry processor instead.
64      */
65     GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip,
66                                                       GrProcessorAnalysisCoverage geometryCoverage,
67                                                       GrProcessorAnalysisColor* geometryColor);
68 
69     /**
70      * Version of above that can be used by ops that have a constant color geometry processor
71      * output. The op passes this color as 'geometryColor' and after return if 'geometryColor' has
72      * changed the op must override its geometry processor color output with the new color.
73      */
74     GrDrawOp::RequiresDstTexture xpRequiresDstTexture(const GrCaps&, const GrAppliedClip*,
75                                                       GrProcessorAnalysisCoverage geometryCoverage,
76                                                       GrColor* geometryColor);
77 
usesLocalCoords()78     bool usesLocalCoords() const {
79         SkASSERT(fDidAnalysis);
80         return fUsesLocalCoords;
81     }
82 
compatibleWithAlphaAsCoverage()83     bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; }
84 
makePipeline(GrMeshDrawOp::Target * target)85     GrPipeline* makePipeline(GrMeshDrawOp::Target* target) const {
86         return target->allocPipeline(this->pipelineInitArgs(target));
87     }
88 
89     struct MakeArgs {
90     private:
91         MakeArgs() = default;
92 
93         GrProcessorSet* fProcessorSet;
94         uint32_t fSRGBFlags;
95 
96         friend class GrSimpleMeshDrawOpHelper;
97     };
98 
99     SkString dumpInfo() const;
100 
101 protected:
aaType()102     GrAAType aaType() const { return static_cast<GrAAType>(fAAType); }
pipelineFlags()103     uint32_t pipelineFlags() const { return fPipelineFlags; }
processors()104     const GrProcessorSet& processors() const {
105         return fProcessors ? *fProcessors : GrProcessorSet::EmptySet();
106     }
107 
108     GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const;
109 
110 private:
111     GrProcessorSet* fProcessors;
112     unsigned fPipelineFlags : 8;
113     unsigned fAAType : 2;
114     unsigned fRequiresDstTexture : 1;
115     unsigned fUsesLocalCoords : 1;
116     unsigned fCompatibleWithAlphaAsCoveage : 1;
117     SkDEBUGCODE(unsigned fDidAnalysis : 1;)
118 };
119 
120 /**
121  * This class extends GrSimpleMeshDrawOpHelper to support an optional GrUserStencilSettings. This
122  * uses private inheritance because it non-virtually overrides methods in the base class and should
123  * never be used with a GrSimpleMeshDrawOpHelper pointer or reference.
124  */
125 class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper {
126 public:
127     using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs;
128     using Flags = GrSimpleMeshDrawOpHelper::Flags;
129 
130     // using declarations can't be templated, so this is a pass through function instead.
131     template <typename Op, typename... OpArgs>
FactoryHelper(GrPaint && paint,OpArgs...opArgs)132     static std::unique_ptr<GrDrawOp> FactoryHelper(GrPaint&& paint, OpArgs... opArgs) {
133         return GrSimpleMeshDrawOpHelper::FactoryHelper<Op, OpArgs...>(
134                 std::move(paint), std::forward<OpArgs>(opArgs)...);
135     }
136 
137     GrSimpleMeshDrawOpHelperWithStencil(const MakeArgs&, GrAAType, const GrUserStencilSettings*,
138                                         Flags = Flags::kNone);
139 
140     GrDrawOp::FixedFunctionFlags fixedFunctionFlags() const;
141 
142     using GrSimpleMeshDrawOpHelper::xpRequiresDstTexture;
143     using GrSimpleMeshDrawOpHelper::usesLocalCoords;
144     using GrSimpleMeshDrawOpHelper::compatibleWithAlphaAsCoverage;
145 
146     bool isCompatible(const GrSimpleMeshDrawOpHelperWithStencil& that, const GrCaps&,
147                       const SkRect& thisBounds, const SkRect& thatBounds) const;
148 
149     const GrPipeline* makePipeline(GrMeshDrawOp::Target*) const;
150 
151     SkString dumpInfo() const;
152 
153 private:
154     const GrUserStencilSettings* fStencilSettings;
155     typedef GrSimpleMeshDrawOpHelper INHERITED;
156 };
157 
158 template <typename Op, typename... OpArgs>
FactoryHelper(GrPaint && paint,OpArgs...opArgs)159 std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrPaint&& paint,
160                                                                   OpArgs... opArgs) {
161     MakeArgs makeArgs;
162     makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint);
163     GrColor color = paint.getColor();
164     if (paint.isTrivial()) {
165         makeArgs.fProcessorSet = nullptr;
166         return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
167     } else {
168         char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet));
169         char* setMem = mem + sizeof(Op);
170         makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint));
171         return std::unique_ptr<GrDrawOp>(
172                 new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...));
173     }
174 }
175 
176 GR_MAKE_BITFIELD_CLASS_OPS(GrSimpleMeshDrawOpHelper::Flags)
177 
178 #endif
179