blob: 947fd14b179f1cb13581652714574ae088608bd4 [file] [log] [blame]
/*
* 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