Simplify promise image lazy instantiation callbacks.
Now that we never re-fulfill a promise image we no longer need to deinstantiate
promise image proxies. They now can use kSingleUse callback semantics.
This was the only usage of the kDeinstantiate lazy callback type so it is
removed. The DeinstantiateProxyTracker is also no longer required and is
removed.
The GrTexture idle callback mechanism now uses GrReleaseProcHelper, which has
been extended to support chaining multiple callbacks together and an abandon()
method that aborts calling the callback in the destructor. It has been renamed
GrRefCntedCallback to reflect its more general usage.
Bug: skia:8800
Change-Id: I857c9eec57fdf706631a266ec8bea682d6657a7c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/196500
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index c4ff818..40ce8a1 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -45,7 +45,7 @@
virtual GrBackendFormat backendFormat() const = 0;
- void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
+ void setRelease(sk_sp<GrRefCntedCallback> releaseHelper) {
this->onSetRelease(releaseHelper);
fReleaseHelper = std::move(releaseHelper);
}
@@ -55,7 +55,7 @@
typedef void* ReleaseCtx;
typedef void (*ReleaseProc)(ReleaseCtx);
void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
- sk_sp<GrReleaseProcHelper> helper(new GrReleaseProcHelper(proc, ctx));
+ sk_sp<GrRefCntedCallback> helper(new GrRefCntedCallback(proc, ctx));
this->setRelease(std::move(helper));
}
@@ -132,7 +132,7 @@
private:
const char* getResourceType() const override { return "Surface"; }
- virtual void onSetRelease(sk_sp<GrReleaseProcHelper> releaseHelper) = 0;
+ virtual void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) = 0;
void invokeReleaseProc() {
// Depending on the ref count of fReleaseHelper this may or may not actually trigger the
// ReleaseProc to be called.
@@ -143,7 +143,7 @@
int fWidth;
int fHeight;
GrInternalSurfaceFlags fSurfaceFlags;
- sk_sp<GrReleaseProcHelper> fReleaseHelper;
+ sk_sp<GrRefCntedCallback> fReleaseHelper;
typedef GrGpuResource INHERITED;
};
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 542e785..4a7935f 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -57,9 +57,10 @@
* will always be called before the texture is destroyed, even in unusual shutdown scenarios
* (e.g. GrContext::abandonContext()).
*/
- using IdleProc = void(void*);
- virtual void setIdleProc(IdleProc, void* context) = 0;
- virtual void* idleContext() const = 0;
+ virtual void addIdleProc(sk_sp<GrRefCntedCallback> callback) {
+ callback->addChild(std::move(fIdleCallback));
+ fIdleCallback = std::move(callback);
+ }
/** Access methods that are only to be used within Skia code. */
inline GrTexturePriv texturePriv();
@@ -70,7 +71,15 @@
virtual bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) = 0;
+ sk_sp<GrRefCntedCallback> fIdleCallback;
+
+ void willRemoveLastRefOrPendingIO() override {
+ // We're about to be idle in the resource cache. Do our part to trigger the idle callback.
+ fIdleCallback.reset();
+ }
+
private:
+
void computeScratchKey(GrScratchKey*) const override;
size_t onGpuMemorySize() const override;
void markMipMapsDirty();
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index c9eec6c..7c572bb 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -208,8 +208,6 @@
enum class LazyInstantiationType {
kSingleUse, // Instantiation callback is allowed to be called only once.
kMultipleUse, // Instantiation callback can be called multiple times.
- kDeinstantiate, // Instantiation callback can be called multiple times,
- // but we will deinstantiate the proxy after every flush.
};
enum class LazyState {
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 63ceb4d..d6ea362 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -1554,20 +1554,44 @@
return kUnknown_GrPixelConfig;
}
-class GrReleaseProcHelper : public SkRefCnt {
+/**
+ * Ref-counted object that calls a callback from its destructor. These can be chained together. Any
+ * owner can cancel calling the callback via abandon().
+ */
+class GrRefCntedCallback : public SkRefCnt {
public:
- // These match the definitions in SkImage, from whence they came
- typedef void* ReleaseCtx;
- typedef void (*ReleaseProc)(ReleaseCtx);
+ using Context = void*;
+ using Callback = void (*)(Context);
- GrReleaseProcHelper(ReleaseProc proc, ReleaseCtx ctx) : fReleaseProc(proc), fReleaseCtx(ctx) {
+ GrRefCntedCallback(Callback proc, Context ctx) : fReleaseProc(proc), fReleaseCtx(ctx) {
SkASSERT(proc);
}
- ~GrReleaseProcHelper() override { fReleaseProc(fReleaseCtx); }
+ ~GrRefCntedCallback() override { fReleaseProc ? fReleaseProc(fReleaseCtx) : void(); }
+
+ /**
+ * After abandon is called the release proc will no longer be called in the destructor. This
+ * does not recurse on child release procs or unref them.
+ */
+ void abandon() {
+ fReleaseProc = nullptr;
+ fReleaseCtx = nullptr;
+ }
+
+ /** Adds another GrRefCntedCallback that this will unref in its destructor. */
+ void addChild(sk_sp<GrRefCntedCallback> next) {
+ if (!fNext) {
+ fNext = std::move(next);
+ return;
+ }
+ fNext->addChild(std::move(next));
+ }
+
+ Context context() const { return fReleaseCtx; }
private:
- ReleaseProc fReleaseProc;
- ReleaseCtx fReleaseCtx;
+ sk_sp<GrRefCntedCallback> fNext;
+ Callback fReleaseProc;
+ Context fReleaseCtx;
};
#endif