blob: a6e7da5c2ef3f93409fbc009a18821c5aaac7845 [file] [log] [blame]
bsalomon16b99132015-08-13 14:55:50 -07001/*
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
Brian Salomon53e4c3c2016-12-21 11:38:53 -05008#ifndef GrMeshDrawOp_DEFINED
9#define GrMeshDrawOp_DEFINED
bsalomon16b99132015-08-13 14:55:50 -070010
Brian Salomon49348902018-06-26 09:12:38 -040011#include "GrAppliedClip.h"
Brian Salomon9afd3712016-12-01 10:59:09 -050012#include "GrDrawOp.h"
bsalomon342bfc22016-04-01 06:06:20 -070013#include "GrGeometryProcessor.h"
egdaniel0e1853c2016-03-17 11:35:45 -070014#include "GrMesh.h"
bsalomon75398562015-08-17 12:55:38 -070015
Robert Phillipsc4039ea2018-03-01 11:36:45 -050016class GrAtlasManager;
Brian Salomon54d212e2017-03-21 14:22:38 -040017class GrCaps;
Robert Phillipsc4039ea2018-03-01 11:36:45 -050018class GrGlyphCache;
Brian Salomon742e31d2016-12-07 17:06:19 -050019class GrOpFlushState;
bsalomon16b99132015-08-13 14:55:50 -070020
21/**
Brian Salomondad29232016-12-01 16:40:24 -050022 * Base class for mesh-drawing GrDrawOps.
bsalomon16b99132015-08-13 14:55:50 -070023 */
Brian Salomondad29232016-12-01 16:40:24 -050024class GrMeshDrawOp : public GrDrawOp {
bsalomon16b99132015-08-13 14:55:50 -070025public:
Brian Salomon29b60c92017-10-31 14:42:10 -040026 /** Abstract interface that represents a destination for a GrMeshDrawOp. */
bsalomon75398562015-08-17 12:55:38 -070027 class Target;
28
Brian Salomond3ccb0a2017-04-03 10:38:00 -040029protected:
30 GrMeshDrawOp(uint32_t classID);
31
Chris Daltonff926502017-05-03 14:36:54 -040032 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
33 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
34 class PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040035 public:
Brian Salomonb9485722018-08-05 21:30:33 -040036 PatternHelper(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
37 int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040038
Brian Salomonb9485722018-08-05 21:30:33 -040039 /** Called to issue draws to the GrMeshDrawOp::Target.*/
Brian Salomon607be372018-08-03 11:54:34 -040040 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>, const GrPipeline*,
Brian Salomonb9485722018-08-05 21:30:33 -040041 const GrPipeline::FixedDynamicState*) const;
42
43 void* vertices() const { return fVertices; }
44
45 protected:
46 PatternHelper() = default;
47 void init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
48 int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040049
50 private:
Brian Salomonb9485722018-08-05 21:30:33 -040051 void* fVertices = nullptr;
52 GrMesh* fMesh = nullptr;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040053 };
54
55 static const int kVerticesPerQuad = 4;
56 static const int kIndicesPerQuad = 6;
57
58 /** A specialization of InstanceHelper for quad rendering. */
Chris Daltonff926502017-05-03 14:36:54 -040059 class QuadHelper : private PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040060 public:
Brian Salomonb9485722018-08-05 21:30:33 -040061 QuadHelper() = delete;
62 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040063
Chris Daltonff926502017-05-03 14:36:54 -040064 using PatternHelper::recordDraw;
Brian Salomonb9485722018-08-05 21:30:33 -040065 using PatternHelper::vertices;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040066
67 private:
Chris Daltonff926502017-05-03 14:36:54 -040068 typedef PatternHelper INHERITED;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040069 };
70
71private:
72 void onPrepare(GrOpFlushState* state) final;
73 void onExecute(GrOpFlushState* state) final;
Brian Salomon91326c32017-08-09 16:02:19 -040074 virtual void onPrepareDraws(Target*) = 0;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040075 typedef GrDrawOp INHERITED;
76};
77
Brian Salomon29b60c92017-10-31 14:42:10 -040078class GrMeshDrawOp::Target {
79public:
80 virtual ~Target() {}
81
82 /** Adds a draw of a mesh. */
Brian Salomonb9485722018-08-05 21:30:33 -040083 virtual void draw(sk_sp<const GrGeometryProcessor>,
84 const GrPipeline*,
85 const GrPipeline::FixedDynamicState*,
86 const GrMesh[],
87 int meshCount) = 0;
88
89 /** Helper for drawing a single GrMesh. */
90 void draw(sk_sp<const GrGeometryProcessor> gp,
91 const GrPipeline* pipeline,
92 const GrPipeline::FixedDynamicState* fixedDynamicState,
93 const GrMesh* mesh) {
94 this->draw(std::move(gp), pipeline, fixedDynamicState, mesh, 1);
95 }
Brian Salomon29b60c92017-10-31 14:42:10 -040096
97 /**
98 * Makes space for vertex data. The returned pointer is the location where vertex data
99 * should be written. On return the buffer that will hold the data as well as an offset into
100 * the buffer (in 'vertexSize' units) where the data will be placed.
101 */
102 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**,
103 int* startVertex) = 0;
104
105 /**
106 * Makes space for index data. The returned pointer is the location where index data
107 * should be written. On return the buffer that will hold the data as well as an offset into
108 * the buffer (in uint16_t units) where the data will be placed.
109 */
110 virtual uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) = 0;
111
112 /**
113 * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
114 * vertices in the returned pointer, which may exceed 'minVertexCount'.
115 * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
116 * buffer is allocated on behalf of this request.
117 */
118 virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
119 int fallbackVertexCount, const GrBuffer**,
120 int* startVertex, int* actualVertexCount) = 0;
121
122 /**
123 * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
124 * indices in the returned pointer, which may exceed 'minIndexCount'.
125 * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
126 * buffer is allocated on behalf of this request.
127 */
128 virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
129 const GrBuffer**, int* startIndex,
130 int* actualIndexCount) = 0;
131
132 /** Helpers for ops which over-allocate and then return excess data to the pool. */
133 virtual void putBackIndices(int indices) = 0;
134 virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
135
136 /**
137 * Allocate space for a pipeline. The target ensures this pipeline lifetime is at least
138 * as long as any deferred execution of draws added via draw().
139 * @tparam Args
140 * @param args
141 * @return
142 */
143 template <typename... Args>
144 GrPipeline* allocPipeline(Args&&... args) {
145 return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...);
146 }
147
Brian Salomonb9485722018-08-05 21:30:33 -0400148 GrMesh* allocMesh(GrPrimitiveType primitiveType) {
149 return this->pipelineArena()->make<GrMesh>(primitiveType);
150 }
151
152 GrMesh* allocMeshes(int n) { return this->pipelineArena()->makeArray<GrMesh>(n); }
153
Brian Salomonaf874832018-08-03 11:53:40 -0400154 GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect,
155 int numPrimitiveProcessorTextures = 0) {
156 auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect);
157 if (numPrimitiveProcessorTextures) {
158 result->fPrimitiveProcessorTextures =
159 this->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorTextures);
160 }
161 return result;
162 }
163
164 GrTextureProxy** allocPrimitiveProcessorTextureArray(int n) {
165 SkASSERT(n > 0);
166 return this->pipelineArena()->makeArrayDefault<GrTextureProxy*>(n);
Brian Salomon49348902018-06-26 09:12:38 -0400167 }
168
169 // Once we have C++17 structured bindings make this just be a tuple because then we can do:
170 // auto [pipeline, fixedDynamicState] = target->makePipeline(...);
171 // in addition to:
172 // std::tie(flushInfo.fPipeline, flushInfo.fFixedState) = target->makePipeline(...);
173 struct PipelineAndFixedDynamicState {
174 const GrPipeline* fPipeline;
Brian Salomonaf874832018-08-03 11:53:40 -0400175 GrPipeline::FixedDynamicState* fFixedDynamicState;
Brian Salomon49348902018-06-26 09:12:38 -0400176 };
177
Brian Salomon29b60c92017-10-31 14:42:10 -0400178 /**
179 * Helper that makes a pipeline targeting the op's render target that incorporates the op's
Brian Salomon49348902018-06-26 09:12:38 -0400180 * GrAppliedClip and uses a fixed dynamic state.
Brian Salomon7dc6e752017-11-02 11:34:51 -0400181 */
Brian Salomonf5136822018-08-03 09:09:36 -0400182 PipelineAndFixedDynamicState makePipeline(uint32_t pipelineFlags, GrProcessorSet&&,
Brian Salomonaf874832018-08-03 11:53:40 -0400183 GrAppliedClip&&,
184 int numPrimitiveProcessorTextures = 0);
Brian Salomon29b60c92017-10-31 14:42:10 -0400185
186 virtual GrRenderTargetProxy* proxy() const = 0;
187
188 virtual GrAppliedClip detachAppliedClip() = 0;
189
190 virtual const GrXferProcessor::DstProxy& dstProxy() const = 0;
191
192 virtual GrResourceProvider* resourceProvider() const = 0;
Brian Salomon238069b2018-07-11 15:58:57 -0400193 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
Brian Salomon29b60c92017-10-31 14:42:10 -0400194
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500195 virtual GrGlyphCache* glyphCache() const = 0;
Robert Phillips5a66efb2018-03-07 15:13:18 -0500196 virtual GrAtlasManager* atlasManager() const = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500197
Brian Salomon29b60c92017-10-31 14:42:10 -0400198 virtual const GrCaps& caps() const = 0;
199
200 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
201
202private:
203 virtual SkArenaAlloc* pipelineArena() = 0;
204};
205
bsalomon16b99132015-08-13 14:55:50 -0700206#endif