• 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 "GrAppliedClip.h"
12 #include "GrDrawOp.h"
13 #include "GrGeometryProcessor.h"
14 #include "GrMesh.h"
15 #include <type_traits>
16 
17 class GrAtlasManager;
18 class GrCaps;
19 class GrStrikeCache;
20 class GrOpFlushState;
21 
22 /**
23  * Base class for mesh-drawing GrDrawOps.
24  */
25 class GrMeshDrawOp : public GrDrawOp {
26 public:
27     /** Abstract interface that represents a destination for a GrMeshDrawOp. */
28     class Target;
29 
30 protected:
31     GrMeshDrawOp(uint32_t classID);
32 
33     /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
34         space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
35     class PatternHelper {
36     public:
37         PatternHelper(Target*, GrPrimitiveType, size_t vertexStride,
38                       sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition,
39                       int indicesPerRepetition, int repeatCount);
40 
41         /** Called to issue draws to the GrMeshDrawOp::Target.*/
42         void recordDraw(Target*, sk_sp<const GrGeometryProcessor>) const;
43         void recordDraw(Target*, sk_sp<const GrGeometryProcessor>,
44                         const GrPipeline::FixedDynamicState*) const;
45 
vertices()46         void* vertices() const { return fVertices; }
47 
48     protected:
49         PatternHelper() = default;
50         void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
51                   int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
52 
53     private:
54         void* fVertices = nullptr;
55         GrMesh* fMesh = nullptr;
56     };
57 
58     static const int kVerticesPerQuad = 4;
59     static const int kIndicesPerQuad = 6;
60 
61     /** A specialization of InstanceHelper for quad rendering. */
62     class QuadHelper : private PatternHelper {
63     public:
64         QuadHelper() = delete;
65         QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
66 
67         using PatternHelper::recordDraw;
68         using PatternHelper::vertices;
69 
70     private:
71         typedef PatternHelper INHERITED;
72     };
73 
74 private:
75     void onPrepare(GrOpFlushState* state) final;
76     virtual void onPrepareDraws(Target*) = 0;
77     typedef GrDrawOp INHERITED;
78 };
79 
80 class GrMeshDrawOp::Target {
81 public:
~Target()82     virtual ~Target() {}
83 
84     /** Adds a draw of a mesh. */
85     virtual void recordDraw(
86             sk_sp<const GrGeometryProcessor>, const GrMesh[], int meshCnt,
87             const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*) = 0;
88 
89     /**
90      * Helper for drawing GrMesh(es) with zero primProc textures and no dynamic state besides the
91      * scissor clip.
92      */
93     void recordDraw(sk_sp<const GrGeometryProcessor> gp, const GrMesh meshes[], int meshCnt = 1) {
94         static constexpr int kZeroPrimProcTextures = 0;
95         auto fixedDynamicState = this->makeFixedDynamicState(kZeroPrimProcTextures);
96         this->recordDraw(std::move(gp), meshes, meshCnt, fixedDynamicState, nullptr);
97     }
98 
99     /**
100      * Makes space for vertex data. The returned pointer is the location where vertex data
101      * should be written. On return the buffer that will hold the data as well as an offset into
102      * the buffer (in 'vertexSize' units) where the data will be placed.
103      */
104     virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
105                                   int* startVertex) = 0;
106 
107     /**
108      * Makes space for index data. The returned pointer is the location where index data
109      * should be written. On return the buffer that will hold the data as well as an offset into
110      * the buffer (in uint16_t units) where the data will be placed.
111      */
112     virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;
113 
114     /**
115      * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
116      * vertices in the returned pointer, which may exceed 'minVertexCount'.
117      * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
118      * buffer is allocated on behalf of this request.
119      */
120     virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
121                                          int fallbackVertexCount, sk_sp<const GrBuffer>*,
122                                          int* startVertex, int* actualVertexCount) = 0;
123 
124     /**
125      * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
126      * indices in the returned pointer, which may exceed 'minIndexCount'.
127      * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
128      * buffer is allocated on behalf of this request.
129      */
130     virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
131                                             sk_sp<const GrBuffer>*, int* startIndex,
132                                             int* actualIndexCount) = 0;
133 
134     /** Helpers for ops which over-allocate and then return excess data to the pool. */
135     virtual void putBackIndices(int indices) = 0;
136     virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
137 
allocMesh(GrPrimitiveType primitiveType)138     GrMesh* allocMesh(GrPrimitiveType primitiveType) {
139         return this->allocator()->make<GrMesh>(primitiveType);
140     }
141 
allocMeshes(int n)142     GrMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrMesh>(n); }
143 
144     GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes,
145                                                             int numPrimitiveProcessorTextures,
146                                                             bool allocScissors);
147 
148     GrPipeline::FixedDynamicState* makeFixedDynamicState(int numPrimitiveProcessorTextures);
149 
150     virtual GrRenderTargetProxy* proxy() const = 0;
151 
152     virtual const GrAppliedClip* appliedClip() = 0;
153     virtual GrAppliedClip detachAppliedClip() = 0;
154 
155     virtual const GrXferProcessor::DstProxy& dstProxy() const = 0;
156 
157     virtual GrResourceProvider* resourceProvider() const = 0;
contextUniqueID()158     uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
159 
160     virtual GrStrikeCache* glyphCache() const = 0;
161     virtual GrAtlasManager* atlasManager() const = 0;
162 
163     virtual const GrCaps& caps() const = 0;
164 
165     virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
166 
167 private:
168     virtual SkArenaAlloc* allocator() = 0;
169 };
170 
171 #endif
172