| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrOpFlushState_DEFINED |
| #define GrOpFlushState_DEFINED |
| |
| #include "GrAppliedClip.h" |
| #include "GrBufferAllocPool.h" |
| #include "GrDeferredUpload.h" |
| #include "SkArenaAlloc.h" |
| #include "ops/GrMeshDrawOp.h" |
| |
| class GrGpu; |
| class GrGpuCommandBuffer; |
| class GrGpuRTCommandBuffer; |
| class GrResourceProvider; |
| |
| // TODO: Store uploads on GrOpFlushState rather than GrDrawOp and remove this. |
| class GrDrawOp::FlushStateAccess { |
| private: |
| friend class GrOpFlushState; |
| |
| explicit FlushStateAccess(GrDrawOp* op) : fOp(op) {} |
| |
| void addInlineUpload(GrDeferredTextureUploadFn&& upload, GrDeferredUploadToken token) { |
| fOp->fInlineUploads.emplace_back(std::move(upload), token); |
| } |
| |
| GrDrawOp* fOp; |
| }; |
| |
| // TODO: Store draw related data on GrOpFlushState rather than GrMeshDrawOp and remove this. |
| class GrMeshDrawOp::FlushStateAccess { |
| private: |
| friend class GrOpFlushState; |
| using QueuedDraw = GrMeshDrawOp::QueuedDraw; |
| |
| explicit FlushStateAccess(GrMeshDrawOp* op) : fOp(op) {} |
| |
| void addMesh(const GrMesh& mesh) { fOp->fMeshes.push_back(mesh); } |
| |
| QueuedDraw* lastDraw() { |
| return fOp->fQueuedDraws.empty() ? nullptr : &fOp->fQueuedDraws.back(); |
| } |
| |
| QueuedDraw* addDraw() { return &fOp->fQueuedDraws.push_back(); } |
| |
| GrDeferredUploadToken lastUploadToken() const { |
| if (fOp->fInlineUploads.empty()) { |
| return GrDeferredUploadToken::AlreadyFlushedToken(); |
| } |
| return fOp->fInlineUploads.back().fUploadBeforeToken; |
| } |
| |
| void setBaseDrawToken(GrDeferredUploadToken token) { fOp->fBaseDrawToken = token; } |
| |
| GrMeshDrawOp* fOp; |
| }; |
| |
| /** Tracks the state across all the GrOps (really just the GrDrawOps) in a GrOpList flush. */ |
| class GrOpFlushState final : public GrDeferredUploadTarget, public GrMeshDrawOp::Target { |
| public: |
| GrOpFlushState(GrGpu*, GrResourceProvider*); |
| |
| ~GrOpFlushState() final { this->reset(); } |
| |
| /** This is called after each op has a chance to prepare its draws and before the draws are |
| issued. */ |
| void preIssueDraws() { |
| fVertexPool.unmap(); |
| fIndexPool.unmap(); |
| int uploadCount = fASAPUploads.count(); |
| |
| for (int i = 0; i < uploadCount; i++) { |
| this->doUpload(fASAPUploads[i]); |
| } |
| fASAPUploads.reset(); |
| } |
| |
| void doUpload(GrDeferredTextureUploadFn&); |
| |
| GrGpuCommandBuffer* commandBuffer() { return fCommandBuffer; } |
| // Helper function used by Ops that are only called via RenderTargetOpLists |
| GrGpuRTCommandBuffer* rtCommandBuffer(); |
| void setCommandBuffer(GrGpuCommandBuffer* buffer) { fCommandBuffer = buffer; } |
| |
| GrGpu* gpu() { return fGpu; } |
| |
| void reset() { |
| fVertexPool.reset(); |
| fIndexPool.reset(); |
| fPipelines.reset(); |
| } |
| |
| /** Additional data required on a per-op basis when executing GrOps. */ |
| struct OpArgs { |
| GrRenderTarget* renderTarget() const { return fProxy->priv().peekRenderTarget(); } |
| |
| GrOp* fOp; |
| // TODO: do we still need the dst proxy here? |
| GrRenderTargetProxy* fProxy; |
| GrAppliedClip* fAppliedClip; |
| GrXferProcessor::DstProxy fDstProxy; |
| }; |
| |
| void setOpArgs(OpArgs* opArgs) { fOpArgs = opArgs; } |
| |
| const OpArgs& drawOpArgs() const { |
| SkASSERT(fOpArgs); |
| SkASSERT(fOpArgs->fOp); |
| return *fOpArgs; |
| } |
| |
| /** Expose base class methods for incrementing the last flushed and next draw token. */ |
| |
| void flushToken() { this->GrDeferredUploadTarget::flushToken(); } |
| |
| GrDeferredUploadToken issueDrawToken() { |
| return this->GrDeferredUploadTarget::issueDrawToken(); |
| } |
| |
| /** Overrides of GrDeferredUploadTarget. */ |
| |
| GrDeferredUploadToken addInlineUpload(GrDeferredTextureUploadFn&&) final; |
| GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final; |
| |
| /** Overrides of GrMeshDrawOp::Target. */ |
| |
| void draw(const GrGeometryProcessor*, const GrPipeline*, const GrMesh&) final; |
| void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**, |
| int* startVertex) final; |
| uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final; |
| void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, int fallbackVertexCount, |
| const GrBuffer**, int* startVertex, int* actualVertexCount) final; |
| uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, const GrBuffer**, |
| int* startIndex, int* actualIndexCount) final; |
| void putBackIndices(int indexCount) final; |
| void putBackVertices(int vertices, size_t vertexStride) final; |
| GrRenderTargetProxy* proxy() const final { return fOpArgs->fProxy; } |
| GrAppliedClip detachAppliedClip() final; |
| const GrXferProcessor::DstProxy& dstProxy() const final { return fOpArgs->fDstProxy; } |
| GrDeferredUploadTarget* deferredUploadTarget() final { return this; } |
| const GrCaps& caps() const final; |
| GrResourceProvider* resourceProvider() const final { return fResourceProvider; } |
| |
| private: |
| /** GrMeshDrawOp::Target override. */ |
| SkArenaAlloc* pipelineArena() override { return &fPipelines; } |
| |
| GrGpu* fGpu; |
| GrResourceProvider* fResourceProvider; |
| GrGpuCommandBuffer* fCommandBuffer; |
| GrVertexBufferAllocPool fVertexPool; |
| GrIndexBufferAllocPool fIndexPool; |
| SkSTArray<4, GrDeferredTextureUploadFn> fASAPUploads; |
| OpArgs* fOpArgs; |
| SkArenaAlloc fPipelines{sizeof(GrPipeline) * 100}; |
| }; |
| |
| #endif |