diff options
author | 2017-10-31 14:42:10 -0400 | |
---|---|---|
committer | 2017-10-31 19:01:06 +0000 | |
commit | 29b60c9020ce4376df3d31db15d1aa316d640711 (patch) | |
tree | 86748ea86ae5d10f62d1714e0423487ed4e43a4a /src/gpu/ops | |
parent | f78b55cb94f4ac89b76a26d5a56d6380aa8fea6b (diff) |
Make deferred upload handling and draw recording be virtual interfaces implemented by GrOpFlushState.
The motivation for this is to allow other clients of GrDrawOpAtlas. Making GrMeshDrawOp::Target also be an abstract interface is somewhat incidental to this goal.
Bug: skia:
Change-Id: I0987adfa8a269aa2ca94147e933a2827d734c1cc
Reviewed-on: https://skia-review.googlesource.com/65121
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu/ops')
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.cpp | 6 | ||||
-rw-r--r-- | src/gpu/ops/GrDrawOp.h | 5 | ||||
-rw-r--r-- | src/gpu/ops/GrMeshDrawOp.cpp | 32 | ||||
-rw-r--r-- | src/gpu/ops/GrMeshDrawOp.h | 92 | ||||
-rw-r--r-- | src/gpu/ops/GrSmallPathRenderer.cpp | 19 |
5 files changed, 109 insertions, 45 deletions
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index 591afb2770..f0a9300d9e 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -235,9 +235,9 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { size_t byteCount; void* blobVertices; int subRunGlyphCount; - blob->regenInOp(target, fFontCache, &helper, args.fRun, args.fSubRun, &glyphCache, - vertexStride, args.fViewMatrix, args.fX, args.fY, args.fColor, - &blobVertices, &byteCount, &subRunGlyphCount); + blob->regenInOp(target->deferredUploadTarget(), fFontCache, &helper, args.fRun, + args.fSubRun, &glyphCache, vertexStride, args.fViewMatrix, args.fX, args.fY, + args.fColor, &blobVertices, &byteCount, &subRunGlyphCount); // now copy all vertices if (args.fClipRect.isEmpty()) { diff --git a/src/gpu/ops/GrDrawOp.h b/src/gpu/ops/GrDrawOp.h index 88edfe7f38..f4a7102a88 100644 --- a/src/gpu/ops/GrDrawOp.h +++ b/src/gpu/ops/GrDrawOp.h @@ -16,11 +16,12 @@ class GrAppliedClip; /** - * Base class for GrOps that draw. These ops have a GrPipeline installed by GrOpList. + * Base class for GrOps that draw. These ops can draw into an op list's GrRenderTarget. */ class GrDrawOp : public GrOp { public: - class Target; + /** Provides GrOpFlushState with privileged access to GrDrawOp. */ + class FlushStateAccess; GrDrawOp(uint32_t classID) : INHERITED(classID) {} diff --git a/src/gpu/ops/GrMeshDrawOp.cpp b/src/gpu/ops/GrMeshDrawOp.cpp index 2e12953fe1..a00af15179 100644 --- a/src/gpu/ops/GrMeshDrawOp.cpp +++ b/src/gpu/ops/GrMeshDrawOp.cpp @@ -13,10 +13,7 @@ GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID), fBaseDrawToken(GrDeferredUploadToken::AlreadyFlushedToken()) {} -void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { - Target target(state, this); - this->onPrepareDraws(&target); -} +void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); } void* GrMeshDrawOp::PatternHelper::init(Target* target, size_t vertexStride, const GrBuffer* indexBuffer, int verticesPerRepetition, @@ -85,30 +82,3 @@ void GrMeshDrawOp::onExecute(GrOpFlushState* state) { fQueuedDraws.reset(); fInlineUploads.reset(); } - -////////////////////////////////////////////////////////////////////////////// - -void GrMeshDrawOp::Target::draw(const GrGeometryProcessor* gp, const GrPipeline* pipeline, - const GrMesh& mesh) { - GrMeshDrawOp* op = this->meshDrawOp(); - op->fMeshes.push_back(mesh); - if (!op->fQueuedDraws.empty()) { - // If the last draw shares a geometry processor and pipeline and there are no intervening - // uploads, add this mesh to it. - GrMeshDrawOp::QueuedDraw& lastDraw = op->fQueuedDraws.back(); - if (lastDraw.fGeometryProcessor == gp && lastDraw.fPipeline == pipeline && - (op->fInlineUploads.empty() || - op->fInlineUploads.back().fUploadBeforeToken != this->nextDrawToken())) { - ++lastDraw.fMeshCnt; - return; - } - } - GrMeshDrawOp::QueuedDraw& draw = op->fQueuedDraws.push_back(); - GrDeferredUploadToken token = this->state()->issueDrawToken(); - draw.fGeometryProcessor.reset(gp); - draw.fPipeline = pipeline; - draw.fMeshCnt = 1; - if (op->fQueuedDraws.count() == 1) { - op->fBaseDrawToken = token; - } -} diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h index 64faaa8013..232adb2da1 100644 --- a/src/gpu/ops/GrMeshDrawOp.h +++ b/src/gpu/ops/GrMeshDrawOp.h @@ -23,7 +23,10 @@ class GrOpFlushState; */ class GrMeshDrawOp : public GrDrawOp { public: + /** Abstract interface that represents a destination for a GrMeshDrawOp. */ class Target; + /** Provides GrOpFlushState with privileged access to GrMeshDrawOp. */ + class FlushStateAccess; protected: GrMeshDrawOp(uint32_t classID); @@ -90,4 +93,93 @@ private: typedef GrDrawOp INHERITED; }; +class GrMeshDrawOp::Target { +public: + virtual ~Target() {} + + /** Adds a draw of a mesh. */ + virtual void draw(const GrGeometryProcessor*, const GrPipeline*, const GrMesh&) = 0; + + /** + * Makes space for vertex data. The returned pointer is the location where vertex data + * should be written. On return the buffer that will hold the data as well as an offset into + * the buffer (in 'vertexSize' units) where the data will be placed. + */ + virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**, + int* startVertex) = 0; + + /** + * Makes space for index data. The returned pointer is the location where index data + * should be written. On return the buffer that will hold the data as well as an offset into + * the buffer (in uint16_t units) where the data will be placed. + */ + virtual uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) = 0; + + /** + * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount' + * vertices in the returned pointer, which may exceed 'minVertexCount'. + * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new + * buffer is allocated on behalf of this request. + */ + virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, + int fallbackVertexCount, const GrBuffer**, + int* startVertex, int* actualVertexCount) = 0; + + /** + * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount' + * indices in the returned pointer, which may exceed 'minIndexCount'. + * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new + * buffer is allocated on behalf of this request. + */ + virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, + const GrBuffer**, int* startIndex, + int* actualIndexCount) = 0; + + /** Helpers for ops which over-allocate and then return excess data to the pool. */ + virtual void putBackIndices(int indices) = 0; + virtual void putBackVertices(int vertices, size_t vertexStride) = 0; + + /** + * Allocate space for a pipeline. The target ensures this pipeline lifetime is at least + * as long as any deferred execution of draws added via draw(). + * @tparam Args + * @param args + * @return + */ + template <typename... Args> + GrPipeline* allocPipeline(Args&&... args) { + return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...); + } + + /** + * Helper that makes a pipeline targeting the op's render target that incorporates the op's + * GrAppliedClip. + * */ + GrPipeline* makePipeline(uint32_t pipelineFlags, GrProcessorSet&& processorSet, + GrAppliedClip&& clip) { + GrPipeline::InitArgs pipelineArgs; + pipelineArgs.fFlags = pipelineFlags; + pipelineArgs.fProxy = this->proxy(); + pipelineArgs.fDstProxy = this->dstProxy(); + pipelineArgs.fCaps = &this->caps(); + pipelineArgs.fResourceProvider = this->resourceProvider(); + return this->allocPipeline(pipelineArgs, std::move(processorSet), std::move(clip)); + } + + virtual GrRenderTargetProxy* proxy() const = 0; + + virtual GrAppliedClip detachAppliedClip() = 0; + + virtual const GrXferProcessor::DstProxy& dstProxy() const = 0; + + virtual GrResourceProvider* resourceProvider() const = 0; + + virtual const GrCaps& caps() const = 0; + + virtual GrDeferredUploadTarget* deferredUploadTarget() = 0; + +private: + virtual SkArenaAlloc* pipelineArena() = 0; +}; + #endif diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index 0aaab9cd23..d3084981f8 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -383,10 +383,9 @@ private: } } - atlas->setLastUseToken(shapeData->fID, target->nextDrawToken()); + atlas->setLastUseToken(shapeData->fID, target->deferredUploadTarget()->nextDrawToken()); - this->writePathVertices(target, - atlas, + this->writePathVertices(atlas, offset, args.fColor, vertexStride, @@ -489,9 +488,11 @@ private: // add to atlas SkIPoint16 atlasLocation; GrDrawOpAtlas::AtlasID id; - if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) { + auto uploadTarget = target->deferredUploadTarget(); + if (!atlas->addToAtlas(&id, uploadTarget, width, height, dfStorage.get(), &atlasLocation)) { this->flush(target, flushInfo); - if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atlasLocation)) { + if (!atlas->addToAtlas(&id, uploadTarget, width, height, dfStorage.get(), + &atlasLocation)) { return false; } } @@ -589,10 +590,11 @@ private: // add to atlas SkIPoint16 atlasLocation; GrDrawOpAtlas::AtlasID id; - if (!atlas->addToAtlas(&id, target, dst.width(), dst.height(), dst.addr(), + auto uploadTarget = target->deferredUploadTarget(); + if (!atlas->addToAtlas(&id, uploadTarget, dst.width(), dst.height(), dst.addr(), &atlasLocation)) { this->flush(target, flushInfo); - if (!atlas->addToAtlas(&id, target, dst.width(), dst.height(), dst.addr(), + if (!atlas->addToAtlas(&id, uploadTarget, dst.width(), dst.height(), dst.addr(), &atlasLocation)) { return false; } @@ -622,8 +624,7 @@ private: return true; } - void writePathVertices(GrDrawOp::Target* target, - GrDrawOpAtlas* atlas, + void writePathVertices(GrDrawOpAtlas* atlas, intptr_t offset, GrColor color, size_t vertexStride, |