diff options
author | Robert Phillips <robertphillips@google.com> | 2018-06-19 13:09:54 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-19 19:51:20 +0000 |
commit | c994a93b327235182c6d29a782c409b2c58476ae (patch) | |
tree | dba9ab1ff4a414e76da883f47ee90acbf0f27868 /src/gpu | |
parent | 4d75975b70c454288226afc03e512ad9bc2db5ac (diff) |
Move op memory storage to GrContext (take 2)
TBR=bsalomon@google.com
Change-Id: I4a448694d4114d83cd3a720cfc8bd37de51733d1
Reviewed-on: https://skia-review.googlesource.com/135707
Reviewed-by: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src/gpu')
26 files changed, 191 insertions, 96 deletions
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index f987536a5c..4b1af9991e 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -12,6 +12,7 @@ #include "GrContextPriv.h" #include "GrDrawingManager.h" #include "GrGpu.h" +#include "GrMemoryPool.h" #include "GrProxyProvider.h" #include "GrRenderTargetContext.h" #include "GrRenderTargetProxy.h" @@ -811,6 +812,22 @@ void GrContextPriv::flushSurfaceIO(GrSurfaceProxy* proxy) { //////////////////////////////////////////////////////////////////////////////// +sk_sp<GrOpMemoryPool> GrContextPriv::refOpMemoryPool() { + if (!fContext->fOpMemoryPool) { + // DDL TODO: should the size of the memory pool be decreased in DDL mode? CPU-side memory + // consumed in DDL mode vs. normal mode for a single skp might be a good metric of wasted + // memory. + fContext->fOpMemoryPool = sk_sp<GrOpMemoryPool>(new GrOpMemoryPool(16384, 16384)); + } + + SkASSERT(fContext->fOpMemoryPool); + return fContext->fOpMemoryPool; +} + +GrOpMemoryPool* GrContextPriv::opMemoryPool() { + return this->refOpMemoryPool().get(); +} + sk_sp<GrSurfaceContext> GrContextPriv::makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy> proxy, sk_sp<SkColorSpace> colorSpace, const SkSurfaceProps* props) { diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 84de0560fa..8d4b1ed28f 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -13,6 +13,7 @@ #include "text/GrAtlasManager.h" class GrBackendRenderTarget; +class GrOpMemoryPool; class GrOnFlushCallbackObject; class GrSemaphore; class GrSurfaceProxy; @@ -32,6 +33,9 @@ public: const GrCaps* caps() const { return fContext->fCaps.get(); } + sk_sp<GrOpMemoryPool> refOpMemoryPool(); + GrOpMemoryPool* opMemoryPool(); + GrDrawingManager* drawingManager() { return fContext->fDrawingManager.get(); } sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy>, diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp index 99eb04b918..7c6338f3d2 100644 --- a/src/gpu/GrDrawingManager.cpp +++ b/src/gpu/GrDrawingManager.cpp @@ -10,6 +10,7 @@ #include "GrContext.h" #include "GrContextPriv.h" #include "GrGpu.h" +#include "GrMemoryPool.h" #include "GrOnFlushResourceProvider.h" #include "GrOpList.h" #include "GrRenderTargetContext.h" @@ -236,6 +237,15 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*, #endif fOpLists.reset(); +#ifdef SK_DEBUG + // In non-DDL mode this checks that all the flushed ops have been freed from the memory pool. + // When we move to partial flushes this assert will no longer be valid. + // In DDL mode this check is somewhat superfluous since the memory for most of the ops/opLists + // will be stored in the DDL's GrOpMemoryPools. + GrOpMemoryPool* opMemoryPool = fContext->contextPriv().opMemoryPool(); + opMemoryPool->isEmpty(); +#endif + GrSemaphoresSubmitted result = gpu->finishFlush(numSemaphores, backendSemaphores); flushState.uninstantiateProxyTracker()->uninstantiateAllProxies(); @@ -420,6 +430,7 @@ sk_sp<GrRenderTargetOpList> GrDrawingManager::newRTOpList(GrRenderTargetProxy* r sk_sp<GrRenderTargetOpList> opList(new GrRenderTargetOpList( resourceProvider, + fContext->contextPriv().refOpMemoryPool(), rtp, fContext->contextPriv().getAuditTrail())); SkASSERT(rtp->getLastOpList() == opList.get()); @@ -442,6 +453,7 @@ sk_sp<GrTextureOpList> GrDrawingManager::newTextureOpList(GrTextureProxy* textur } sk_sp<GrTextureOpList> opList(new GrTextureOpList(fContext->contextPriv().resourceProvider(), + fContext->contextPriv().refOpMemoryPool(), textureProxy, fContext->contextPriv().getAuditTrail())); diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h index 67991d3fa0..15399b6852 100644 --- a/src/gpu/GrMemoryPool.h +++ b/src/gpu/GrMemoryPool.h @@ -146,6 +146,8 @@ public: void release(std::unique_ptr<GrOp> op); + bool isEmpty() const { return fMemoryPool.isEmpty(); } + private: GrMemoryPool fMemoryPool; }; diff --git a/src/gpu/GrOpList.cpp b/src/gpu/GrOpList.cpp index 6fed34a38c..b9f425576e 100644 --- a/src/gpu/GrOpList.cpp +++ b/src/gpu/GrOpList.cpp @@ -9,6 +9,7 @@ #include "GrContext.h" #include "GrDeferredProxyUploader.h" +#include "GrMemoryPool.h" #include "GrSurfaceProxy.h" #include "GrTextureProxyPriv.h" @@ -24,11 +25,13 @@ uint32_t GrOpList::CreateUniqueID() { return id; } -GrOpList::GrOpList(GrResourceProvider* resourceProvider, +GrOpList::GrOpList(GrResourceProvider* resourceProvider, sk_sp<GrOpMemoryPool> opMemoryPool, GrSurfaceProxy* surfaceProxy, GrAuditTrail* auditTrail) - : fAuditTrail(auditTrail) - , fUniqueID(CreateUniqueID()) - , fFlags(0) { + : fOpMemoryPool(std::move(opMemoryPool)) + , fAuditTrail(auditTrail) + , fUniqueID(CreateUniqueID()) + , fFlags(0) { + SkASSERT(fOpMemoryPool); fTarget.setProxy(sk_ref_sp(surfaceProxy), kWrite_GrIOType); fTarget.get()->setLastOpList(this); diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp index ebb0054f40..1dbde17575 100644 --- a/src/gpu/GrRenderTargetContext.cpp +++ b/src/gpu/GrRenderTargetContext.cpp @@ -1726,6 +1726,7 @@ static void op_bounds(SkRect* bounds, const GrOp* op) { uint32_t GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<GrDrawOp> op) { ASSERT_SINGLE_OWNER if (this->drawingManager()->wasAbandoned()) { + fContext->contextPriv().opMemoryPool()->release(std::move(op)); return SK_InvalidUniqueID; } SkDEBUGCODE(this->validate();) @@ -1739,6 +1740,7 @@ uint32_t GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<Gr if (!clip.apply(fContext, this, fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesHWAA, fixedFunctionFlags & GrDrawOp::FixedFunctionFlags::kUsesStencil, &appliedClip, &bounds)) { + fContext->contextPriv().opMemoryPool()->release(std::move(op)); return SK_InvalidUniqueID; } @@ -1755,6 +1757,7 @@ uint32_t GrRenderTargetContext::addDrawOp(const GrClip& clip, std::unique_ptr<Gr if (GrDrawOp::RequiresDstTexture::kYes == op->finalize(*this->caps(), &appliedClip, dstIsClamped)) { if (!this->setupDstProxy(this->asRenderTargetProxy(), clip, op->bounds(), &dstProxy)) { + fContext->contextPriv().opMemoryPool()->release(std::move(op)); return SK_InvalidUniqueID; } } diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp index b04ec3629a..423b71ca10 100644 --- a/src/gpu/GrRenderTargetOpList.cpp +++ b/src/gpu/GrRenderTargetOpList.cpp @@ -26,14 +26,29 @@ static const int kMaxOpLookback = 10; static const int kMaxOpLookahead = 10; GrRenderTargetOpList::GrRenderTargetOpList(GrResourceProvider* resourceProvider, + sk_sp<GrOpMemoryPool> opMemoryPool, GrRenderTargetProxy* proxy, GrAuditTrail* auditTrail) - : INHERITED(resourceProvider, proxy, auditTrail) + : INHERITED(resourceProvider, std::move(opMemoryPool), proxy, auditTrail) , fLastClipStackGenID(SK_InvalidUniqueID) SkDEBUGCODE(, fNumClips(0)) { } +void GrRenderTargetOpList::RecordedOp::deleteOp(GrOpMemoryPool* opMemoryPool) { + opMemoryPool->release(std::move(fOp)); +} + +void GrRenderTargetOpList::deleteOps() { + for (int i = 0; i < fRecordedOps.count(); ++i) { + if (fRecordedOps[i].fOp) { + fRecordedOps[i].deleteOp(fOpMemoryPool.get()); + } + } + fRecordedOps.reset(); +} + GrRenderTargetOpList::~GrRenderTargetOpList() { + this->deleteOps(); } //////////////////////////////////////////////////////////////////////////////// @@ -188,7 +203,7 @@ bool GrRenderTargetOpList::onExecute(GrOpFlushState* flushState) { void GrRenderTargetOpList::endFlush() { fLastClipStackGenID = SK_InvalidUniqueID; - fRecordedOps.reset(); + this->deleteOps(); fClipAllocator.reset(); INHERITED::endFlush(); } @@ -210,7 +225,7 @@ void GrRenderTargetOpList::fullClear(GrContext* context, GrColor color) { // Beware! If we ever add any ops that have a side effect beyond modifying the stencil // buffer we will need a more elaborate tracking system (skbug.com/7002). if (this->isEmpty() || !fTarget.get()->asRenderTargetProxy()->needsStencil()) { - fRecordedOps.reset(); + this->deleteOps(); fDeferredProxies.reset(); fColorLoadOp = GrLoadOp::kClear; fLoadClearColor = color; @@ -257,7 +272,7 @@ void GrRenderTargetOpList::purgeOpsWithUninstantiatedProxies() { recordedOp.visitProxies(checkInstantiation); if (hasUninstantiatedProxy) { // When instantiation of the proxy fails we drop the Op - recordedOp.fOp = nullptr; + recordedOp.deleteOp(fOpMemoryPool.get()); } } } @@ -360,6 +375,7 @@ uint32_t GrRenderTargetOpList::recordOp(std::unique_ptr<GrOp> op, GrOP_INFO("\t\t\tBackward: Combined op info:\n"); GrOP_INFO(SkTabString(candidate.fOp->dumpInfo(), 4).c_str()); GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, candidate.fOp.get(), op.get()); + fOpMemoryPool->release(std::move(op)); return SK_InvalidUniqueID; } // Stop going backwards if we would cause a painter's order violation. @@ -405,6 +421,7 @@ void GrRenderTargetOpList::forwardCombine(const GrCaps& caps) { i, op->name(), op->uniqueID(), candidate.fOp->name(), candidate.fOp->uniqueID()); GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(fAuditTrail, op, candidate.fOp.get()); + fOpMemoryPool->release(std::move(fRecordedOps[j].fOp)); fRecordedOps[j].fOp = std::move(fRecordedOps[i].fOp); break; } diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h index 00b9f5eb27..8629a7cb1f 100644 --- a/src/gpu/GrRenderTargetOpList.h +++ b/src/gpu/GrRenderTargetOpList.h @@ -32,7 +32,8 @@ private: using DstProxy = GrXferProcessor::DstProxy; public: - GrRenderTargetOpList(GrResourceProvider*, GrRenderTargetProxy*, GrAuditTrail*); + GrRenderTargetOpList(GrResourceProvider*, sk_sp<GrOpMemoryPool>, + GrRenderTargetProxy*, GrAuditTrail*); ~GrRenderTargetOpList() override; @@ -122,6 +123,8 @@ public: private: friend class GrRenderTargetContextPriv; // for stencil clip state. TODO: this is invasive + void deleteOps(); + struct RecordedOp { RecordedOp(std::unique_ptr<GrOp> op, GrAppliedClip* appliedClip, const DstProxy* dstProxy) : fOp(std::move(op)), fAppliedClip(appliedClip) { @@ -130,7 +133,12 @@ private: } } - ~RecordedOp() { } + ~RecordedOp() { + // The ops are stored in a GrMemoryPool so had better have been handled separately + SkASSERT(!fOp); + } + + void deleteOp(GrOpMemoryPool* opMemoryPool); void visitProxies(const GrOp::VisitProxyFunc& func) const { if (fOp) { diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp index a868b5d393..6a601aa83c 100644 --- a/src/gpu/GrTextureOpList.cpp +++ b/src/gpu/GrTextureOpList.cpp @@ -11,6 +11,7 @@ #include "GrContext.h" #include "GrContextPriv.h" #include "GrGpu.h" +#include "GrMemoryPool.h" #include "GrResourceAllocator.h" #include "GrTextureProxy.h" #include "SkStringUtils.h" @@ -19,12 +20,28 @@ //////////////////////////////////////////////////////////////////////////////// GrTextureOpList::GrTextureOpList(GrResourceProvider* resourceProvider, + sk_sp<GrOpMemoryPool> opMemoryPool, GrTextureProxy* proxy, GrAuditTrail* auditTrail) - : INHERITED(resourceProvider, proxy, auditTrail) { + : INHERITED(resourceProvider, std::move(opMemoryPool), proxy, auditTrail) { + SkASSERT(fOpMemoryPool); +} + +void GrTextureOpList::deleteOp(int index) { + SkASSERT(index >= 0 && index < fRecordedOps.count()); + fOpMemoryPool->release(std::move(fRecordedOps[index])); +} + +void GrTextureOpList::deleteOps() { + for (int i = 0; i < fRecordedOps.count(); ++i) { + fOpMemoryPool->release(std::move(fRecordedOps[i])); + } + fRecordedOps.reset(); + fOpMemoryPool = nullptr; } GrTextureOpList::~GrTextureOpList() { + this->deleteOps(); } //////////////////////////////////////////////////////////////////////////////// @@ -107,7 +124,7 @@ bool GrTextureOpList::onExecute(GrOpFlushState* flushState) { } void GrTextureOpList::endFlush() { - fRecordedOps.reset(); + this->deleteOps(); INHERITED::endFlush(); } @@ -152,7 +169,7 @@ void GrTextureOpList::purgeOpsWithUninstantiatedProxies() { } if (hasUninstantiatedProxy) { // When instantiation of the proxy fails we drop the Op - fRecordedOps[i] = nullptr; + this->deleteOp(i); } } } diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h index d3e3e87ef3..83ec22c602 100644 --- a/src/gpu/GrTextureOpList.h +++ b/src/gpu/GrTextureOpList.h @@ -23,7 +23,7 @@ struct SkIRect; class GrTextureOpList final : public GrOpList { public: - GrTextureOpList(GrResourceProvider*, GrTextureProxy*, GrAuditTrail*); + GrTextureOpList(GrResourceProvider*, sk_sp<GrOpMemoryPool>, GrTextureProxy*, GrAuditTrail*); ~GrTextureOpList() override; /** @@ -61,12 +61,16 @@ public: SkDEBUGCODE(int numOps() const override { return fRecordedOps.count(); }) private: + void deleteOp(int index); + void deleteOps(); + void purgeOpsWithUninstantiatedProxies() override; void gatherProxyIntervals(GrResourceAllocator*) const override; void recordOp(std::unique_ptr<GrOp>); + // The memory for the ops in 'fRecordedOps' is actually stored in 'fOpMemoryPool' SkSTArray<2, std::unique_ptr<GrOp>, true> fRecordedOps; typedef GrOpList INHERITED; diff --git a/src/gpu/ccpr/GrCCDrawPathsOp.cpp b/src/gpu/ccpr/GrCCDrawPathsOp.cpp index ad078b2853..e3010f9669 100644 --- a/src/gpu/ccpr/GrCCDrawPathsOp.cpp +++ b/src/gpu/ccpr/GrCCDrawPathsOp.cpp @@ -22,9 +22,12 @@ static bool has_coord_transforms(const GrPaint& paint) { return false; } -std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::Make(GrContext*, const SkIRect& clipIBounds, - const SkMatrix& m, const GrShape& shape, - const SkRect& devBounds, GrPaint&& paint) { +std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::Make(GrContext* context, + const SkIRect& clipIBounds, + const SkMatrix& m, + const GrShape& shape, + const SkRect& devBounds, + GrPaint&& paint) { bool canStashPathMask = true; SkIRect looseClippedIBounds; devBounds.roundOut(&looseClippedIBounds); // GrCCPathParser might find slightly tighter bounds. @@ -34,9 +37,11 @@ std::unique_ptr<GrCCDrawPathsOp> GrCCDrawPathsOp::Make(GrContext*, const SkIRect return nullptr; } } - return std::unique_ptr<GrCCDrawPathsOp>(new GrCCDrawPathsOp(looseClippedIBounds, m, shape, - canStashPathMask, devBounds, - std::move(paint))); + + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrCCDrawPathsOp>(looseClippedIBounds, m, shape, canStashPathMask, + devBounds, std::move(paint)); } GrCCDrawPathsOp::GrCCDrawPathsOp(const SkIRect& looseClippedIBounds, const SkMatrix& m, diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp index 84f905cbc6..a1cecb3f88 100644 --- a/src/gpu/ccpr/GrCCPerFlushResources.cpp +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -53,8 +53,10 @@ public: sk_sp<const GrCCPerFlushResources> resources, sk_sp<GrTextureProxy> copyProxy, int baseInstance, int endInstance, const SkISize& drawBounds) { - return std::unique_ptr<GrDrawOp>(new CopyAtlasOp(std::move(resources), std::move(copyProxy), - baseInstance, endInstance, drawBounds)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<CopyAtlasOp>(std::move(resources), std::move(copyProxy), + baseInstance, endInstance, drawBounds); } const char* name() const override { return "CopyAtlasOp (CCPR)"; } @@ -96,8 +98,9 @@ public: static std::unique_ptr<GrDrawOp> Make(GrContext* context, sk_sp<const GrCCPerFlushResources> resources, CoverageCountBatchID batchID, const SkISize& drawBounds) { - return std::unique_ptr<GrDrawOp>(new RenderAtlasOp(std::move(resources), batchID, - drawBounds)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<RenderAtlasOp>(std::move(resources), batchID, drawBounds); } // GrDrawOp interface. diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index eb39079423..1ea3ddfae6 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -8,6 +8,7 @@ #include "GrAtlasTextOp.h" #include "GrContext.h" +#include "GrContextPriv.h" #include "GrMemoryPool.h" #include "GrOpFlushState.h" #include "GrResourceProvider.h" @@ -27,7 +28,9 @@ std::unique_ptr<GrAtlasTextOp> GrAtlasTextOp::MakeBitmap(GrContext* context, GrMaskFormat maskFormat, int glyphCount, bool needsTransform) { - std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint))); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + std::unique_ptr<GrAtlasTextOp> op = pool->allocate<GrAtlasTextOp>(std::move(paint)); switch (maskFormat) { case kA8_GrMaskFormat: @@ -57,7 +60,9 @@ std::unique_ptr<GrAtlasTextOp> GrAtlasTextOp::MakeDistanceField( const SkSurfaceProps& props, bool isAntiAliased, bool useLCD) { - std::unique_ptr<GrAtlasTextOp> op(new GrAtlasTextOp(std::move(paint))); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + std::unique_ptr<GrAtlasTextOp> op = pool->allocate<GrAtlasTextOp>(std::move(paint)); bool isBGR = SkPixelGeometryIsBGR(props.pixelGeometry()); bool isLCD = useLCD && SkPixelGeometryIsH(props.pixelGeometry()); diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp index 70fc160c95..612ff2085d 100644 --- a/src/gpu/ops/GrClearOp.cpp +++ b/src/gpu/ops/GrClearOp.cpp @@ -21,7 +21,9 @@ std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context, return nullptr; } - return std::unique_ptr<GrClearOp>(new GrClearOp(clip, color, dstProxy)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrClearOp>(clip, color, dstProxy); } std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context, @@ -30,7 +32,9 @@ std::unique_ptr<GrClearOp> GrClearOp::Make(GrContext* context, bool fullScreen) { SkASSERT(fullScreen || !rect.isEmpty()); - return std::unique_ptr<GrClearOp>(new GrClearOp(rect, color, fullScreen)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrClearOp>(rect, color, fullScreen); } GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* proxy) diff --git a/src/gpu/ops/GrClearStencilClipOp.cpp b/src/gpu/ops/GrClearStencilClipOp.cpp index 9a0e75a019..64985b707d 100644 --- a/src/gpu/ops/GrClearStencilClipOp.cpp +++ b/src/gpu/ops/GrClearStencilClipOp.cpp @@ -14,7 +14,9 @@ std::unique_ptr<GrOp> GrClearStencilClipOp::Make(GrContext* context, const GrFixedClip& clip, bool insideStencilMask, GrRenderTargetProxy* proxy) { - return std::unique_ptr<GrOp>(new GrClearStencilClipOp(clip, insideStencilMask, proxy)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrClearStencilClipOp>(clip, insideStencilMask, proxy); } void GrClearStencilClipOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrCopySurfaceOp.cpp b/src/gpu/ops/GrCopySurfaceOp.cpp index da8e910025..a90579bdfe 100644 --- a/src/gpu/ops/GrCopySurfaceOp.cpp +++ b/src/gpu/ops/GrCopySurfaceOp.cpp @@ -78,8 +78,9 @@ std::unique_ptr<GrOp> GrCopySurfaceOp::Make(GrContext* context, return nullptr; } - return std::unique_ptr<GrOp>(new GrCopySurfaceOp(dstProxy, srcProxy, - clippedSrcRect, clippedDstPoint)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrCopySurfaceOp>(dstProxy, srcProxy, clippedSrcRect, clippedDstPoint); } void GrCopySurfaceOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp index b784b0590e..cafb3e54c9 100644 --- a/src/gpu/ops/GrDashOp.cpp +++ b/src/gpu/ops/GrDashOp.cpp @@ -271,8 +271,10 @@ public: SkPaint::Cap cap, AAMode aaMode, bool fullDash, const GrUserStencilSettings* stencilSettings) { - return std::unique_ptr<GrDrawOp>( - new DashOp(std::move(paint), geometry, cap, aaMode, fullDash, stencilSettings)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<DashOp>(std::move(paint), geometry, cap, + aaMode, fullDash, stencilSettings); } const char* name() const override { return "DashOp"; } diff --git a/src/gpu/ops/GrDebugMarkerOp.cpp b/src/gpu/ops/GrDebugMarkerOp.cpp index ed54965e10..712e625d0b 100644 --- a/src/gpu/ops/GrDebugMarkerOp.cpp +++ b/src/gpu/ops/GrDebugMarkerOp.cpp @@ -17,7 +17,9 @@ std::unique_ptr<GrOp> GrDebugMarkerOp::Make(GrContext* context, GrRenderTargetProxy* proxy, const SkString& str) { - return std::unique_ptr<GrOp>(new GrDebugMarkerOp(proxy, str)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrDebugMarkerOp>(proxy, str); } void GrDebugMarkerOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp index a5a98f2e87..a8081fcff8 100644 --- a/src/gpu/ops/GrDrawPathOp.cpp +++ b/src/gpu/ops/GrDrawPathOp.cpp @@ -69,8 +69,9 @@ std::unique_ptr<GrDrawOp> GrDrawPathOp::Make(GrContext* context, GrPaint&& paint, GrAAType aaType, GrPath* path) { - return std::unique_ptr<GrDrawOp>( - new GrDrawPathOp(viewMatrix, std::move(paint), aaType, path)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aaType, path); } void GrDrawPathOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrOp.cpp b/src/gpu/ops/GrOp.cpp index f020cdef67..cab8ca1d18 100644 --- a/src/gpu/ops/GrOp.cpp +++ b/src/gpu/ops/GrOp.cpp @@ -7,57 +7,27 @@ #include "GrOp.h" -#include "GrMemoryPool.h" -#include "SkSpinlock.h" -#include "SkTo.h" - -// TODO I noticed a small benefit to using a larger exclusive pool for ops. Its very small, but -// seems to be mostly consistent. There is a lot in flux right now, but we should really revisit -// this. - - -// We use a global pool protected by a mutex(spinlock). Chrome may use the same GrContext on -// different threads. The GrContext is not used concurrently on different threads and there is a -// memory barrier between accesses of a context on different threads. Also, there may be multiple -// GrContexts and those contexts may be in use concurrently on different threads. -namespace { -#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) -static SkSpinlock gOpPoolSpinLock; -#endif -class MemoryPoolAccessor { -public: - -// We know in the Android framework there is only one GrContext. -#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) - MemoryPoolAccessor() {} - ~MemoryPoolAccessor() {} -#else - MemoryPoolAccessor() { gOpPoolSpinLock.acquire(); } - ~MemoryPoolAccessor() { gOpPoolSpinLock.release(); } -#endif - - GrMemoryPool* pool() const { - static GrMemoryPool gPool(16384, 16384); - return &gPool; - } -}; -} - int32_t GrOp::gCurrOpClassID = GrOp::kIllegalOpID; int32_t GrOp::gCurrOpUniqueID = GrOp::kIllegalOpID; +#ifdef SK_DEBUG void* GrOp::operator new(size_t size) { - return MemoryPoolAccessor().pool()->allocate(size); + // All GrOp-derived class should be allocated in a GrMemoryPool + SkASSERT(0); + return ::operator new(size); } void GrOp::operator delete(void* target) { - return MemoryPoolAccessor().pool()->release(target); + // All GrOp-derived class should be released from their owning GrMemoryPool + SkASSERT(0); + ::operator delete(target); } +#endif GrOp::GrOp(uint32_t classID) - : fClassID(classID) - , fUniqueID(kIllegalOpID) { + : fClassID(classID) + , fUniqueID(kIllegalOpID) { SkASSERT(classID == SkToU32(fClassID)); SkDEBUGCODE(fBoundsFlags = kUninitialized_BoundsFlag); } diff --git a/src/gpu/ops/GrOp.h b/src/gpu/ops/GrOp.h index 5d7922374c..5c776fc05d 100644 --- a/src/gpu/ops/GrOp.h +++ b/src/gpu/ops/GrOp.h @@ -104,6 +104,8 @@ public: return SkToBool(fBoundsFlags & kZeroArea_BoundsFlag); } +#ifdef SK_DEBUG + // All GrOp-derived classes should be allocated in and deleted from a GrMemoryPool void* operator new(size_t size); void operator delete(void* target); @@ -113,6 +115,7 @@ public: void operator delete(void* target, void* placement) { ::operator delete(target, placement); } +#endif /** * Helper for safely down-casting to a GrOp subclass diff --git a/src/gpu/ops/GrSemaphoreOp.cpp b/src/gpu/ops/GrSemaphoreOp.cpp index fedf6b723a..9beb2a606b 100644 --- a/src/gpu/ops/GrSemaphoreOp.cpp +++ b/src/gpu/ops/GrSemaphoreOp.cpp @@ -21,9 +21,9 @@ public: sk_sp<GrSemaphore> semaphore, GrRenderTargetProxy* proxy, bool forceFlush) { - return std::unique_ptr<GrSignalSemaphoreOp>(new GrSignalSemaphoreOp(std::move(semaphore), - proxy, - forceFlush)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrSignalSemaphoreOp>(std::move(semaphore), proxy, forceFlush); } const char* name() const override { return "SignalSemaphore"; } @@ -51,8 +51,9 @@ public: static std::unique_ptr<GrOp> Make(GrContext* context, sk_sp<GrSemaphore> semaphore, GrRenderTargetProxy* proxy) { - return std::unique_ptr<GrWaitSemaphoreOp>(new GrWaitSemaphoreOp(std::move(semaphore), - proxy)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrWaitSemaphoreOp>(std::move(semaphore), proxy); } const char* name() const override { return "WaitSemaphore"; } diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp index a2ec23000d..f61d11dd53 100644 --- a/src/gpu/ops/GrShadowRRectOp.cpp +++ b/src/gpu/ops/GrShadowRRectOp.cpp @@ -678,12 +678,14 @@ std::unique_ptr<GrDrawOp> Make(GrContext* context, SkScalar scaledRadius = SkScalarAbs(radius*matrixFactor); SkScalar scaledInsetWidth = SkScalarAbs(insetWidth*matrixFactor); - return std::unique_ptr<GrDrawOp>(new ShadowCircularRRectOp(color, bounds, - scaledRadius, - rrect.isOval(), - blurWidth, - scaledInsetWidth, - blurClamp)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<ShadowCircularRRectOp>(color, bounds, + scaledRadius, + rrect.isOval(), + blurWidth, + scaledInsetWidth, + blurClamp); } } diff --git a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h index b63728fe0f..e5229a713a 100644 --- a/src/gpu/ops/GrSimpleMeshDrawOpHelper.h +++ b/src/gpu/ops/GrSimpleMeshDrawOpHelper.h @@ -174,19 +174,22 @@ template <typename Op, typename... OpArgs> std::unique_ptr<GrDrawOp> GrSimpleMeshDrawOpHelper::FactoryHelper(GrContext* context, GrPaint&& paint, OpArgs... opArgs) { + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + MakeArgs makeArgs; makeArgs.fSRGBFlags = GrPipeline::SRGBFlagsFromPaint(paint); GrColor color = paint.getColor(); if (paint.isTrivial()) { makeArgs.fProcessorSet = nullptr; - return std::unique_ptr<GrDrawOp>(new Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); + return pool->allocate<Op>(makeArgs, color, std::forward<OpArgs>(opArgs)...); } else { - char* mem = (char*)GrOp::operator new(sizeof(Op) + sizeof(GrProcessorSet)); + char* mem = (char*) pool->allocate(sizeof(Op) + sizeof(GrProcessorSet)); char* setMem = mem + sizeof(Op); makeArgs.fProcessorSet = new (setMem) GrProcessorSet(std::move(paint)); - return std::unique_ptr<GrDrawOp>( - new (mem) Op(makeArgs, color, std::forward<OpArgs>(opArgs)...)); + + return std::unique_ptr<GrDrawOp>(new (mem) Op(makeArgs, color, + std::forward<OpArgs>(opArgs)...)); } } diff --git a/src/gpu/ops/GrStencilPathOp.cpp b/src/gpu/ops/GrStencilPathOp.cpp index 5b712cffbc..25dbf311e5 100644 --- a/src/gpu/ops/GrStencilPathOp.cpp +++ b/src/gpu/ops/GrStencilPathOp.cpp @@ -21,8 +21,10 @@ std::unique_ptr<GrOp> GrStencilPathOp::Make(GrContext* context, bool hasStencilClip, const GrScissorState& scissor, const GrPath* path) { - return std::unique_ptr<GrOp>(new GrStencilPathOp(viewMatrix, useHWAA, fillType, - hasStencilClip, scissor, path)); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<GrStencilPathOp>(viewMatrix, useHWAA, fillType, + hasStencilClip, scissor, path); } void GrStencilPathOp::onExecute(GrOpFlushState* state) { diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp index 80174bcb7d..e06d94f806 100644 --- a/src/gpu/ops/GrTextureOp.cpp +++ b/src/gpu/ops/GrTextureOp.cpp @@ -621,9 +621,11 @@ public: SkCanvas::SrcRectConstraint constraint, const SkMatrix& viewMatrix, sk_sp<GrColorSpaceXform> csxf) { - return std::unique_ptr<GrDrawOp>(new TextureOp(std::move(proxy), filter, color, srcRect, - dstRect, aaType, constraint, viewMatrix, - std::move(csxf))); + GrOpMemoryPool* pool = context->contextPriv().opMemoryPool(); + + return pool->allocate<TextureOp>(std::move(proxy), filter, color, + srcRect, dstRect, aaType, constraint, + viewMatrix, std::move(csxf)); } ~TextureOp() override { |