aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-03-08 15:27:36 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-08 21:05:21 +0000
commit4684f82ebca85d4c7043e5c1028e34cf5631da32 (patch)
tree6e640d1b212ab614fa19ccd4e43c5adff440dacd /src
parent3adc12213b2d1efbe417476517ff3381af17a311 (diff)
Add ability to uninstantiate lazy proxies after every flush.
Bug: skia: Change-Id: Id32540cda54a9c5e3e6cb721776699be3cc8ac1a Reviewed-on: https://skia-review.googlesource.com/113263 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrDrawingManager.cpp5
-rw-r--r--src/gpu/GrOnFlushResourceProvider.cpp2
-rw-r--r--src/gpu/GrOpFlushState.h8
-rw-r--r--src/gpu/GrResourceAllocator.cpp10
-rw-r--r--src/gpu/GrResourceAllocator.h4
-rw-r--r--src/gpu/GrSurfaceProxyPriv.h6
-rw-r--r--src/gpu/GrUninstantiateProxyTracker.cpp30
-rw-r--r--src/gpu/GrUninstantiateProxyTracker.h30
-rw-r--r--src/gpu/mock/GrMockGpu.cpp16
-rw-r--r--src/gpu/mock/GrMockGpu.h4
-rw-r--r--src/gpu/mock/GrMockTexture.h25
11 files changed, 134 insertions, 6 deletions
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 62db98edd4..63d1175930 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -214,7 +214,8 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
}
GrResourceAllocator::AssignError error = GrResourceAllocator::AssignError::kNoError;
- while (alloc.assign(&startIndex, &stopIndex, &error)) {
+ while (alloc.assign(&startIndex, &stopIndex, flushState.uninstantiateProxyTracker(),
+ &error)) {
if (GrResourceAllocator::AssignError::kFailedProxyInstantiation == error) {
for (int i = startIndex; i < stopIndex; ++i) {
fOpLists[i]->purgeOpsWithUninstantiatedProxies();
@@ -231,6 +232,8 @@ GrSemaphoresSubmitted GrDrawingManager::internalFlush(GrSurfaceProxy*,
GrSemaphoresSubmitted result = gpu->finishFlush(numSemaphores, backendSemaphores);
+ flushState.uninstantiateProxyTracker()->uninstantiateAllProxies();
+
// We always have to notify the cache when it requested a flush so it can reset its state.
if (flushed || type == GrResourceCache::FlushType::kCacheRequested) {
fContext->contextPriv().getResourceCache()->notifyFlushOccurred(type);
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index 9abd3f63b2..c33bc514da 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -85,6 +85,8 @@ bool GrOnFlushResourceProvider::instatiateProxy(GrSurfaceProxy* proxy) {
auto resourceProvider = fDrawingMgr->getContext()->contextPriv().resourceProvider();
if (GrSurfaceProxy::LazyState::kNot != proxy->lazyInstantiationState()) {
+ // DDL TODO: Decide if we ever plan to have these proxies use the GrUninstantiateTracker
+ // to support unistantiating them at the end of a flush.
return proxy->priv().doLazyInstantiation(resourceProvider);
}
diff --git a/src/gpu/GrOpFlushState.h b/src/gpu/GrOpFlushState.h
index 4f210a83d2..a6f0c26e5e 100644
--- a/src/gpu/GrOpFlushState.h
+++ b/src/gpu/GrOpFlushState.h
@@ -12,6 +12,7 @@
#include "GrAppliedClip.h"
#include "GrBufferAllocPool.h"
#include "GrDeferredUpload.h"
+#include "GrUninstantiateProxyTracker.h"
#include "SkArenaAlloc.h"
#include "SkArenaAllocList.h"
#include "ops/GrMeshDrawOp.h"
@@ -96,6 +97,10 @@ public:
// permissible).
GrAtlasManager* atlasManager() const final;
+ GrUninstantiateProxyTracker* uninstantiateProxyTracker() {
+ return &fUninstantiateProxyTracker;
+ }
+
private:
/** GrMeshDrawOp::Target override. */
SkArenaAlloc* pipelineArena() override { return &fArena; }
@@ -150,6 +155,9 @@ private:
SkArenaAllocList<Draw>::Iter fCurrDraw;
int fCurrMesh;
SkArenaAllocList<InlineUpload>::Iter fCurrUpload;
+
+ // Used to track the proxies that need to be uninstantiated after we finish a flush
+ GrUninstantiateProxyTracker fUninstantiateProxyTracker;
};
#endif
diff --git a/src/gpu/GrResourceAllocator.cpp b/src/gpu/GrResourceAllocator.cpp
index f41169c110..d3895073aa 100644
--- a/src/gpu/GrResourceAllocator.cpp
+++ b/src/gpu/GrResourceAllocator.cpp
@@ -16,6 +16,7 @@
#include "GrSurfaceProxy.h"
#include "GrSurfaceProxyPriv.h"
#include "GrTextureProxy.h"
+#include "GrUninstantiateProxyTracker.h"
void GrResourceAllocator::Interval::assign(sk_sp<GrSurface> s) {
SkASSERT(!fAssignedSurface);
@@ -200,7 +201,9 @@ void GrResourceAllocator::expire(unsigned int curIndex) {
}
}
-bool GrResourceAllocator::assign(int* startIndex, int* stopIndex, AssignError* outError) {
+bool GrResourceAllocator::assign(int* startIndex, int* stopIndex,
+ GrUninstantiateProxyTracker* uninstantiateTracker,
+ AssignError* outError) {
SkASSERT(outError);
*outError = AssignError::kNoError;
@@ -252,6 +255,11 @@ bool GrResourceAllocator::assign(int* startIndex, int* stopIndex, AssignError* o
if (GrSurfaceProxy::LazyState::kNot != cur->proxy()->lazyInstantiationState()) {
if (!cur->proxy()->priv().doLazyInstantiation(fResourceProvider)) {
*outError = AssignError::kFailedProxyInstantiation;
+ } else {
+ if (GrSurfaceProxy::LazyInstantiationType::kUninstantiate ==
+ cur->proxy()->priv().lazyInstantiationType()) {
+ uninstantiateTracker->addProxy(cur->proxy());
+ }
}
} else if (sk_sp<GrSurface> surface = this->findSurfaceFor(cur->proxy(), needsStencil)) {
// TODO: make getUniqueKey virtual on GrSurfaceProxy
diff --git a/src/gpu/GrResourceAllocator.h b/src/gpu/GrResourceAllocator.h
index f25bef309e..427ff327cb 100644
--- a/src/gpu/GrResourceAllocator.h
+++ b/src/gpu/GrResourceAllocator.h
@@ -17,6 +17,7 @@
#include "SkTMultiMap.h"
class GrResourceProvider;
+class GrUninstantiateProxyTracker;
/*
* The ResourceAllocator explicitly distributes GPU resources at flush time. It operates by
@@ -68,7 +69,8 @@ public:
// If this happens, the caller should remove all ops which reference an uninstantiated proxy.
// This is used to execute a portion of the queued opLists in order to reduce the total
// amount of GPU resources required.
- bool assign(int* startIndex, int* stopIndex, AssignError* outError);
+ bool assign(int* startIndex, int* stopIndex, GrUninstantiateProxyTracker*,
+ AssignError* outError);
void markEndOfOpList(int opListIndex);
diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h
index e5d1f906a2..10203b71d0 100644
--- a/src/gpu/GrSurfaceProxyPriv.h
+++ b/src/gpu/GrSurfaceProxyPriv.h
@@ -74,6 +74,12 @@ public:
return fProxy->fLazyInstantiationType;
}
+ bool isSafeToUninstantiate() const {
+ return SkToBool(fProxy->fTarget) &&
+ SkToBool(fProxy->fLazyInstantiateCallback) &&
+ GrSurfaceProxy::LazyInstantiationType::kUninstantiate == lazyInstantiationType();
+ }
+
void testingOnly_setLazyInstantiationType(GrSurfaceProxy::LazyInstantiationType lazyType) {
fProxy->fLazyInstantiationType = lazyType;
}
diff --git a/src/gpu/GrUninstantiateProxyTracker.cpp b/src/gpu/GrUninstantiateProxyTracker.cpp
new file mode 100644
index 0000000000..c4da21b9dc
--- /dev/null
+++ b/src/gpu/GrUninstantiateProxyTracker.cpp
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrUninstantiateProxyTracker.h"
+
+#include "GrSurfaceProxy.h"
+#include "GrSurfaceProxyPriv.h"
+
+void GrUninstantiateProxyTracker::addProxy(GrSurfaceProxy* proxy) {
+#ifdef SK_DEBUG
+ using LazyType = GrSurfaceProxy::LazyInstantiationType;
+ SkASSERT(LazyType::kUninstantiate == proxy->priv().lazyInstantiationType());
+ for (int i = 0; i < fProxies.count(); ++i) {
+ SkASSERT(proxy != fProxies[i]);
+ }
+#endif
+ fProxies.push_back(proxy);
+}
+
+void GrUninstantiateProxyTracker::uninstantiateAllProxies() {
+ for (int i = 0; i < fProxies.count(); ++i) {
+ GrSurfaceProxy* proxy = fProxies[i];
+ SkASSERT(proxy->priv().isSafeToUninstantiate());
+ proxy->deInstantiate();
+ }
+}
diff --git a/src/gpu/GrUninstantiateProxyTracker.h b/src/gpu/GrUninstantiateProxyTracker.h
new file mode 100644
index 0000000000..a862bb640c
--- /dev/null
+++ b/src/gpu/GrUninstantiateProxyTracker.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrUninstantiateProxyTracker_DEFINED
+#define GrUninstantiateProxyTracker_DEFINED
+
+#include "SkTArray.h"
+
+class GrSurfaceProxy;
+
+class GrUninstantiateProxyTracker {
+public:
+ GrUninstantiateProxyTracker() {}
+
+ // Adds a proxy which will be uninstantiated at the end of flush. The same proxy may not be
+ // added multiple times.
+ void addProxy(GrSurfaceProxy* proxy);
+
+ // Loops through all tracked proxies and uninstantiates them.
+ void uninstantiateAllProxies();
+
+private:
+ SkTArray<GrSurfaceProxy*> fProxies;
+};
+
+#endif
diff --git a/src/gpu/mock/GrMockGpu.cpp b/src/gpu/mock/GrMockGpu.cpp
index 9341472090..e31a775730 100644
--- a/src/gpu/mock/GrMockGpu.cpp
+++ b/src/gpu/mock/GrMockGpu.cpp
@@ -78,6 +78,22 @@ sk_sp<GrTexture> GrMockGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgete
return sk_sp<GrTexture>(new GrMockTexture(this, budgeted, desc, mipMapsStatus, info));
}
+sk_sp<GrTexture> GrMockGpu::onWrapBackendTexture(const GrBackendTexture& tex,
+ GrWrapOwnership ownership) {
+ GrSurfaceDesc desc;
+ desc.fWidth = tex.width();
+ desc.fHeight = tex.height();
+ SkASSERT(tex.getMockTextureInfo());
+ GrMockTextureInfo info = *tex.getMockTextureInfo();
+ desc.fConfig = info.fConfig;
+
+ GrMipMapsStatus mipMapsStatus = tex.hasMipMaps() ? GrMipMapsStatus::kValid
+ : GrMipMapsStatus::kNotAllocated;
+
+ return sk_sp<GrTexture>(new GrMockTexture(this, GrMockTexture::kWrapped, desc, mipMapsStatus,
+ info));
+}
+
GrBuffer* GrMockGpu::onCreateBuffer(size_t sizeInBytes, GrBufferType type,
GrAccessPattern accessPattern, const void*) {
return new GrMockBuffer(this, sizeInBytes, type, accessPattern);
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index d3e665c2e4..00b19ac82e 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -58,9 +58,7 @@ private:
sk_sp<GrTexture> onCreateTexture(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel[],
int mipLevelCount) override;
- sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override {
- return nullptr;
- }
+ sk_sp<GrTexture> onWrapBackendTexture(const GrBackendTexture&, GrWrapOwnership) override;
sk_sp<GrTexture> onWrapRenderableBackendTexture(const GrBackendTexture&,
int sampleCnt,
diff --git a/src/gpu/mock/GrMockTexture.h b/src/gpu/mock/GrMockTexture.h
index 8a5a1758a6..5ed785e052 100644
--- a/src/gpu/mock/GrMockTexture.h
+++ b/src/gpu/mock/GrMockTexture.h
@@ -20,6 +20,14 @@ public:
: GrMockTexture(gpu, desc, mipMapsStatus, info) {
this->registerWithCache(budgeted);
}
+
+ enum Wrapped { kWrapped };
+ GrMockTexture(GrMockGpu* gpu, Wrapped, const GrSurfaceDesc& desc,
+ GrMipMapsStatus mipMapsStatus, const GrMockTextureInfo& info)
+ : GrMockTexture(gpu, desc, mipMapsStatus, info) {
+ this->registerWithCacheWrapped();
+ }
+
~GrMockTexture() override {}
GrBackendObject getTextureHandle() const override {
@@ -44,11 +52,28 @@ protected:
mipMapsStatus)
, fInfo(info) {}
+ void onRelease() override {
+ this->invokeReleaseProc();
+ INHERITED::onRelease();
+ }
+
+ void onAbandon() override {
+ this->invokeReleaseProc();
+ INHERITED::onAbandon();
+ }
+
bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override {
return false;
}
private:
+ void invokeReleaseProc() {
+ if (fReleaseHelper) {
+ // Depending on the ref count of fReleaseHelper this may or may not actually trigger the
+ // ReleaseProc to be called.
+ fReleaseHelper.reset();
+ }
+ }
GrMockTextureInfo fInfo;
sk_sp<GrReleaseProcHelper> fReleaseHelper;