blob: 34653be818b01ee16b25dd5ec4f58f539166b11d [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
Robert Phillips03e4c952019-11-26 16:20:22 -050011#include "src/core/SkArenaAlloc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "src/gpu/GrAppliedClip.h"
13#include "src/gpu/GrGeometryProcessor.h"
Chris Daltoneb694b72020-03-16 09:25:50 -060014#include "src/gpu/GrSimpleMesh.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/gpu/ops/GrDrawOp.h"
Brian Osman7d8f82b2018-11-08 10:24:09 -050016#include <type_traits>
bsalomon75398562015-08-17 12:55:38 -070017
Robert Phillipsc4039ea2018-03-01 11:36:45 -050018class GrAtlasManager;
Brian Salomon54d212e2017-03-21 14:22:38 -040019class GrCaps;
Herb Derby081e6f32019-01-16 13:46:02 -050020class GrStrikeCache;
Brian Salomon742e31d2016-12-07 17:06:19 -050021class GrOpFlushState;
bsalomon16b99132015-08-13 14:55:50 -070022
23/**
Brian Salomondad29232016-12-01 16:40:24 -050024 * Base class for mesh-drawing GrDrawOps.
bsalomon16b99132015-08-13 14:55:50 -070025 */
Brian Salomondad29232016-12-01 16:40:24 -050026class GrMeshDrawOp : public GrDrawOp {
bsalomon16b99132015-08-13 14:55:50 -070027public:
Brian Salomon29b60c92017-10-31 14:42:10 -040028 /** Abstract interface that represents a destination for a GrMeshDrawOp. */
bsalomon75398562015-08-17 12:55:38 -070029 class Target;
30
Robert Phillipsbbd459d2019-10-29 14:40:03 -040031 static bool CanUpgradeAAOnMerge(GrAAType aa1, GrAAType aa2) {
32 return (aa1 == GrAAType::kNone && aa2 == GrAAType::kCoverage) ||
33 (aa1 == GrAAType::kCoverage && aa2 == GrAAType::kNone);
34 }
35
Brian Salomond3ccb0a2017-04-03 10:38:00 -040036protected:
37 GrMeshDrawOp(uint32_t classID);
38
Robert Phillips4133dc42020-03-11 15:55:55 -040039 void createProgramInfo(const GrCaps* caps,
40 SkArenaAlloc* arena,
Brian Salomon8afde5f2020-04-01 16:22:00 -040041 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -040042 GrAppliedClip&& appliedClip,
43 const GrXferProcessor::DstProxyView& dstProxyView) {
Brian Salomon8afde5f2020-04-01 16:22:00 -040044 this->onCreateProgramInfo(caps, arena, writeView, std::move(appliedClip), dstProxyView);
Robert Phillips4133dc42020-03-11 15:55:55 -040045 }
46
47 void createProgramInfo(Target* target);
48
Chris Daltonff926502017-05-03 14:36:54 -040049 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
50 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
51 class PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040052 public:
Brian Salomondbf70722019-02-07 11:31:24 -050053 PatternHelper(Target*, GrPrimitiveType, size_t vertexStride,
54 sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition,
Robert Phillipsee08d522019-10-28 16:34:44 -040055 int indicesPerRepetition, int repeatCount, int maxRepetitions);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040056
Brian Salomon7eae3e02018-08-07 14:02:38 +000057 /** Called to issue draws to the GrMeshDrawOp::Target.*/
Robert Phillips7cd0bfe2019-11-20 16:08:10 -050058 void recordDraw(Target*, const GrGeometryProcessor*) const;
59 void recordDraw(Target*, const GrGeometryProcessor*,
Chris Dalton304e14d2020-03-17 14:29:06 -060060 const GrSurfaceProxy* const primProcProxies[]) const;
Brian Salomon7eae3e02018-08-07 14:02:38 +000061
62 void* vertices() const { return fVertices; }
Chris Daltoneb694b72020-03-16 09:25:50 -060063 GrSimpleMesh* mesh() { return fMesh; }
Brian Salomon7eae3e02018-08-07 14:02:38 +000064
65 protected:
66 PatternHelper() = default;
Brian Salomondbf70722019-02-07 11:31:24 -050067 void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
Robert Phillipsee08d522019-10-28 16:34:44 -040068 int verticesPerRepetition, int indicesPerRepetition, int repeatCount,
69 int maxRepetitions);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040070
71 private:
Brian Salomon7eae3e02018-08-07 14:02:38 +000072 void* fVertices = nullptr;
Chris Daltoneb694b72020-03-16 09:25:50 -060073 GrSimpleMesh* fMesh = nullptr;
Robert Phillipscea290f2019-11-06 11:21:03 -050074 GrPrimitiveType fPrimitiveType;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040075 };
76
Robert Phillipse94cdd22019-11-04 14:15:58 -050077 /** A specialization of InstanceHelper for quad rendering.
78 * It only draws non-antialiased indexed quads.
79 */
Chris Daltonff926502017-05-03 14:36:54 -040080 class QuadHelper : private PatternHelper {
Brian Salomond3ccb0a2017-04-03 10:38:00 -040081 public:
Brian Salomon7eae3e02018-08-07 14:02:38 +000082 QuadHelper() = delete;
83 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
Brian Salomond3ccb0a2017-04-03 10:38:00 -040084
Robert Phillipsce978572020-02-28 11:56:44 -050085 using PatternHelper::mesh;
Chris Daltonff926502017-05-03 14:36:54 -040086 using PatternHelper::recordDraw;
Brian Salomon7eae3e02018-08-07 14:02:38 +000087 using PatternHelper::vertices;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040088
89 private:
Chris Daltonff926502017-05-03 14:36:54 -040090 typedef PatternHelper INHERITED;
Brian Salomond3ccb0a2017-04-03 10:38:00 -040091 };
92
Robert Phillipsbbd459d2019-10-29 14:40:03 -040093 static bool CombinedQuadCountWillOverflow(GrAAType aaType,
94 bool willBeUpgradedToAA,
95 int combinedQuadCount) {
96 bool willBeAA = (aaType == GrAAType::kCoverage) || willBeUpgradedToAA;
97
98 return combinedQuadCount > (willBeAA ? GrResourceProvider::MaxNumAAQuads()
99 : GrResourceProvider::MaxNumNonAAQuads());
100 }
101
Chris Daltondbb833b2020-03-17 12:15:46 -0600102 virtual void onPrePrepareDraws(GrRecordingContext*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400103 const GrSurfaceProxyView* writeView,
Chris Daltondbb833b2020-03-17 12:15:46 -0600104 GrAppliedClip*,
105 const GrXferProcessor::DstProxyView&);
106
Brian Salomond3ccb0a2017-04-03 10:38:00 -0400107private:
Robert Phillips2669a7b2020-03-12 12:07:19 -0400108 virtual GrProgramInfo* programInfo() = 0;
Robert Phillips4133dc42020-03-11 15:55:55 -0400109 // This method is responsible for creating all the programInfos required
110 // by this op.
111 virtual void onCreateProgramInfo(const GrCaps*,
112 SkArenaAlloc*,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400113 const GrSurfaceProxyView* writeView,
Robert Phillips4133dc42020-03-11 15:55:55 -0400114 GrAppliedClip&&,
115 const GrXferProcessor::DstProxyView&) = 0;
116
Robert Phillipsdf70f152019-11-15 14:57:05 -0500117 void onPrePrepare(GrRecordingContext* context,
Brian Salomon8afde5f2020-04-01 16:22:00 -0400118 const GrSurfaceProxyView* writeView,
Robert Phillips8053c972019-11-21 10:44:53 -0500119 GrAppliedClip* clip,
120 const GrXferProcessor::DstProxyView& dstProxyView) final {
Brian Salomon8afde5f2020-04-01 16:22:00 -0400121 this->onPrePrepareDraws(context, writeView, clip, dstProxyView);
Robert Phillips61fc7992019-10-22 11:58:17 -0400122 }
Brian Salomond3ccb0a2017-04-03 10:38:00 -0400123 void onPrepare(GrOpFlushState* state) final;
Robert Phillips7327c9d2019-10-08 16:32:56 -0400124
Brian Salomon91326c32017-08-09 16:02:19 -0400125 virtual void onPrepareDraws(Target*) = 0;
Brian Salomond3ccb0a2017-04-03 10:38:00 -0400126 typedef GrDrawOp INHERITED;
127};
128
Brian Salomon29b60c92017-10-31 14:42:10 -0400129class GrMeshDrawOp::Target {
130public:
131 virtual ~Target() {}
132
Chris Dalton304e14d2020-03-17 14:29:06 -0600133 /** Adds a draw of a mesh. 'primProcProxies' must have
134 * GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers.
135 */
Robert Phillips6c59fe42020-02-27 09:30:37 -0500136 virtual void recordDraw(const GrGeometryProcessor*,
Chris Daltoneb694b72020-03-16 09:25:50 -0600137 const GrSimpleMesh[],
Robert Phillips6c59fe42020-02-27 09:30:37 -0500138 int meshCnt,
Chris Dalton304e14d2020-03-17 14:29:06 -0600139 const GrSurfaceProxy* const primProcProxies[],
Robert Phillips6c59fe42020-02-27 09:30:37 -0500140 GrPrimitiveType) = 0;
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700141
142 /**
Chris Dalton304e14d2020-03-17 14:29:06 -0600143 * Helper for drawing GrSimpleMesh(es) with zero primProc textures.
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700144 */
Robert Phillips6c59fe42020-02-27 09:30:37 -0500145 void recordDraw(const GrGeometryProcessor* gp,
Chris Daltoneb694b72020-03-16 09:25:50 -0600146 const GrSimpleMesh meshes[],
Robert Phillips6c59fe42020-02-27 09:30:37 -0500147 int meshCnt,
Robert Phillipscea290f2019-11-06 11:21:03 -0500148 GrPrimitiveType primitiveType) {
Chris Dalton304e14d2020-03-17 14:29:06 -0600149 this->recordDraw(gp, meshes, meshCnt, nullptr, primitiveType);
Brian Salomon7eae3e02018-08-07 14:02:38 +0000150 }
Brian Salomon29b60c92017-10-31 14:42:10 -0400151
152 /**
153 * Makes space for vertex data. The returned pointer is the location where vertex data
154 * should be written. On return the buffer that will hold the data as well as an offset into
155 * the buffer (in 'vertexSize' units) where the data will be placed.
156 */
Brian Salomon12d22642019-01-29 14:38:50 -0500157 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
Brian Salomon29b60c92017-10-31 14:42:10 -0400158 int* startVertex) = 0;
159
160 /**
161 * Makes space for index data. The returned pointer is the location where index data
162 * should be written. On return the buffer that will hold the data as well as an offset into
163 * the buffer (in uint16_t units) where the data will be placed.
164 */
Brian Salomon12d22642019-01-29 14:38:50 -0500165 virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400166
167 /**
168 * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount'
169 * vertices in the returned pointer, which may exceed 'minVertexCount'.
170 * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new
171 * buffer is allocated on behalf of this request.
172 */
173 virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500174 int fallbackVertexCount, sk_sp<const GrBuffer>*,
Brian Salomon29b60c92017-10-31 14:42:10 -0400175 int* startVertex, int* actualVertexCount) = 0;
176
177 /**
178 * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount'
179 * indices in the returned pointer, which may exceed 'minIndexCount'.
180 * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new
181 * buffer is allocated on behalf of this request.
182 */
183 virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500184 sk_sp<const GrBuffer>*, int* startIndex,
Brian Salomon29b60c92017-10-31 14:42:10 -0400185 int* actualIndexCount) = 0;
186
187 /** Helpers for ops which over-allocate and then return excess data to the pool. */
188 virtual void putBackIndices(int indices) = 0;
189 virtual void putBackVertices(int vertices, size_t vertexStride) = 0;
190
Chris Daltoneb694b72020-03-16 09:25:50 -0600191 GrSimpleMesh* allocMesh() { return this->allocator()->make<GrSimpleMesh>(); }
192 GrSimpleMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrSimpleMesh>(n); }
Chris Dalton304e14d2020-03-17 14:29:06 -0600193 const GrSurfaceProxy** allocPrimProcProxyPtrs(int n) {
194 return this->allocator()->makeArray<const GrSurfaceProxy*>(n);
Robert Phillips61fc7992019-10-22 11:58:17 -0400195 }
Brian Salomon29b60c92017-10-31 14:42:10 -0400196
197 virtual GrRenderTargetProxy* proxy() const = 0;
Brian Salomon8afde5f2020-04-01 16:22:00 -0400198 virtual const GrSurfaceProxyView* writeView() const = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400199
Robert Phillips8053c972019-11-21 10:44:53 -0500200 virtual const GrAppliedClip* appliedClip() const = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400201 virtual GrAppliedClip detachAppliedClip() = 0;
202
Greg Daniel524e28b2019-11-01 11:48:53 -0400203 virtual const GrXferProcessor::DstProxyView& dstProxyView() const = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400204
205 virtual GrResourceProvider* resourceProvider() const = 0;
Brian Salomon238069b2018-07-11 15:58:57 -0400206 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); }
Brian Salomon29b60c92017-10-31 14:42:10 -0400207
Herb Derby081e6f32019-01-16 13:46:02 -0500208 virtual GrStrikeCache* glyphCache() const = 0;
Robert Phillips5a66efb2018-03-07 15:13:18 -0500209 virtual GrAtlasManager* atlasManager() const = 0;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500210
Greg Danielb20d7e52019-09-03 13:54:39 -0400211 // This should be called during onPrepare of a GrOp. The caller should add any proxies to the
212 // array it will use that it did not access during a call to visitProxies. This is usually the
213 // case for atlases.
Michael Ludwigfcdd0612019-11-25 08:34:31 -0500214 virtual SkTArray<GrSurfaceProxy*, true>* sampledProxyArray() = 0;
Greg Danielb20d7e52019-09-03 13:54:39 -0400215
Brian Salomon29b60c92017-10-31 14:42:10 -0400216 virtual const GrCaps& caps() const = 0;
217
218 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0;
219
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700220 virtual SkArenaAlloc* allocator() = 0;
Brian Salomon29b60c92017-10-31 14:42:10 -0400221};
222
bsalomon16b99132015-08-13 14:55:50 -0700223#endif