blob: ed8a39ce075f46e7fc6cf44fbad5032a321521ce [file] [log] [blame]
bsalomon75398562015-08-17 12:55:38 -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 Salomon09d994e2016-12-21 11:14:46 -05008#ifndef GrOpFlushState_DEFINED
9#define GrOpFlushState_DEFINED
bsalomon75398562015-08-17 12:55:38 -070010
Brian Salomon7dc6e752017-11-02 11:34:51 -040011#include <utility>
Ben Wagner729a23f2019-05-17 16:29:34 -040012#include "src/core/SkArenaAlloc.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "src/core/SkArenaAllocList.h"
14#include "src/gpu/GrAppliedClip.h"
15#include "src/gpu/GrBufferAllocPool.h"
16#include "src/gpu/GrDeferredUpload.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040017#include "src/gpu/GrRenderTargetProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050018#include "src/gpu/ops/GrMeshDrawOp.h"
bsalomon75398562015-08-17 12:55:38 -070019
Robert Phillips646e4292017-06-13 12:44:56 -040020class GrGpu;
Greg Daniel2d41d0d2019-08-26 11:08:51 -040021class GrOpsRenderPass;
bsalomon75398562015-08-17 12:55:38 -070022class GrResourceProvider;
23
Greg Danielf41b2bd2019-08-22 16:19:24 -040024/** Tracks the state across all the GrOps (really just the GrDrawOps) in a GrOpsTask flush. */
Brian Salomon29b60c92017-10-31 14:42:10 -040025class GrOpFlushState final : public GrDeferredUploadTarget, public GrMeshDrawOp::Target {
bsalomon75398562015-08-17 12:55:38 -070026public:
Brian Salomon58f153c2018-10-18 21:51:15 -040027 // vertexSpace and indexSpace may either be null or an alloation of size
28 // GrBufferAllocPool::kDefaultBufferSize. If the latter, then CPU memory is only allocated for
29 // vertices/indices when a buffer larger than kDefaultBufferSize is required.
Robert Phillipse5f73282019-06-18 17:15:04 -040030 GrOpFlushState(GrGpu*, GrResourceProvider*, GrTokenTracker*,
Brian Salomon601ac802019-02-07 13:37:16 -050031 sk_sp<GrBufferAllocPool::CpuBufferCache> = nullptr);
bsalomon75398562015-08-17 12:55:38 -070032
Brian Salomon29b60c92017-10-31 14:42:10 -040033 ~GrOpFlushState() final { this->reset(); }
bsalomon75398562015-08-17 12:55:38 -070034
Brian Salomon742e31d2016-12-07 17:06:19 -050035 /** This is called after each op has a chance to prepare its draws and before the draws are
Brian Salomon7dc6e752017-11-02 11:34:51 -040036 executed. */
37 void preExecuteDraws();
bsalomon75398562015-08-17 12:55:38 -070038
Greg Danielb20d7e52019-09-03 13:54:39 -040039 /** Called to upload data to a texture using the GrDeferredTextureUploadFn. If the uploaded
40 surface needs to be prepared for being sampled in a draw after the upload, the caller
41 should pass in true for shouldPrepareSurfaceForSampling. This feature is needed for Vulkan
42 when doing inline uploads to reset the image layout back to sampled. */
43 void doUpload(GrDeferredTextureUploadFn&, bool shouldPrepareSurfaceForSampling = false);
bsalomon342bfc22016-04-01 06:06:20 -070044
Brian Salomon7dc6e752017-11-02 11:34:51 -040045 /** Called as ops are executed. Must be called in the same order as the ops were prepared. */
Chris Dalton07cdcfc92019-02-26 11:13:22 -070046 void executeDrawsAndUploadsForMeshDrawOp(
Chris Daltonbaa1b352019-04-03 12:03:00 -060047 const GrOp* op, const SkRect& chainBounds, GrProcessorSet&&,
48 GrPipeline::InputFlags = GrPipeline::InputFlags::kNone,
Chris Dalton07cdcfc92019-02-26 11:13:22 -070049 const GrUserStencilSettings* = &GrUserStencilSettings::kUnused);
Brian Salomon7dc6e752017-11-02 11:34:51 -040050
Greg Daniel2d41d0d2019-08-26 11:08:51 -040051 GrOpsRenderPass* opsRenderPass() { return fOpsRenderPass; }
52 void setOpsRenderPass(GrOpsRenderPass* renderPass) { fOpsRenderPass = renderPass; }
egdaniel9cb63402016-06-23 08:37:05 -070053
bsalomon75398562015-08-17 12:55:38 -070054 GrGpu* gpu() { return fGpu; }
55
Brian Salomon7dc6e752017-11-02 11:34:51 -040056 void reset();
joshualittf6d259b2015-10-02 11:27:14 -070057
Brian Salomon29b60c92017-10-31 14:42:10 -040058 /** Additional data required on a per-op basis when executing GrOps. */
59 struct OpArgs {
Robert Phillipsd0fe8752019-01-31 14:13:59 -050060 GrSurfaceOrigin origin() const { return fProxy->origin(); }
Brian Salomonfd98c2c2018-07-31 17:25:29 -040061 GrRenderTarget* renderTarget() const { return fProxy->peekRenderTarget(); }
Robert Phillips2890fbf2017-07-26 15:48:41 -040062
Brian Salomon29b60c92017-10-31 14:42:10 -040063 GrOp* fOp;
Robert Phillips19e51dc2017-08-09 09:30:51 -040064 // TODO: do we still need the dst proxy here?
Brian Salomonbfd18cd2017-08-09 16:27:09 -040065 GrRenderTargetProxy* fProxy;
66 GrAppliedClip* fAppliedClip;
Greg Daniel2c3398d2019-06-19 11:58:01 -040067 GrSwizzle fOutputSwizzle;
Robert Phillipsbb581ce2017-05-29 15:05:15 -040068 GrXferProcessor::DstProxy fDstProxy;
Brian Salomon54d212e2017-03-21 14:22:38 -040069 };
70
Brian Salomon29b60c92017-10-31 14:42:10 -040071 void setOpArgs(OpArgs* opArgs) { fOpArgs = opArgs; }
Brian Salomon54d212e2017-03-21 14:22:38 -040072
Brian Salomon29b60c92017-10-31 14:42:10 -040073 const OpArgs& drawOpArgs() const {
Brian Salomon54d212e2017-03-21 14:22:38 -040074 SkASSERT(fOpArgs);
Brian Salomon29b60c92017-10-31 14:42:10 -040075 SkASSERT(fOpArgs->fOp);
Brian Salomon54d212e2017-03-21 14:22:38 -040076 return *fOpArgs;
77 }
78
Greg Danielb20d7e52019-09-03 13:54:39 -040079 void setSampledProxyArray(SkTArray<GrTextureProxy*, true>* sampledProxies) {
80 fSampledProxies = sampledProxies;
81 }
82
83 SkTArray<GrTextureProxy*, true>* sampledProxyArray() override {
84 return fSampledProxies;
85 }
86
Brian Salomon29b60c92017-10-31 14:42:10 -040087 /** Overrides of GrDeferredUploadTarget. */
Brian Salomonbfd18cd2017-08-09 16:27:09 -040088
Robert Phillips40a29d72018-01-18 12:59:22 -050089 const GrTokenTracker* tokenTracker() final { return fTokenTracker; }
Brian Salomon29b60c92017-10-31 14:42:10 -040090 GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final;
91 GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final;
Brian Salomon29b60c92017-10-31 14:42:10 -040092
93 /** Overrides of GrMeshDrawOp::Target. */
Brian Salomonbeb7f522019-08-30 16:19:42 -040094 void recordDraw(sk_sp<const GrGeometryProcessor>, const GrMesh[], int meshCnt,
95 const GrPipeline::FixedDynamicState*,
96 const GrPipeline::DynamicStateArrays*) final;
Brian Salomon12d22642019-01-29 14:38:50 -050097 void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*,
Brian Salomon29b60c92017-10-31 14:42:10 -040098 int* startVertex) final;
Brian Salomon12d22642019-01-29 14:38:50 -050099 uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) final;
Brian Salomon29b60c92017-10-31 14:42:10 -0400100 void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, int fallbackVertexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500101 sk_sp<const GrBuffer>*, int* startVertex,
102 int* actualVertexCount) final;
103 uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount,
104 sk_sp<const GrBuffer>*, int* startIndex,
105 int* actualIndexCount) final;
Brian Salomon29b60c92017-10-31 14:42:10 -0400106 void putBackIndices(int indexCount) final;
107 void putBackVertices(int vertices, size_t vertexStride) final;
108 GrRenderTargetProxy* proxy() const final { return fOpArgs->fProxy; }
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700109 const GrAppliedClip* appliedClip() final { return fOpArgs->fAppliedClip; }
Brian Salomon29b60c92017-10-31 14:42:10 -0400110 GrAppliedClip detachAppliedClip() final;
111 const GrXferProcessor::DstProxy& dstProxy() const final { return fOpArgs->fDstProxy; }
112 GrDeferredUploadTarget* deferredUploadTarget() final { return this; }
113 const GrCaps& caps() const final;
114 GrResourceProvider* resourceProvider() const final { return fResourceProvider; }
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400115
Herb Derby081e6f32019-01-16 13:46:02 -0500116 GrStrikeCache* glyphCache() const final;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500117
118 // At this point we know we're flushing so full access to the GrAtlasManager is required (and
119 // permissible).
Robert Phillips5a66efb2018-03-07 15:13:18 -0500120 GrAtlasManager* atlasManager() const final;
Robert Phillipsc4039ea2018-03-01 11:36:45 -0500121
Brian Salomon29b60c92017-10-31 14:42:10 -0400122 /** GrMeshDrawOp::Target override. */
Chris Dalton07cdcfc92019-02-26 11:13:22 -0700123 SkArenaAlloc* allocator() override { return &fArena; }
Brian Salomon7dc6e752017-11-02 11:34:51 -0400124
Brian Salomonbeb7f522019-08-30 16:19:42 -0400125private:
Brian Salomon7dc6e752017-11-02 11:34:51 -0400126 struct InlineUpload {
127 InlineUpload(GrDeferredTextureUploadFn&& upload, GrDeferredUploadToken token)
128 : fUpload(std::move(upload)), fUploadBeforeToken(token) {}
129 GrDeferredTextureUploadFn fUpload;
130 GrDeferredUploadToken fUploadBeforeToken;
131 };
132
133 // A set of contiguous draws that share a draw token, geometry processor, and pipeline. The
134 // meshes for the draw are stored in the fMeshes array. The reason for coalescing meshes
135 // that share a geometry processor into a Draw is that it allows the Gpu object to setup
136 // the shared state once and then issue draws for each mesh.
137 struct Draw {
Brian Salomonf7232642018-09-19 08:58:08 -0400138 ~Draw();
Brian Salomon7eae3e02018-08-07 14:02:38 +0000139 sk_sp<const GrGeometryProcessor> fGeometryProcessor;
Brian Salomon49348902018-06-26 09:12:38 -0400140 const GrPipeline::FixedDynamicState* fFixedDynamicState;
141 const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
Brian Salomon7eae3e02018-08-07 14:02:38 +0000142 const GrMesh* fMeshes = nullptr;
Brian Osmane8012102018-11-29 14:05:07 -0500143 const GrOp* fOp = nullptr;
Brian Salomon7eae3e02018-08-07 14:02:38 +0000144 int fMeshCnt = 0;
Brian Salomon7dc6e752017-11-02 11:34:51 -0400145 };
146
Brian Salomon7dc6e752017-11-02 11:34:51 -0400147 // Storage for ops' pipelines, draws, and inline uploads.
148 SkArenaAlloc fArena{sizeof(GrPipeline) * 100};
149
150 // Store vertex and index data on behalf of ops that are flushed.
151 GrVertexBufferAllocPool fVertexPool;
152 GrIndexBufferAllocPool fIndexPool;
153
154 // Data stored on behalf of the ops being flushed.
Robert Phillips40a29d72018-01-18 12:59:22 -0500155 SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500156 SkArenaAllocList<InlineUpload> fInlineUploads;
157 SkArenaAllocList<Draw> fDraws;
Brian Salomon7dc6e752017-11-02 11:34:51 -0400158
159 // All draws we store have an implicit draw token. This is the draw token for the first draw
160 // in fDraws.
161 GrDeferredUploadToken fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken();
162
163 // Info about the op that is currently preparing or executing using the flush state or null if
164 // an op is not currently preparing of executing.
165 OpArgs* fOpArgs = nullptr;
Brian Salomon29b60c92017-10-31 14:42:10 -0400166
Greg Danielb20d7e52019-09-03 13:54:39 -0400167 // This field is only transiently set during flush. Each GrOpsTask will set it to point to an
168 // array of proxies it uses before call onPrepare and onExecute.
169 SkTArray<GrTextureProxy*, true>* fSampledProxies;
170
Brian Salomon6d4b65e2017-05-03 17:06:09 -0400171 GrGpu* fGpu;
172 GrResourceProvider* fResourceProvider;
Robert Phillips40a29d72018-01-18 12:59:22 -0500173 GrTokenTracker* fTokenTracker;
Greg Daniel2d41d0d2019-08-26 11:08:51 -0400174 GrOpsRenderPass* fOpsRenderPass = nullptr;
Brian Salomon7dc6e752017-11-02 11:34:51 -0400175
176 // Variables that are used to track where we are in lists as ops are executed
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500177 SkArenaAllocList<Draw>::Iter fCurrDraw;
Brian Salomoncbcb0a12017-11-19 13:20:13 -0500178 SkArenaAllocList<InlineUpload>::Iter fCurrUpload;
bsalomon75398562015-08-17 12:55:38 -0700179};
180
bsalomon75398562015-08-17 12:55:38 -0700181#endif