blob: 170fee0e854bcd1d27a37ade49e10015353299c1 [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"
Brian Osman7d8f82b2018-11-08 10:24:09 -050015#include <type_traits>
bsalomon75398562015-08-17 12:55:38 -070016
Robert Phillipsc4039ea2018-03-01 11:36:45 -050017class GrAtlasManager;
Brian Salomon54d212e2017-03-21 14:22:38 -040018class GrCaps;
Herb Derby081e6f32019-01-16 13:46:02 -050019class GrStrikeCache;
Brian Salomon742e31d2016-12-07 17:06:19 -050020class GrOpFlushState;
bsalomon16b99132015-08-13 14:55:50 -070021
22/**
Brian Salomondad29232016-12-01 16:40:24 -050023 * Base class for mesh-drawing GrDrawOps.
bsalomon16b99132015-08-13 14:55:50 -070024 */
Brian Salomondad29232016-12-01 16:40:24 -050025class GrMeshDrawOp : public GrDrawOp {
bsalomon16b99132015-08-13 14:55:50 -070026public:
Brian Salomon29b60c92017-10-31 14:42:10 -040027 /** Abstract interface that represents a destination for a GrMeshDrawOp. */
bsalomon75398562015-08-17 12:55:38 -070028 class Target;
29
Brian Salomond3ccb0a2017-04-03 10:38:00 -040030protected:
31 GrMeshDrawOp(uint32_t classID);
32
Chris Daltonff926502017-05-03 14:36:54 -040033 /** 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 {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040036 public:
Brian Salomondbf70722019-02-07 11:31:24 -050037 PatternHelper(Target*, GrPrimitiveType, size_t vertexStride,
38 sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition,
39 int indicesPerRepetition, int repeatCount);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040040
Brian Salomon7eae3e02018-08-07 14:02:38 +000041 /** Called to issue draws to the GrMeshDrawOp::Target.*/
42 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>, const GrPipeline*,
43 const GrPipeline::FixedDynamicState*) const;
44
45 void* vertices() const { return fVertices; }
46
47 protected:
48 PatternHelper() = default;
Brian Salomondbf70722019-02-07 11:31:24 -050049 void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
Brian Salomon7eae3e02018-08-07 14:02:38 +000050 int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040051
52 private:
Brian Salomon7eae3e02018-08-07 14:02:38 +000053 void* fVertices = nullptr;
54 GrMesh* fMesh = nullptr;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040055 };
56
57 static const int kVerticesPerQuad = 4;
58 static const int kIndicesPerQuad = 6;
59
60 /** A specialization of InstanceHelper for quad rendering. */
Chris Daltonff926502017-05-03 14:36:54 -040061 class QuadHelper : private PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040062 public:
Brian Salomon7eae3e02018-08-07 14:02:38 +000063 QuadHelper() = delete;
64 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040065
Chris Daltonff926502017-05-03 14:36:54 -040066 using PatternHelper::recordDraw;
Brian Salomon7eae3e02018-08-07 14:02:38 +000067 using PatternHelper::vertices;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040068
69 private:
Chris Daltonff926502017-05-03 14:36:54 -040070 typedef PatternHelper INHERITED;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040071 };
72
73private:
74 void onPrepare(GrOpFlushState* state) final;
Brian Salomon588cec72018-11-14 13:56:37 -050075 void onExecute(GrOpFlushState* state, const SkRect& chainBounds) final;
Brian Salomon91326c32017-08-09 16:02:19 -040076 virtual void onPrepareDraws(Target*) = 0;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040077 typedef GrDrawOp INHERITED;
78};
79
Brian Salomon29b60c92017-10-31 14:42:10 -040080class GrMeshDrawOp::Target {
81public:
82 virtual ~Target() {}
83
84 /** Adds a draw of a mesh. */
Brian Salomon7eae3e02018-08-07 14:02:38 +000085 virtual void draw(sk_sp<const GrGeometryProcessor>,
86 const GrPipeline*,
87 const GrPipeline::FixedDynamicState*,
Brian Salomonf7232642018-09-19 08:58:08 -040088 const GrPipeline::DynamicStateArrays*,
Brian Salomon7eae3e02018-08-07 14:02:38 +000089 const GrMesh[],
90 int meshCount) = 0;
Brian Salomon7eae3e02018-08-07 14:02:38 +000091 /** Helper for drawing a single GrMesh. */
92 void draw(sk_sp<const GrGeometryProcessor> gp,
93 const GrPipeline* pipeline,
94 const GrPipeline::FixedDynamicState* fixedDynamicState,
95 const GrMesh* mesh) {
Brian Salomonf7232642018-09-19 08:58:08 -040096 this->draw(std::move(gp), pipeline, fixedDynamicState, nullptr, mesh, 1);
Brian Salomon7eae3e02018-08-07 14:02:38 +000097 }
Brian Salomon29b60c92017-10-31 14:42:10 -040098
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 */
Brian Salomon12d22642019-01-29 14:38:50 -0500104 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
Brian Salomon29b60c92017-10-31 14:42:10 -0400105 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 */
Brian Salomon12d22642019-01-29 14:38:50 -0500112 virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400113
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,
Brian Salomon12d22642019-01-29 14:38:50 -0500121 int fallbackVertexCount, sk_sp<const GrBuffer>*,
Brian Salomon29b60c92017-10-31 14:42:10 -0400122 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,
Brian Salomon12d22642019-01-29 14:38:50 -0500131 sk_sp<const GrBuffer>*, int* startIndex,
Brian Salomon29b60c92017-10-31 14:42:10 -0400132 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
138 /**
139 * Allocate space for a pipeline. The target ensures this pipeline lifetime is at least
140 * as long as any deferred execution of draws added via draw().
141 * @tparam Args
142 * @param args
143 * @return
144 */
145 template <typename... Args>
146 GrPipeline* allocPipeline(Args&&... args) {
147 return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...);
148 }
149
Brian Salomon7eae3e02018-08-07 14:02:38 +0000150 GrMesh* allocMesh(GrPrimitiveType primitiveType) {
151 return this->pipelineArena()->make<GrMesh>(primitiveType);
152 }
153
154 GrMesh* allocMeshes(int n) { return this->pipelineArena()->makeArray<GrMesh>(n); }
155
156 GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect,
Brian Salomonf7232642018-09-19 08:58:08 -0400157 int numPrimitiveProcessorTextures = 0);
158
159 GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes,
160 int numPrimitiveProcessorTextures,
161 bool allocScissors);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000162
163 GrTextureProxy** allocPrimitiveProcessorTextureArray(int n) {
164 SkASSERT(n > 0);
165 return this->pipelineArena()->makeArrayDefault<GrTextureProxy*>(n);
Brian Salomon49348902018-06-26 09:12:38 -0400166 }
167
168 // Once we have C++17 structured bindings make this just be a tuple because then we can do:
169 // auto [pipeline, fixedDynamicState] = target->makePipeline(...);
170 // in addition to:
171 // std::tie(flushInfo.fPipeline, flushInfo.fFixedState) = target->makePipeline(...);
172 struct PipelineAndFixedDynamicState {
173 const GrPipeline* fPipeline;
Brian Salomon7eae3e02018-08-07 14:02:38 +0000174 GrPipeline::FixedDynamicState* fFixedDynamicState;
Brian Salomon49348902018-06-26 09:12:38 -0400175 };
176
Brian Salomon29b60c92017-10-31 14:42:10 -0400177 /**
178 * Helper that makes a pipeline targeting the op's render target that incorporates the op's
Brian Salomon49348902018-06-26 09:12:38 -0400179 * GrAppliedClip and uses a fixed dynamic state.
Brian Salomon7dc6e752017-11-02 11:34:51 -0400180 */
Brian Salomonf5136822018-08-03 09:09:36 -0400181 PipelineAndFixedDynamicState makePipeline(uint32_t pipelineFlags, GrProcessorSet&&,
Brian Salomon7eae3e02018-08-07 14:02:38 +0000182 GrAppliedClip&&,
183 int numPrimitiveProcessorTextures = 0);
Brian Salomon29b60c92017-10-31 14:42:10 -0400184
185 virtual GrRenderTargetProxy* proxy() const = 0;
186
187 virtual GrAppliedClip detachAppliedClip() = 0;
188
189 virtual const GrXferProcessor::DstProxy& dstProxy() const = 0;
190
191 virtual GrResourceProvider* resourceProvider() const = 0;
Brian Salomon238069b2018-07-11 15:58:57 -0400192 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
Brian Salomon29b60c92017-10-31 14:42:10 -0400193
Herb Derby081e6f32019-01-16 13:46:02 -0500194 virtual GrStrikeCache* glyphCache() const = 0;
Robert Phillips5a66efb2018-03-07 15:13:18 -0500195 virtual GrAtlasManager* atlasManager() const = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500196
Brian Salomon29b60c92017-10-31 14:42:10 -0400197 virtual const GrCaps& caps() const = 0;
198
199 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
200
201private:
202 virtual SkArenaAlloc* pipelineArena() = 0;
203};
204
bsalomon16b99132015-08-13 14:55:50 -0700205#endif