From 35a3abe7655ad24410f3d32dbf3111ee592ea69b Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Mon, 25 Feb 2019 23:11:33 +0000 Subject: [PATCH] Revert "Stack-allocate pipelines for GrMeshDrawOp" This reverts commit dfe5000a5ff2cabb50ddc139882dc1f3005fa429. Reason for revert: HWAA pipeline flag not getting set for dashing. Original change's description: > Stack-allocate pipelines for GrMeshDrawOp > > Stack-allocates the pipelines in onExecute. This saves us from having > to store the pipelines on the heap, as well as delaying the need to > detach processors until onExecute. The delay is an improvement because > it allows us to keep visiting proxies after onPrepare. (Previously, > they were moved out of GrProcessorSet and into a pipeline during > onPrepare, so visiting proxies was impossible after that point.) > > Bug: skia:8731 > Change-Id: Idc05063fb0dfbfed42b434e429fa5a497097bdae > Reviewed-on: https://skia-review.googlesource.com/c/193368 > Commit-Queue: Chris Dalton > Reviewed-by: Robert Phillips TBR=robertphillips@google.com,csmartdalton@google.com Change-Id: If706f19423310846de70288f393ac12f17ffeee5 No-Presubmit: true No-Tree-Checks: true No-Try: true Bug: skia:8731 Reviewed-on: https://skia-review.googlesource.com/c/195161 Reviewed-by: Chris Dalton Commit-Queue: Chris Dalton --- bench/VertexColorSpaceBench.cpp | 9 +-- gm/beziereffects.cpp | 12 +-- gm/convexpolyeffect.cpp | 6 +- src/gpu/GrOpFlushState.cpp | 29 +++----- src/gpu/GrOpFlushState.h | 17 +++-- src/gpu/ops/GrAAConvexPathRenderer.cpp | 8 +- src/gpu/ops/GrAAHairLinePathRenderer.cpp | 12 +-- .../ops/GrAALinearizingConvexPathRenderer.cpp | 20 +++-- src/gpu/ops/GrAtlasTextOp.cpp | 19 ++--- src/gpu/ops/GrAtlasTextOp.h | 2 +- src/gpu/ops/GrDashOp.cpp | 9 +-- src/gpu/ops/GrDefaultPathRenderer.cpp | 17 +++-- src/gpu/ops/GrDrawAtlasOp.cpp | 8 +- src/gpu/ops/GrDrawVerticesOp.cpp | 8 +- src/gpu/ops/GrFillRectOp.cpp | 8 +- src/gpu/ops/GrLatticeOp.cpp | 10 +-- src/gpu/ops/GrMeshDrawOp.cpp | 60 +++++++++------ src/gpu/ops/GrMeshDrawOp.h | 74 ++++++++++++++----- src/gpu/ops/GrOvalOpFactory.cpp | 42 +++-------- src/gpu/ops/GrRegionOp.cpp | 7 +- src/gpu/ops/GrShadowRRectOp.cpp | 11 ++- src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp | 62 +++++++++++----- src/gpu/ops/GrSimpleMeshDrawOpHelper.h | 21 +++++- src/gpu/ops/GrSmallPathRenderer.cpp | 18 ++--- src/gpu/ops/GrStrokeRectOp.cpp | 15 +--- src/gpu/ops/GrTessellatingPathRenderer.cpp | 7 +- src/gpu/ops/GrTextureOp.cpp | 27 ++++--- tests/OnFlushCallbackTest.cpp | 7 +- tests/PrimitiveProcessorTest.cpp | 9 +-- tests/ProcessorTest.cpp | 1 - 30 files changed, 281 insertions(+), 274 deletions(-) diff --git a/bench/VertexColorSpaceBench.cpp b/bench/VertexColorSpaceBench.cpp index 4abec485c2..0d395c58f5 100644 --- a/bench/VertexColorSpaceBench.cpp +++ b/bench/VertexColorSpaceBench.cpp @@ -222,12 +222,9 @@ private: GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangleStrip); mesh->setNonIndexedNonInstanced(kVertexCount); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(gp, mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, GrProcessorSet::MakeEmptySet()); + auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(), + target->detachAppliedClip()); + target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh); } Mode fMode; diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index 96622f86a2..bf35de22fa 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -51,9 +51,8 @@ protected: this->setBounds(rect, HasAABloat::kYes, IsZeroArea::kNo); } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, std::move(fProcessorSet)); + Target::PipelineAndFixedDynamicState makePipeline(Target* target) { + return target->makePipeline(0, std::move(fProcessorSet), target->detachAppliedClip()); } sk_sp gp() const { return fGeometryProcessor; } @@ -116,8 +115,8 @@ private: SkPoint3 pt3 = {verts[v].fPosition.x(), verts[v].fPosition.y(), 1.f}; fKLM.mapHomogeneousPoints((SkPoint3* ) verts[v].fKLM, &pt3, 1); } - - helper.recordDraw(target, this->gp()); + auto pipe = this->makePipeline(target); + helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState); } SkMatrix fKLM; @@ -323,7 +322,8 @@ private: SkRect rect = this->rect(); SkPointPriv::SetRectTriStrip(&verts[0].fPosition, rect, sizeof(Vertex)); fDevToUV.apply(verts, 4, sizeof(Vertex), sizeof(SkPoint)); - helper.recordDraw(target, this->gp()); + auto pipe = this->makePipeline(target); + helper.recordDraw(target, this->gp(), pipe.fPipeline, pipe.fFixedDynamicState); } GrPathUtils::QuadUVMatrix fDevToUV; diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 8a5e7be55b..226c2357f4 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -94,11 +94,9 @@ private: } SkPointPriv::SetRectTriStrip(verts, fRect, sizeof(SkPoint)); - helper.recordDraw(target, std::move(gp)); - } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds, std::move(fProcessors)); + auto pipe = target->makePipeline(0, std::move(fProcessors), target->detachAppliedClip()); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } SkPMColor4f fColor; diff --git a/src/gpu/GrOpFlushState.cpp b/src/gpu/GrOpFlushState.cpp index a02b2f4866..7b983c441e 100644 --- a/src/gpu/GrOpFlushState.cpp +++ b/src/gpu/GrOpFlushState.cpp @@ -32,19 +32,8 @@ GrGpuRTCommandBuffer* GrOpFlushState::rtCommandBuffer() { return fCommandBuffer->asRTCommandBuffer(); } -void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp( - const GrOp* op, const SkRect& chainBounds, GrProcessorSet&& processorSet, - uint32_t pipelineFlags, const GrUserStencilSettings* stencilSettings) { +void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(const GrOp* op, const SkRect& opBounds) { SkASSERT(this->rtCommandBuffer()); - - GrPipeline::InitArgs pipelineArgs; - pipelineArgs.fFlags = pipelineFlags; - pipelineArgs.fDstProxy = this->dstProxy(); - pipelineArgs.fCaps = &this->caps(); - pipelineArgs.fResourceProvider = this->resourceProvider(); - pipelineArgs.fUserStencil = stencilSettings; - GrPipeline pipeline(pipelineArgs, std::move(processorSet), this->detachAppliedClip()); - while (fCurrDraw != fDraws.end() && fCurrDraw->fOp == op) { GrDeferredUploadToken drawToken = fTokenTracker->nextTokenToFlush(); while (fCurrUpload != fInlineUploads.end() && @@ -52,10 +41,9 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp( this->rtCommandBuffer()->inlineUpload(this, fCurrUpload->fUpload); ++fCurrUpload; } - this->rtCommandBuffer()->draw( - *fCurrDraw->fGeometryProcessor, pipeline, fCurrDraw->fFixedDynamicState, - fCurrDraw->fDynamicStateArrays, fCurrDraw->fMeshes, fCurrDraw->fMeshCnt, - chainBounds); + this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline, + fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays, + fCurrDraw->fMeshes, fCurrDraw->fMeshCnt, opBounds); fTokenTracker->flushToken(); ++fCurrDraw; } @@ -110,10 +98,10 @@ GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&& return fTokenTracker->nextTokenToFlush(); } -void GrOpFlushState::recordDraw( - sk_sp gp, const GrMesh meshes[], int meshCnt, - const GrPipeline::FixedDynamicState* fixedDynamicState, - const GrPipeline::DynamicStateArrays* dynamicStateArrays) { +void GrOpFlushState::draw(sk_sp gp, const GrPipeline* pipeline, + const GrPipeline::FixedDynamicState* fixedDynamicState, + const GrPipeline::DynamicStateArrays* dynamicStateArrays, + const GrMesh meshes[], int meshCnt) { SkASSERT(fOpArgs); SkASSERT(fOpArgs->fOp); bool firstDraw = fDraws.begin() == fDraws.end(); @@ -131,6 +119,7 @@ void GrOpFlushState::recordDraw( } } draw.fGeometryProcessor = std::move(gp); + draw.fPipeline = pipeline; draw.fFixedDynamicState = fixedDynamicState; draw.fDynamicStateArrays = dynamicStateArrays; draw.fMeshes = meshes; diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h index 07983d421d..54aa4ddb66 100644 --- a/src/gpu/GrOpFlushState.h +++ b/src/gpu/GrOpFlushState.h @@ -41,9 +41,7 @@ public: void doUpload(GrDeferredTextureUploadFn&); /** Called as ops are executed. Must be called in the same order as the ops were prepared. */ - void executeDrawsAndUploadsForMeshDrawOp( - const GrOp* op, const SkRect& chainBounds, GrProcessorSet&&, uint32_t pipelineFlags = 0, - const GrUserStencilSettings* = &GrUserStencilSettings::kUnused); + void executeDrawsAndUploadsForMeshDrawOp(const GrOp* op, const SkRect& opBounds); GrGpuCommandBuffer* commandBuffer() { return fCommandBuffer; } // Helper function used by Ops that are only called via RenderTargetOpLists @@ -81,9 +79,12 @@ public: GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final; /** Overrides of GrMeshDrawOp::Target. */ - void recordDraw( - sk_sp, const GrMesh[], int meshCnt, - const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*) final; + void draw(sk_sp, + const GrPipeline*, + const GrPipeline::FixedDynamicState*, + const GrPipeline::DynamicStateArrays*, + const GrMesh[], + int meshCnt) final; void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp*, int* startVertex) final; uint16_t* makeIndexSpace(int indexCount, sk_sp*, int* startIndex) final; @@ -96,7 +97,6 @@ public: void putBackIndices(int indexCount) final; void putBackVertices(int vertices, size_t vertexStride) final; GrRenderTargetProxy* proxy() const final { return fOpArgs->fProxy; } - const GrAppliedClip* appliedClip() final { return fOpArgs->fAppliedClip; } GrAppliedClip detachAppliedClip() final; const GrXferProcessor::DstProxy& dstProxy() const final { return fOpArgs->fDstProxy; } GrDeferredUploadTarget* deferredUploadTarget() final { return this; } @@ -113,7 +113,7 @@ public: private: /** GrMeshDrawOp::Target override. */ - SkArenaAlloc* allocator() override { return &fArena; } + SkArenaAlloc* pipelineArena() override { return &fArena; } struct InlineUpload { InlineUpload(GrDeferredTextureUploadFn&& upload, GrDeferredUploadToken token) @@ -129,6 +129,7 @@ private: struct Draw { ~Draw(); sk_sp fGeometryProcessor; + const GrPipeline* fPipeline = nullptr; const GrPipeline::FixedDynamicState* fFixedDynamicState; const GrPipeline::DynamicStateArrays* fDynamicStateArrays; const GrMesh* fMeshes = nullptr; diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp index 1e44b87e99..cb9d364911 100644 --- a/src/gpu/ops/GrAAConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp @@ -713,6 +713,7 @@ public: private: void onPrepareDraws(Target* target) override { + auto pipe = fHelper.makePipeline(target); int instanceCount = fPaths.count(); SkMatrix invert; @@ -793,14 +794,11 @@ private: firstIndex += draw.fIndexCnt; firstVertex += draw.fVertexCnt; } - target->recordDraw(quadProcessor, meshes, draws.count()); + target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, nullptr, meshes, + draws.count()); } } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); - } - CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { AAConvexPathOp* that = t->cast(); if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp index 0933a23751..877a522c63 100644 --- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp @@ -845,7 +845,6 @@ public: private: void onPrepareDraws(Target*) override; - void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; typedef SkTArray PtArray; typedef SkTArray IntArray; @@ -955,6 +954,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) { return; } + auto pipe = fHelper.makePipeline(target); // do lines first if (lineCount) { sk_sp lineGP; @@ -993,7 +993,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) { mesh->setIndexedPatterned(std::move(linesIndexBuffer), kIdxsPerLineSeg, kLineSegNumVertices, lineCount, kLineSegsNumInIdxBuffer); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(lineGP), mesh); + target->draw(std::move(lineGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } if (quadCount || conicCount) { @@ -1048,7 +1048,7 @@ void AAHairlineOp::onPrepareDraws(Target* target) { mesh->setIndexedPatterned(quadsIndexBuffer, kIdxsPerQuad, kQuadNumVertices, quadCount, kQuadsNumInIdxBuffer); mesh->setVertexData(vertexBuffer, firstVertex); - target->recordDraw(std::move(quadGP), mesh); + target->draw(std::move(quadGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); firstVertex += quadCount * kQuadNumVertices; } @@ -1057,15 +1057,11 @@ void AAHairlineOp::onPrepareDraws(Target* target) { mesh->setIndexedPatterned(std::move(quadsIndexBuffer), kIdxsPerQuad, kQuadNumVertices, conicCount, kQuadsNumInIdxBuffer); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(conicGP), mesh); + target->draw(std::move(conicGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } } } -void AAHairlineOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); -} - bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) { GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(), "GrAAHairlinePathRenderer::onDrawPath"); diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp index 4ade8661e1..6205b84ef8 100644 --- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp +++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp @@ -193,8 +193,9 @@ public: } private: - void recordDraw(Target* target, sk_sp gp, int vertexCount, - size_t vertexStride, void* vertices, int indexCount, uint16_t* indices) const { + void draw(Target* target, sk_sp gp, const GrPipeline* pipeline, + const GrPipeline::FixedDynamicState* fixedDynamicState, int vertexCount, + size_t vertexStride, void* vertices, int indexCount, uint16_t* indices) const { if (vertexCount == 0 || indexCount == 0) { return; } @@ -220,10 +221,11 @@ private: mesh->setIndexed(std::move(indexBuffer), indexCount, firstIndex, 0, vertexCount - 1, GrPrimitiveRestart::kNo); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); + target->draw(std::move(gp), pipeline, fixedDynamicState, mesh); } void onPrepareDraws(Target* target) override { + auto pipe = fHelper.makePipeline(target); // Setup GrGeometryProcessor sk_sp gp(create_lines_only_gp(target->caps().shaderCaps(), fHelper.compatibleWithAlphaAsCoverage(), @@ -257,8 +259,8 @@ private: if (vertexCount + currentVertices > static_cast(UINT16_MAX)) { // if we added the current instance, we would overflow the indices we can store in a // uint16_t. Draw what we've got so far and reset. - this->recordDraw( - target, gp, vertexCount, vertexStride, vertices, indexCount, indices); + this->draw(target, gp, pipe.fPipeline, pipe.fFixedDynamicState, vertexCount, + vertexStride, vertices, indexCount, indices); vertexCount = 0; indexCount = 0; } @@ -289,17 +291,13 @@ private: indexCount += currentIndices; } if (vertexCount <= SK_MaxS32 && indexCount <= SK_MaxS32) { - this->recordDraw(target, std::move(gp), vertexCount, vertexStride, vertices, indexCount, - indices); + this->draw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, vertexCount, + vertexStride, vertices, indexCount, indices); } sk_free(vertices); sk_free(indices); } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); - } - CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { AAFlatteningConvexPathOp* that = t->cast(); if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index fae54df956..8e231cb8c6 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -298,13 +298,16 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { GR_STATIC_ASSERT(GrDistanceFieldA8TextGeoProc::kMaxTextures == kMaxTextures); GR_STATIC_ASSERT(GrDistanceFieldLCDTextGeoProc::kMaxTextures == kMaxTextures); - auto fixedDynamicState = target->makeFixedDynamicState(kMaxTextures); + static const uint32_t kPipelineFlags = 0; + auto pipe = target->makePipeline(kPipelineFlags, std::move(fProcessors), + target->detachAppliedClip(), kMaxTextures); for (unsigned i = 0; i < numActiveProxies; ++i) { - fixedDynamicState->fPrimitiveProcessorTextures[i] = proxies[i].get(); + pipe.fFixedDynamicState->fPrimitiveProcessorTextures[i] = proxies[i].get(); } FlushInfo flushInfo; - flushInfo.fFixedDynamicState = fixedDynamicState; + flushInfo.fPipeline = pipe.fPipeline; + flushInfo.fFixedDynamicState = pipe.fFixedDynamicState; bool vmPerspective = fGeoData[0].fViewMatrix.hasPerspective(); if (this->usesDistanceFields()) { @@ -386,12 +389,6 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { this->flush(target, &flushInfo); } -void GrAtlasTextOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { - static const uint32_t kPipelineFlags = 0; - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, std::move(fProcessors), kPipelineFlags); -} - void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) const { if (!flushInfo->fGlyphsToFlush) { return; @@ -431,8 +428,8 @@ void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) co mesh->setIndexedPatterned(flushInfo->fIndexBuffer, kIndicesPerGlyph, kVerticesPerGlyph, flushInfo->fGlyphsToFlush, maxGlyphsPerDraw); mesh->setVertexData(flushInfo->fVertexBuffer, flushInfo->fVertexOffset); - target->recordDraw( - flushInfo->fGeometryProcessor, mesh, 1, flushInfo->fFixedDynamicState, nullptr); + target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, flushInfo->fFixedDynamicState, + mesh); flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush; flushInfo->fGlyphsToFlush = 0; } diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h index 8f5ff20a11..d8d453a668 100644 --- a/src/gpu/ops/GrAtlasTextOp.h +++ b/src/gpu/ops/GrAtlasTextOp.h @@ -107,13 +107,13 @@ private: sk_sp fVertexBuffer; sk_sp fIndexBuffer; sk_sp fGeometryProcessor; + const GrPipeline* fPipeline; GrPipeline::FixedDynamicState* fFixedDynamicState; int fGlyphsToFlush; int fVertexOffset; }; void onPrepareDraws(Target*) override; - void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; GrMaskFormat maskFormat() const { switch (fMaskType) { diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp index 9bf2f9a7f6..ca97f290d4 100644 --- a/src/gpu/ops/GrDashOp.cpp +++ b/src/gpu/ops/GrDashOp.cpp @@ -621,12 +621,9 @@ private: if (AAMode::kCoverageWithMSAA == fAAMode) { pipelineFlags |= GrPipeline::kHWAntialias_Flag; } - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, std::move(fProcessorSet)); + auto pipe = target->makePipeline(pipelineFlags, std::move(fProcessorSet), + target->detachAppliedClip()); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp index 1ac80e6f53..7b50162ed1 100644 --- a/src/gpu/ops/GrDefaultPathRenderer.cpp +++ b/src/gpu/ops/GrDefaultPathRenderer.cpp @@ -66,11 +66,14 @@ namespace { class PathGeoBuilder { public: PathGeoBuilder(GrPrimitiveType primitiveType, GrMeshDrawOp::Target* target, - sk_sp geometryProcessor) + sk_sp geometryProcessor, const GrPipeline* pipeline, + const GrPipeline::FixedDynamicState* fixedDynamicState) : fPrimitiveType(primitiveType) , fTarget(target) , fVertexStride(sizeof(SkPoint)) , fGeometryProcessor(std::move(geometryProcessor)) + , fPipeline(pipeline) + , fFixedDynamicState(fixedDynamicState) , fFirstIndex(0) , fIndicesInChunk(0) , fIndices(nullptr) { @@ -276,7 +279,7 @@ private: vertexCount - 1, GrPrimitiveRestart::kNo); } mesh->setVertexData(std::move(fVertexBuffer), fFirstVertex); - fTarget->recordDraw(fGeometryProcessor, mesh); + fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, mesh); } fTarget->putBackIndices((size_t)(fIndicesInChunk - indexCount)); @@ -313,6 +316,8 @@ private: GrMeshDrawOp::Target* fTarget; size_t fVertexStride; sk_sp fGeometryProcessor; + const GrPipeline* fPipeline; + const GrPipeline::FixedDynamicState* fFixedDynamicState; sk_sp fVertexBuffer; int fFirstVertex; @@ -425,7 +430,9 @@ private: } else { primitiveType = GrPrimitiveType::kTriangles; } - PathGeoBuilder pathGeoBuilder(primitiveType, target, std::move(gp)); + auto pipe = fHelper.makePipeline(target); + PathGeoBuilder pathGeoBuilder(primitiveType, target, std::move(gp), pipe.fPipeline, + pipe.fFixedDynamicState); // fill buffers for (int i = 0; i < instanceCount; i++) { @@ -434,10 +441,6 @@ private: } } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); - } - CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { DefaultPathOp* that = t->cast(); if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { diff --git a/src/gpu/ops/GrDrawAtlasOp.cpp b/src/gpu/ops/GrDrawAtlasOp.cpp index 6dfeb3b82c..e37e960b34 100644 --- a/src/gpu/ops/GrDrawAtlasOp.cpp +++ b/src/gpu/ops/GrDrawAtlasOp.cpp @@ -48,7 +48,6 @@ public: private: void onPrepareDraws(Target*) override; - void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; const SkPMColor4f& color() const { return fColor; } const SkMatrix& viewMatrix() const { return fViewMatrix; } @@ -207,11 +206,8 @@ void DrawAtlasOp::onPrepareDraws(Target* target) { memcpy(vertPtr, args.fVerts.begin(), allocSize); vertPtr += allocSize; } - helper.recordDraw(target, std::move(gp)); -} - -void DrawAtlasOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } GrOp::CombineResult DrawAtlasOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp index f1589ed201..ec82f87ca0 100644 --- a/src/gpu/ops/GrDrawVerticesOp.cpp +++ b/src/gpu/ops/GrDrawVerticesOp.cpp @@ -47,7 +47,6 @@ private: }; void onPrepareDraws(Target*) override; - void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; void drawVolatile(Target*); void drawNonVolatile(Target*); @@ -503,11 +502,8 @@ void DrawVerticesOp::drawVertices(Target* target, mesh->setNonIndexedNonInstanced(fVertexCount); } mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); -} - -void DrawVerticesOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } GrOp::CombineResult DrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) { diff --git a/src/gpu/ops/GrFillRectOp.cpp b/src/gpu/ops/GrFillRectOp.cpp index 171243371c..1d4e13ce5e 100644 --- a/src/gpu/ops/GrFillRectOp.cpp +++ b/src/gpu/ops/GrFillRectOp.cpp @@ -227,12 +227,10 @@ private: return; } mesh->setVertexData(std::move(vbuffer), vertexOffsetInBuffer); - target->recordDraw(std::move(gp), mesh); - } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); - } + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); + } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { TRACE_EVENT0("skia", TRACE_FUNC); diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp index 4d49c6e1b5..dcb88d3cde 100644 --- a/src/gpu/ops/GrLatticeOp.cpp +++ b/src/gpu/ops/GrLatticeOp.cpp @@ -284,13 +284,9 @@ private: kVertsPerRect * patch.fIter->numRectsToDraw()); } } - auto fixedDynamicState = target->makeFixedDynamicState(1); - fixedDynamicState->fPrimitiveProcessorTextures[0] = fProxy.get(); - helper.recordDraw(target, std::move(gp), fixedDynamicState); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target, 1); + pipe.fFixedDynamicState->fPrimitiveProcessorTextures[0] = fProxy.get(); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/src/gpu/ops/GrMeshDrawOp.cpp b/src/gpu/ops/GrMeshDrawOp.cpp index a8ad86399c..ac019f3409 100644 --- a/src/gpu/ops/GrMeshDrawOp.cpp +++ b/src/gpu/ops/GrMeshDrawOp.cpp @@ -14,6 +14,10 @@ GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID) {} void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); } +void GrMeshDrawOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) { + state->executeDrawsAndUploadsForMeshDrawOp(this, chainBounds); +} + ////////////////////////////////////////////////////////////////////////////// GrMeshDrawOp::PatternHelper::PatternHelper(Target* target, GrPrimitiveType primitiveType, @@ -50,14 +54,9 @@ void GrMeshDrawOp::PatternHelper::init(Target* target, GrPrimitiveType primitive } void GrMeshDrawOp::PatternHelper::recordDraw( - Target* target, sk_sp gp) const { - target->recordDraw(std::move(gp), fMesh); -} - -void GrMeshDrawOp::PatternHelper::recordDraw( - Target* target, sk_sp gp, + Target* target, sk_sp gp, const GrPipeline* pipeline, const GrPipeline::FixedDynamicState* fixedDynamicState) const { - target->recordDraw(std::move(gp), fMesh, 1, fixedDynamicState, nullptr); + target->draw(std::move(gp), pipeline, fixedDynamicState, fMesh); } ////////////////////////////////////////////////////////////////////////////// @@ -74,32 +73,45 @@ GrMeshDrawOp::QuadHelper::QuadHelper(Target* target, size_t vertexStride, int qu ////////////////////////////////////////////////////////////////////////////// -GrPipeline::DynamicStateArrays* GrMeshDrawOp::Target::allocDynamicStateArrays( - int numMeshes, int numPrimitiveProcessorTextures, bool allocScissors) { - auto result = this->allocator()->make(); - if (allocScissors) { - result->fScissorRects = this->allocator()->makeArray(numMeshes); - } +GrPipeline::FixedDynamicState* GrMeshDrawOp::Target::allocFixedDynamicState( + const SkIRect& rect, int numPrimitiveProcessorTextures) { + auto result = this->pipelineArena()->make(rect); if (numPrimitiveProcessorTextures) { result->fPrimitiveProcessorTextures = - this->allocator()->makeArrayDefault( - numPrimitiveProcessorTextures * numMeshes); + this->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorTextures); } return result; } -GrPipeline::FixedDynamicState* GrMeshDrawOp::Target::makeFixedDynamicState( +GrPipeline::DynamicStateArrays* GrMeshDrawOp::Target::allocDynamicStateArrays( + int numMeshes, int numPrimitiveProcessorTextures, bool allocScissors) { + auto result = this->pipelineArena()->make(); + if (allocScissors) { + result->fScissorRects = this->pipelineArena()->makeArray(numMeshes); + } + if (numPrimitiveProcessorTextures) { + result->fPrimitiveProcessorTextures = this->allocPrimitiveProcessorTextureArray( + numPrimitiveProcessorTextures * numMeshes); + } + return result; +} + +GrMeshDrawOp::Target::PipelineAndFixedDynamicState GrMeshDrawOp::Target::makePipeline( + uint32_t pipelineFlags, GrProcessorSet&& processorSet, GrAppliedClip&& clip, int numPrimProcTextures) { - const GrAppliedClip* clip = this->appliedClip(); - if ((clip && clip->scissorState().enabled()) || numPrimProcTextures) { - const SkIRect& scissor = (clip) ? clip->scissorState().rect() : SkIRect::MakeEmpty(); - auto fixedDynamicState = - this->allocator()->make(scissor); + GrPipeline::InitArgs pipelineArgs; + pipelineArgs.fFlags = pipelineFlags; + pipelineArgs.fDstProxy = this->dstProxy(); + pipelineArgs.fCaps = &this->caps(); + pipelineArgs.fResourceProvider = this->resourceProvider(); + GrPipeline::FixedDynamicState* fixedDynamicState = nullptr; + if (clip.scissorState().enabled() || numPrimProcTextures) { + fixedDynamicState = this->allocFixedDynamicState(clip.scissorState().rect()); if (numPrimProcTextures) { fixedDynamicState->fPrimitiveProcessorTextures = - this->allocator()->makeArrayDefault(numPrimProcTextures); + this->allocPrimitiveProcessorTextureArray(numPrimProcTextures); } - return fixedDynamicState; } - return nullptr; + return {this->allocPipeline(pipelineArgs, std::move(processorSet), std::move(clip)), + fixedDynamicState}; } diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h index f0c11a4327..170fee0e85 100644 --- a/src/gpu/ops/GrMeshDrawOp.h +++ b/src/gpu/ops/GrMeshDrawOp.h @@ -39,8 +39,7 @@ protected: int indicesPerRepetition, int repeatCount); /** Called to issue draws to the GrMeshDrawOp::Target.*/ - void recordDraw(Target*, sk_sp) const; - void recordDraw(Target*, sk_sp, + void recordDraw(Target*, sk_sp, const GrPipeline*, const GrPipeline::FixedDynamicState*) const; void* vertices() const { return fVertices; } @@ -73,6 +72,7 @@ protected: private: void onPrepare(GrOpFlushState* state) final; + void onExecute(GrOpFlushState* state, const SkRect& chainBounds) final; virtual void onPrepareDraws(Target*) = 0; typedef GrDrawOp INHERITED; }; @@ -82,18 +82,18 @@ public: virtual ~Target() {} /** Adds a draw of a mesh. */ - virtual void recordDraw( - sk_sp, const GrMesh[], int meshCnt, - const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*) = 0; - - /** - * Helper for drawing GrMesh(es) with zero primProc textures and no dynamic state besides the - * scissor clip. - */ - void recordDraw(sk_sp gp, const GrMesh meshes[], int meshCnt = 1) { - static constexpr int kZeroPrimProcTextures = 0; - auto fixedDynamicState = this->makeFixedDynamicState(kZeroPrimProcTextures); - this->recordDraw(std::move(gp), meshes, meshCnt, fixedDynamicState, nullptr); + virtual void draw(sk_sp, + const GrPipeline*, + const GrPipeline::FixedDynamicState*, + const GrPipeline::DynamicStateArrays*, + const GrMesh[], + int meshCount) = 0; + /** Helper for drawing a single GrMesh. */ + void draw(sk_sp gp, + const GrPipeline* pipeline, + const GrPipeline::FixedDynamicState* fixedDynamicState, + const GrMesh* mesh) { + this->draw(std::move(gp), pipeline, fixedDynamicState, nullptr, mesh, 1); } /** @@ -135,21 +135,55 @@ public: virtual void putBackIndices(int indices) = 0; virtual void putBackVertices(int vertices, size_t vertexStride) = 0; - GrMesh* allocMesh(GrPrimitiveType primitiveType) { - return this->allocator()->make(primitiveType); + /** + * 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 + GrPipeline* allocPipeline(Args&&... args) { + return this->pipelineArena()->make(std::forward(args)...); } - GrMesh* allocMeshes(int n) { return this->allocator()->makeArray(n); } + GrMesh* allocMesh(GrPrimitiveType primitiveType) { + return this->pipelineArena()->make(primitiveType); + } + + GrMesh* allocMeshes(int n) { return this->pipelineArena()->makeArray(n); } + + GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect, + int numPrimitiveProcessorTextures = 0); GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes, int numPrimitiveProcessorTextures, bool allocScissors); - GrPipeline::FixedDynamicState* makeFixedDynamicState(int numPrimitiveProcessorTextures); + GrTextureProxy** allocPrimitiveProcessorTextureArray(int n) { + SkASSERT(n > 0); + return this->pipelineArena()->makeArrayDefault(n); + } + + // Once we have C++17 structured bindings make this just be a tuple because then we can do: + // auto [pipeline, fixedDynamicState] = target->makePipeline(...); + // in addition to: + // std::tie(flushInfo.fPipeline, flushInfo.fFixedState) = target->makePipeline(...); + struct PipelineAndFixedDynamicState { + const GrPipeline* fPipeline; + GrPipeline::FixedDynamicState* fFixedDynamicState; + }; + + /** + * Helper that makes a pipeline targeting the op's render target that incorporates the op's + * GrAppliedClip and uses a fixed dynamic state. + */ + PipelineAndFixedDynamicState makePipeline(uint32_t pipelineFlags, GrProcessorSet&&, + GrAppliedClip&&, + int numPrimitiveProcessorTextures = 0); virtual GrRenderTargetProxy* proxy() const = 0; - virtual const GrAppliedClip* appliedClip() = 0; virtual GrAppliedClip detachAppliedClip() = 0; virtual const GrXferProcessor::DstProxy& dstProxy() const = 0; @@ -165,7 +199,7 @@ public: virtual GrDeferredUploadTarget* deferredUploadTarget() = 0; private: - virtual SkArenaAlloc* allocator() = 0; + virtual SkArenaAlloc* pipelineArena() = 0; }; #endif diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp index 3c44259033..315455fa9d 100644 --- a/src/gpu/ops/GrOvalOpFactory.cpp +++ b/src/gpu/ops/GrOvalOpFactory.cpp @@ -1289,11 +1289,8 @@ private: mesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertCount - 1, GrPrimitiveRestart::kNo); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { @@ -1576,11 +1573,8 @@ private: mesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertCount - 1, GrPrimitiveRestart::kNo); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { @@ -1812,11 +1806,8 @@ private: origin_centered_tri_strip(xMaxOffset, yMaxOffset), invRadii); } - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { @@ -2029,11 +2020,8 @@ private: origin_centered_tri_strip(innerRatioX + offsetDx, innerRatioY + offsetDy)); } - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { @@ -2460,11 +2448,8 @@ private: mesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertCount - 1, GrPrimitiveRestart::kNo); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { @@ -2731,11 +2716,8 @@ private: reciprocalRadii); } } - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp index a90bfb90bc..c050142cdf 100644 --- a/src/gpu/ops/GrRegionOp.cpp +++ b/src/gpu/ops/GrRegionOp.cpp @@ -134,11 +134,8 @@ private: iter.next(); } } - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp index 8cb87d66a8..0d99501ff9 100644 --- a/src/gpu/ops/GrShadowRRectOp.cpp +++ b/src/gpu/ops/GrShadowRRectOp.cpp @@ -589,16 +589,15 @@ private: } } + static const uint32_t kPipelineFlags = 0; + auto pipe = target->makePipeline(kPipelineFlags, GrProcessorSet::MakeEmptySet(), + target->detachAppliedClip()); + GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles); mesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertCount - 1, GrPrimitiveRestart::kNo); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, GrProcessorSet::MakeEmptySet()); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp index dcd5567f84..ad7fdf5d33 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.cpp @@ -98,17 +98,6 @@ GrProcessorSet::Analysis GrSimpleMeshDrawOpHelper::finalizeProcessors( return result; } -void GrSimpleMeshDrawOpHelper::executeDrawsAndUploads( - const GrOp* op, GrOpFlushState* flushState, const SkRect& chainBounds) { - if (fProcessors) { - flushState->executeDrawsAndUploadsForMeshDrawOp( - op, chainBounds, std::move(*fProcessors), fPipelineFlags); - } else { - flushState->executeDrawsAndUploadsForMeshDrawOp( - op, chainBounds, GrProcessorSet::MakeEmptySet(), fPipelineFlags); - } -} - #ifdef SK_DEBUG SkString GrSimpleMeshDrawOpHelper::dumpInfo() const { const GrProcessorSet& processors = fProcessors ? *fProcessors : GrProcessorSet::EmptySet(); @@ -133,6 +122,42 @@ SkString GrSimpleMeshDrawOpHelper::dumpInfo() const { } #endif +GrPipeline::InitArgs GrSimpleMeshDrawOpHelper::pipelineInitArgs( + GrMeshDrawOp::Target* target) const { + GrPipeline::InitArgs args; + args.fFlags = this->pipelineFlags(); + args.fDstProxy = target->dstProxy(); + args.fCaps = &target->caps(); + args.fResourceProvider = target->resourceProvider(); + return args; +} + +auto GrSimpleMeshDrawOpHelper::internalMakePipeline(GrMeshDrawOp::Target* target, + const GrPipeline::InitArgs& args, + int numPrimitiveProcessorProxies) + -> PipelineAndFixedDynamicState { + // A caller really should only call this once as the processor set and applied clip get + // moved into the GrPipeline. + SkASSERT(!fMadePipeline); + SkDEBUGCODE(fMadePipeline = true); + auto clip = target->detachAppliedClip(); + GrPipeline::FixedDynamicState* fixedDynamicState = nullptr; + if (clip.scissorState().enabled() || numPrimitiveProcessorProxies) { + fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect()); + if (numPrimitiveProcessorProxies) { + fixedDynamicState->fPrimitiveProcessorTextures = + target->allocPrimitiveProcessorTextureArray(numPrimitiveProcessorProxies); + } + } + if (fProcessors) { + return {target->allocPipeline(args, std::move(*fProcessors), std::move(clip)), + fixedDynamicState}; + } else { + return {target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip)), + fixedDynamicState}; + } +} + GrSimpleMeshDrawOpHelperWithStencil::GrSimpleMeshDrawOpHelperWithStencil( const MakeArgs& args, GrAAType aaType, const GrUserStencilSettings* stencilSettings, Flags flags) @@ -154,15 +179,12 @@ bool GrSimpleMeshDrawOpHelperWithStencil::isCompatible( fStencilSettings == that.fStencilSettings; } -void GrSimpleMeshDrawOpHelperWithStencil::executeDrawsAndUploads( - const GrOp* op, GrOpFlushState* flushState, const SkRect& chainBounds) { - if (fProcessors) { - flushState->executeDrawsAndUploadsForMeshDrawOp( - op, chainBounds, std::move(*fProcessors), fPipelineFlags, fStencilSettings); - } else { - flushState->executeDrawsAndUploadsForMeshDrawOp( - op, chainBounds, GrProcessorSet::MakeEmptySet(), fPipelineFlags, fStencilSettings); - } +auto GrSimpleMeshDrawOpHelperWithStencil::makePipeline(GrMeshDrawOp::Target* target, + int numPrimitiveProcessorTextures) + -> PipelineAndFixedDynamicState { + auto args = INHERITED::pipelineInitArgs(target); + args.fUserStencil = fStencilSettings; + return this->internalMakePipeline(target, args, numPrimitiveProcessorTextures); } #ifdef SK_DEBUG diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h index 8c37b48e84..66b9b4cd58 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h @@ -92,6 +92,14 @@ public: bool compatibleWithAlphaAsCoverage() const { return fCompatibleWithAlphaAsCoveage; } + using PipelineAndFixedDynamicState = GrOpFlushState::PipelineAndFixedDynamicState; + /** Makes a pipeline that consumes the processor set and the op's applied clip. */ + PipelineAndFixedDynamicState makePipeline(GrMeshDrawOp::Target* target, + int numPrimitiveProcessorTextures = 0) { + return this->internalMakePipeline(target, this->pipelineInitArgs(target), + numPrimitiveProcessorTextures); + } + struct MakeArgs { private: MakeArgs() = default; @@ -116,11 +124,16 @@ public: fAAType = static_cast(aaType); } - void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds); - protected: uint32_t pipelineFlags() const { return fPipelineFlags; } + GrPipeline::InitArgs pipelineInitArgs(GrMeshDrawOp::Target* target) const; + + PipelineAndFixedDynamicState internalMakePipeline(GrMeshDrawOp::Target*, + const GrPipeline::InitArgs&, + int numPrimitiveProcessorTextures); + +private: GrProcessorSet* fProcessors; unsigned fPipelineFlags : 8; unsigned fAAType : 2; @@ -139,6 +152,7 @@ class GrSimpleMeshDrawOpHelperWithStencil : private GrSimpleMeshDrawOpHelper { public: using MakeArgs = GrSimpleMeshDrawOpHelper::MakeArgs; using Flags = GrSimpleMeshDrawOpHelper::Flags; + using PipelineAndFixedDynamicState = GrOpFlushState::PipelineAndFixedDynamicState; using GrSimpleMeshDrawOpHelper::visitProxies; @@ -166,7 +180,8 @@ public: const SkRect& thisBounds, const SkRect& thatBounds, bool noneAACompatibleWithCoverage = false) const; - void executeDrawsAndUploads(const GrOp*, GrOpFlushState*, const SkRect& chainBounds); + PipelineAndFixedDynamicState makePipeline(GrMeshDrawOp::Target*, + int numPrimitiveProcessorTextures = 0); #ifdef SK_DEBUG SkString dumpInfo() const; diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index 25791aae3f..bb55520a65 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -308,6 +308,7 @@ private: sk_sp fVertexBuffer; sk_sp fIndexBuffer; sk_sp fGeometryProcessor; + const GrPipeline* fPipeline; GrPipeline::FixedDynamicState* fFixedDynamicState; int fVertexOffset; int fInstancesToFlush; @@ -319,14 +320,17 @@ private: static constexpr int kMaxTextures = GrDistanceFieldPathGeoProc::kMaxTextures; GR_STATIC_ASSERT(GrBitmapTextGeoProc::kMaxTextures == kMaxTextures); - FlushInfo flushInfo; - flushInfo.fFixedDynamicState = target->makeFixedDynamicState(kMaxTextures); + auto pipe = fHelper.makePipeline(target, kMaxTextures); int numActiveProxies = fAtlas->numActivePages(); const auto proxies = fAtlas->getProxies(); for (int i = 0; i < numActiveProxies; ++i) { - flushInfo.fFixedDynamicState->fPrimitiveProcessorTextures[i] = proxies[i].get(); + pipe.fFixedDynamicState->fPrimitiveProcessorTextures[i] = proxies[i].get(); } + FlushInfo flushInfo; + flushInfo.fPipeline = pipe.fPipeline; + flushInfo.fFixedDynamicState = pipe.fFixedDynamicState; + // Setup GrGeometryProcessor const SkMatrix& ctm = fShapes[0].fViewMatrix; if (fUsesDistanceField) { @@ -794,17 +798,13 @@ private: mesh->setIndexedPatterned(flushInfo->fIndexBuffer, kIndicesPerQuad, kVerticesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); mesh->setVertexData(flushInfo->fVertexBuffer, flushInfo->fVertexOffset); - target->recordDraw( - flushInfo->fGeometryProcessor, mesh, 1, flushInfo->fFixedDynamicState, nullptr); + target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, + flushInfo->fFixedDynamicState, mesh); flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush; flushInfo->fInstancesToFlush = 0; } } - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); - } - const SkPMColor4f& color() const { return fShapes[0].fColor; } bool usesDistanceField() const { return fUsesDistanceField; } diff --git a/src/gpu/ops/GrStrokeRectOp.cpp b/src/gpu/ops/GrStrokeRectOp.cpp index 71c5aecc3b..e50f918e71 100644 --- a/src/gpu/ops/GrStrokeRectOp.cpp +++ b/src/gpu/ops/GrStrokeRectOp.cpp @@ -217,11 +217,8 @@ private: GrMesh* mesh = target->allocMesh(primType); mesh->setNonIndexedNonInstanced(vertexCount); mesh->setVertexData(std::move(vertexBuffer), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } // TODO: override onCombineIfPossible @@ -415,7 +412,6 @@ public: private: void onPrepareDraws(Target*) override; - void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; static const int kMiterIndexCnt = 3 * 24; static const int kMiterVertexCnt = 16; @@ -504,11 +500,8 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) { info.fDegenerate, fHelper.compatibleWithAlphaAsCoverage()); } - helper.recordDraw(target, std::move(gp)); -} - -void AAStrokeRectOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } sk_sp AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider, diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp index e619f19066..dc3f59ff78 100644 --- a/src/gpu/ops/GrTessellatingPathRenderer.cpp +++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp @@ -363,11 +363,8 @@ private: : GrPrimitiveType::kTriangles); mesh->setNonIndexedNonInstanced(count); mesh->setVertexData(std::move(vb), firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } Helper fHelper; diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index eb9ccee6cf..5cf35ec869 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -453,17 +453,28 @@ private: textureType, config, samplerState, extraSamplerKey, std::move(fTextureColorSpaceXform)); + GrPipeline::InitArgs args; + args.fCaps = &target->caps(); + args.fResourceProvider = target->resourceProvider(); + args.fFlags = 0; + if (aaType == GrAAType::kMSAA) { + args.fFlags |= GrPipeline::kHWAntialias_Flag; + } + + auto clip = target->detachAppliedClip(); // We'll use a dynamic state array for the GP textures when there are multiple ops. // Otherwise, we use fixed dynamic state to specify the single op's proxy. GrPipeline::DynamicStateArrays* dynamicStateArrays = nullptr; GrPipeline::FixedDynamicState* fixedDynamicState; if (numProxies > 1) { dynamicStateArrays = target->allocDynamicStateArrays(numProxies, 1, false); - fixedDynamicState = target->makeFixedDynamicState(0); + fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect(), 0); } else { - fixedDynamicState = target->makeFixedDynamicState(1); + fixedDynamicState = target->allocFixedDynamicState(clip.scissorState().rect(), 1); fixedDynamicState->fPrimitiveProcessorTextures[0] = fProxies[0].fProxy; } + const auto* pipeline = + target->allocPipeline(args, GrProcessorSet::MakeEmptySet(), std::move(clip)); size_t vertexSize = gp->vertexStride(); @@ -514,16 +525,8 @@ private: } SkASSERT(!numQuadVerticesLeft); SkASSERT(!numAllocatedVertices); - target->recordDraw( - std::move(gp), meshes, numProxies, fixedDynamicState, dynamicStateArrays); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - auto pipelineFlags = (GrAAType::kMSAA == this->aaType()) - ? GrPipeline::kHWAntialias_Flag - : 0; - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, GrProcessorSet::MakeEmptySet(), pipelineFlags); + target->draw(std::move(gp), pipeline, fixedDynamicState, dynamicStateArrays, meshes, + numProxies); } CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override { diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp index 197864a57d..00faf49edc 100644 --- a/tests/OnFlushCallbackTest.cpp +++ b/tests/OnFlushCallbackTest.cpp @@ -158,11 +158,8 @@ private: mesh->setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo); mesh->setVertexData(vertexBuffer, firstVertex); - target->recordDraw(std::move(gp), mesh); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - fHelper.executeDrawsAndUploads(this, flushState, chainBounds); + auto pipe = fHelper.makePipeline(target); + target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); } Helper fHelper; diff --git a/tests/PrimitiveProcessorTest.cpp b/tests/PrimitiveProcessorTest.cpp index 7380d6fef2..ba6e148594 100644 --- a/tests/PrimitiveProcessorTest.cpp +++ b/tests/PrimitiveProcessorTest.cpp @@ -104,12 +104,9 @@ private: QuadHelper helper(target, vertexStride, 1); SkPoint* vertices = reinterpret_cast(helper.vertices()); SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride); - helper.recordDraw(target, std::move(gp)); - } - - void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override { - flushState->executeDrawsAndUploadsForMeshDrawOp( - this, chainBounds, GrProcessorSet::MakeEmptySet()); + auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(), + target->detachAppliedClip()); + helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState); } int fNumAttribs; diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp index d5b27aba13..0c854d1df1 100644 --- a/tests/ProcessorTest.cpp +++ b/tests/ProcessorTest.cpp @@ -61,7 +61,6 @@ private: } void onPrepareDraws(Target* target) override { return; } - void onExecute(GrOpFlushState*, const SkRect&) override { return; } GrProcessorSet fProcessors;