blob: 5baf9852849b0a82717e891e2d9dbffcf3e53bf8 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/gpu/GrAppliedClip.h"
12#include "src/gpu/GrGeometryProcessor.h"
13#include "src/gpu/GrMesh.h"
14#include "src/gpu/ops/GrDrawOp.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.*/
Chris Dalton07cdcfc92019-02-26 11:13:22 -070042 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>) const;
43 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>,
Brian Salomon7eae3e02018-08-07 14:02:38 +000044 const GrPipeline::FixedDynamicState*) const;
45
46 void* vertices() const { return fVertices; }
47
48 protected:
49 PatternHelper() = default;
Brian Salomondbf70722019-02-07 11:31:24 -050050 void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
Brian Salomon7eae3e02018-08-07 14:02:38 +000051 int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040052
53 private:
Brian Salomon7eae3e02018-08-07 14:02:38 +000054 void* fVertices = nullptr;
55 GrMesh* fMesh = nullptr;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040056 };
57
58 static const int kVerticesPerQuad = 4;
59 static const int kIndicesPerQuad = 6;
60
61 /** A specialization of InstanceHelper for quad rendering. */
Chris Daltonff926502017-05-03 14:36:54 -040062 class QuadHelper : private PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040063 public:
Brian Salomon7eae3e02018-08-07 14:02:38 +000064 QuadHelper() = delete;
65 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040066
Chris Daltonff926502017-05-03 14:36:54 -040067 using PatternHelper::recordDraw;
Brian Salomon7eae3e02018-08-07 14:02:38 +000068 using PatternHelper::vertices;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040069
70 private:
Chris Daltonff926502017-05-03 14:36:54 -040071 typedef PatternHelper INHERITED;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040072 };
73
74private:
75 void onPrepare(GrOpFlushState* state) 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. */
Chris Dalton07cdcfc92019-02-26 11:13:22 -070085 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);
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
Chris Dalton35a3abe2019-02-25 23:11:33 +0000138 GrMesh* allocMesh(GrPrimitiveType primitiveType) {
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700139 return this->allocator()->make<GrMesh>(primitiveType);
Chris Dalton35a3abe2019-02-25 23:11:33 +0000140 }
141
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700142 GrMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrMesh>(n); }
Brian Salomonf7232642018-09-19 08:58:08 -0400143
144 GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes,
145 int numPrimitiveProcessorTextures,
146 bool allocScissors);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000147
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700148 GrPipeline::FixedDynamicState* makeFixedDynamicState(int numPrimitiveProcessorTextures);
Brian Salomon29b60c92017-10-31 14:42:10 -0400149
150 virtual GrRenderTargetProxy* proxy() const = 0;
151
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700152 virtual const GrAppliedClip* appliedClip() = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400153 virtual GrAppliedClip detachAppliedClip() = 0;
154
155 virtual const GrXferProcessor::DstProxy& dstProxy() const = 0;
156
157 virtual GrResourceProvider* resourceProvider() const = 0;
Brian Salomon238069b2018-07-11 15:58:57 -0400158 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
Brian Salomon29b60c92017-10-31 14:42:10 -0400159
Herb Derby081e6f32019-01-16 13:46:02 -0500160 virtual GrStrikeCache* glyphCache() const = 0;
Robert Phillips5a66efb2018-03-07 15:13:18 -0500161 virtual GrAtlasManager* atlasManager() const = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500162
Greg Danielb20d7e52019-09-03 13:54:39 -0400163 // This should be called during onPrepare of a GrOp. The caller should add any proxies to the
164 // array it will use that it did not access during a call to visitProxies. This is usually the
165 // case for atlases.
166 virtual SkTArray<GrTextureProxy*, true>* sampledProxyArray() = 0;
167
Brian Salomon29b60c92017-10-31 14:42:10 -0400168 virtual const GrCaps& caps() const = 0;
169
170 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
171
172private:
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700173 virtual SkArenaAlloc* allocator() = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400174};
175
bsalomon16b99132015-08-13 14:55:50 -0700176#endif