• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 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 GrMeshDrawOp_DEFINED
9 #define GrMeshDrawOp_DEFINED
10 
11 #include "src/core/SkArenaAlloc.h"
12 #include "src/gpu/GrAppliedClip.h"
13 #include "src/gpu/GrDrawIndirectCommand.h"
14 #include "src/gpu/GrGeometryProcessor.h"
15 #include "src/gpu/GrSimpleMesh.h"
16 #include "src/gpu/ops/GrDrawOp.h"
17 #include <type_traits>
18 
19 class GrAtlasManager;
20 class GrCaps;
21 class GrStrikeCache;
22 class GrOpFlushState;
23 class GrSmallPathAtlasMgr;
24 
25 /**
26  * Base class for mesh-drawing GrDrawOps.
27  */
28 class GrMeshDrawOp : public GrDrawOp {
29 public:
30     /** Abstract interface that represents a destination for a GrMeshDrawOp. */
31     class Target;
32 
CanUpgradeAAOnMerge(GrAAType aa1,GrAAType aa2)33     static bool CanUpgradeAAOnMerge(GrAAType aa1, GrAAType aa2) {
34         return (aa1 == GrAAType::kNone && aa2 == GrAAType::kCoverage) ||
35                (aa1 == GrAAType::kCoverage && aa2 == GrAAType::kNone);
36     }
37 
38 protected:
39     GrMeshDrawOp(uint32_t classID);
40 
createProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,GrAppliedClip && appliedClip,const GrXferProcessor::DstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)41     void createProgramInfo(const GrCaps* caps,
42                            SkArenaAlloc* arena,
43                            const GrSurfaceProxyView& writeView,
44                            GrAppliedClip&& appliedClip,
45                            const GrXferProcessor::DstProxyView& dstProxyView,
46                            GrXferBarrierFlags renderPassXferBarriers,
47                            GrLoadOp colorLoadOp) {
48         this->onCreateProgramInfo(caps, arena, writeView, std::move(appliedClip), dstProxyView,
49                                   renderPassXferBarriers, colorLoadOp);
50     }
51 
52     void createProgramInfo(Target* target);
53 
54     /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
55         space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
56     class PatternHelper {
57     public:
58         PatternHelper(Target*, GrPrimitiveType, size_t vertexStride,
59                       sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition,
60                       int indicesPerRepetition, int repeatCount, int maxRepetitions);
61 
62         /** Called to issue draws to the GrMeshDrawOp::Target.*/
63         void recordDraw(Target*, const GrGeometryProcessor*) const;
64         void recordDraw(Target*, const GrGeometryProcessor*,
65                         const GrSurfaceProxy* const primProcProxies[]) const;
66 
vertices()67         void* vertices() const { return fVertices; }
mesh()68         GrSimpleMesh* mesh() { return fMesh; }
69 
70     protected:
71         PatternHelper() = default;
72         void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
73                   int verticesPerRepetition, int indicesPerRepetition, int repeatCount,
74                   int maxRepetitions);
75 
76     private:
77         void* fVertices = nullptr;
78         GrSimpleMesh* fMesh = nullptr;
79         GrPrimitiveType fPrimitiveType;
80     };
81 
82     /** A specialization of InstanceHelper for quad rendering.
83      *  It only draws non-antialiased indexed quads.
84      */
85     class QuadHelper : private PatternHelper {
86     public:
87         QuadHelper() = delete;
88         QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
89 
90         using PatternHelper::mesh;
91         using PatternHelper::recordDraw;
92         using PatternHelper::vertices;
93 
94     private:
95         using INHERITED = PatternHelper;
96     };
97 
CombinedQuadCountWillOverflow(GrAAType aaType,bool willBeUpgradedToAA,int combinedQuadCount)98     static bool CombinedQuadCountWillOverflow(GrAAType aaType,
99                                               bool willBeUpgradedToAA,
100                                               int combinedQuadCount) {
101         bool willBeAA = (aaType == GrAAType::kCoverage) || willBeUpgradedToAA;
102 
103         return combinedQuadCount > (willBeAA ? GrResourceProvider::MaxNumAAQuads()
104                                              : GrResourceProvider::MaxNumNonAAQuads());
105     }
106 
107     virtual void onPrePrepareDraws(GrRecordingContext*,
108                                    const GrSurfaceProxyView& writeView,
109                                    GrAppliedClip*,
110                                    const GrXferProcessor::DstProxyView&,
111                                    GrXferBarrierFlags renderPassXferBarriers,
112                                    GrLoadOp colorLoadOp);
113 
114 private:
115     virtual GrProgramInfo* programInfo() = 0;
116     // This method is responsible for creating all the programInfos required
117     // by this op.
118     virtual void onCreateProgramInfo(const GrCaps*,
119                                      SkArenaAlloc*,
120                                      const GrSurfaceProxyView& writeView,
121                                      GrAppliedClip&&,
122                                      const GrXferProcessor::DstProxyView&,
123                                      GrXferBarrierFlags renderPassXferBarriers,
124                                      GrLoadOp colorLoadOp) = 0;
125 
onPrePrepare(GrRecordingContext * context,const GrSurfaceProxyView & writeView,GrAppliedClip * clip,const GrXferProcessor::DstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)126     void onPrePrepare(GrRecordingContext* context,
127                       const GrSurfaceProxyView& writeView,
128                       GrAppliedClip* clip,
129                       const GrXferProcessor::DstProxyView& dstProxyView,
130                       GrXferBarrierFlags renderPassXferBarriers,
131                       GrLoadOp colorLoadOp) final {
132         this->onPrePrepareDraws(context, writeView, clip, dstProxyView, renderPassXferBarriers,
133                                 colorLoadOp);
134     }
135     void onPrepare(GrOpFlushState* state) final;
136 
137     virtual void onPrepareDraws(Target*) = 0;
138     using INHERITED = GrDrawOp;
139 };
140 
141 class GrMeshDrawOp::Target {
142 public:
~Target()143     virtual ~Target() {}
144 
145     /** Adds a draw of a mesh. 'primProcProxies' must have
146      * GrGeometryProcessor::numTextureSamplers() entries. Can be null if no samplers.
147      */
148     virtual void recordDraw(const GrGeometryProcessor*,
149                             const GrSimpleMesh[],
150                             int meshCnt,
151                             const GrSurfaceProxy* const primProcProxies[],
152                             GrPrimitiveType) = 0;
153 
154     /**
155      * Helper for drawing GrSimpleMesh(es) with zero primProc textures.
156      */
recordDraw(const GrGeometryProcessor * gp,const GrSimpleMesh meshes[],int meshCnt,GrPrimitiveType primitiveType)157     void recordDraw(const GrGeometryProcessor* gp,
158                     const GrSimpleMesh meshes[],
159                     int meshCnt,
160                     GrPrimitiveType primitiveType) {
161         this->recordDraw(gp, meshes, meshCnt, nullptr, primitiveType);
162     }
163 
164     /**
165      * Makes space for vertex data. The returned pointer is the location where vertex data
166      * should be written. On return the buffer that will hold the data as well as an offset into
167      * the buffer (in 'vertexSize' units) where the data will be placed.
168      */
169     virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
170                                   int* startVertex) = 0;
171 
172     /**
173      * Makes space for index data. The returned pointer is the location where index data
174      * should be written. On return the buffer that will hold the data as well as an offset into
175      * the buffer (in uint16_t units) where the data will be placed.
176      */
177     virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;
178 
179     /**
180      * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
181      * vertices in the returned pointer, which may exceed 'minVertexCount'.
182      * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
183      * buffer is allocated on behalf of this request.
184      */
185     virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
186                                          int fallbackVertexCount, sk_sp<const GrBuffer>*,
187                                          int* startVertex, int* actualVertexCount) = 0;
188 
189     /**
190      * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
191      * indices in the returned pointer, which may exceed 'minIndexCount'.
192      * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
193      * buffer is allocated on behalf of this request.
194      */
195     virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
196                                             sk_sp<const GrBuffer>*, int* startIndex,
197                                             int* actualIndexCount) = 0;
198 
199     /**
200      * Makes space for elements in a draw-indirect buffer. Upon success, the returned pointer is a
201      * CPU mapping where the data should be written.
202      */
203     virtual GrDrawIndirectWriter makeDrawIndirectSpace(int drawCount, sk_sp<const GrBuffer>* buffer,
204                                                        size_t* offsetInBytes) = 0;
205 
206     /**
207      * Makes space for elements in a draw-indexed-indirect buffer. Upon success, the returned
208      * pointer is a CPU mapping where the data should be written.
209      */
210     virtual GrDrawIndexedIndirectWriter makeDrawIndexedIndirectSpace(int drawCount,
211                                                                      sk_sp<const GrBuffer>*,
212                                                                      size_t* offsetInBytes) = 0;
213 
214     /** Helpers for ops which over-allocate and then return excess data to the pool. */
215     virtual void putBackIndices(int indices) = 0;
216     virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
217     virtual void putBackIndirectDraws(int count) = 0;
218     virtual void putBackIndexedIndirectDraws(int count) = 0;
219 
allocMesh()220     GrSimpleMesh* allocMesh() { return this->allocator()->make<GrSimpleMesh>(); }
allocMeshes(int n)221     GrSimpleMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrSimpleMesh>(n); }
allocPrimProcProxyPtrs(int n)222     const GrSurfaceProxy** allocPrimProcProxyPtrs(int n) {
223         return this->allocator()->makeArray<const GrSurfaceProxy*>(n);
224     }
225 
226     virtual GrRenderTargetProxy* rtProxy() const = 0;
227     virtual const GrSurfaceProxyView& writeView() const = 0;
228 
229     virtual const GrAppliedClip* appliedClip() const = 0;
230     virtual GrAppliedClip detachAppliedClip() = 0;
231 
232     virtual const GrXferProcessor::DstProxyView& dstProxyView() const = 0;
233     virtual bool usesMSAASurface() const = 0;
234 
235     virtual GrXferBarrierFlags renderPassBarriers() const = 0;
236 
237     virtual GrLoadOp colorLoadOp() const = 0;
238 
239     virtual GrThreadSafeCache* threadSafeCache() const = 0;
240     virtual GrResourceProvider* resourceProvider() const = 0;
contextUniqueID()241     uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
242 
243     virtual GrStrikeCache* strikeCache() const = 0;
244     virtual GrAtlasManager* atlasManager() const = 0;
245     virtual GrSmallPathAtlasMgr* smallPathAtlasManager() const = 0;
246 
247     // This should be called during onPrepare of a GrOp. The caller should add any proxies to the
248     // array it will use that it did not access during a call to visitProxies. This is usually the
249     // case for atlases.
250     virtual SkTArray<GrSurfaceProxy*, true>* sampledProxyArray() = 0;
251 
252     virtual const GrCaps& caps() const = 0;
253 
254     virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
255 
256     virtual SkArenaAlloc* allocator() = 0;
257 };
258 
259 #endif
260