aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2018-06-19 13:09:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-19 19:51:20 +0000
commitc994a93b327235182c6d29a782c409b2c58476ae (patch)
treedba9ab1ff4a414e76da883f47ee90acbf0f27868 /src/gpu
parent4d75975b70c454288226afc03e512ad9bc2db5ac (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')
-rw-r--r--src/gpu/GrContext.cpp17
-rw-r--r--src/gpu/GrContextPriv.h4
-rw-r--r--src/gpu/GrDrawingManager.cpp12
-rw-r--r--src/gpu/GrMemoryPool.h2
-rw-r--r--src/gpu/GrOpList.cpp11
-rw-r--r--src/gpu/GrRenderTargetContext.cpp3
-rw-r--r--src/gpu/GrRenderTargetOpList.cpp25
-rw-r--r--src/gpu/GrRenderTargetOpList.h12
-rw-r--r--src/gpu/GrTextureOpList.cpp23
-rw-r--r--src/gpu/GrTextureOpList.h6
-rw-r--r--src/gpu/ccpr/GrCCDrawPathsOp.cpp17
-rw-r--r--src/gpu/ccpr/GrCCPerFlushResources.cpp11
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp9
-rw-r--r--src/gpu/ops/GrClearOp.cpp8
-rw-r--r--src/gpu/ops/GrClearStencilClipOp.cpp4
-rw-r--r--src/gpu/ops/GrCopySurfaceOp.cpp5
-rw-r--r--src/gpu/ops/GrDashOp.cpp6
-rw-r--r--src/gpu/ops/GrDebugMarkerOp.cpp4
-rw-r--r--src/gpu/ops/GrDrawPathOp.cpp5
-rw-r--r--src/gpu/ops/GrOp.cpp50
-rw-r--r--src/gpu/ops/GrOp.h3
-rw-r--r--src/gpu/ops/GrSemaphoreOp.cpp11
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp14
-rw-r--r--src/gpu/ops/GrSimpleMeshDrawOpHelper.h11
-rw-r--r--src/gpu/ops/GrStencilPathOp.cpp6
-rw-r--r--src/gpu/ops/GrTextureOp.cpp8
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 {