Avoid unbounded listener growth on SkImage_Lazy when textures are purged
Generalizes the system used on SkPathRef where a GrTexture's key
destructor signals that a listener on the image can be removed via
the unique key custom data.
Removes texturesAreCacheable() from SkImageGenerator. This was used to
prevent unbounded growth in a narrow situation related to
GrBackendTextureImageGenerator.
Change-Id: I3c605da099acfac94751e793331e356a0979d359
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274038
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index edea530..ece4e5a 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -5,6 +5,8 @@
* found in the LICENSE file.
*/
+#include "src/gpu/GrSoftwarePathRenderer.h"
+
#include "include/private/SkSemaphore.h"
#include "src/core/SkTaskGroup.h"
#include "src/core/SkTraceEvent.h"
@@ -19,8 +21,8 @@
#include "src/gpu/GrRecordingContextPriv.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/GrSWMaskHelper.h"
-#include "src/gpu/GrSoftwarePathRenderer.h"
#include "src/gpu/GrSurfaceContextPriv.h"
+#include "src/gpu/SkGr.h"
#include "src/gpu/geometry/GrShape.h"
#include "src/gpu/ops/GrDrawOp.h"
@@ -215,20 +217,6 @@
GrAA fAA;
};
-// When the SkPathRef genID changes, invalidate a corresponding GrResource described by key.
-class PathInvalidator : public SkPathRef::GenIDChangeListener {
-public:
- PathInvalidator(const GrUniqueKey& key, uint32_t contextUniqueID)
- : fMsg(key, contextUniqueID) {}
-
-private:
- GrUniqueKeyInvalidatedMessage fMsg;
-
- void onChange() override {
- SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
- }
-};
-
}
////////////////////////////////////////////////////////////////////////////////
@@ -379,25 +367,11 @@
SkASSERT(view.origin() == kTopLeft_GrSurfaceOrigin);
// We will add an invalidator to the path so that if the path goes away we will
- // delete or recycle the mask texture. We also invalidate the other way: If the mask
- // goes away we signal that the invalidator on the path can be removed. This prevents
- // unbounded growth of invalidators on long lived paths.
- auto invalidator =
- sk_make_sp<PathInvalidator>(maskKey, args.fContext->priv().contextID());
-
- auto invalidateInvalidator = [](const void* ptr, void* /*context*/) {
- auto invalidator = reinterpret_cast<const sk_sp<PathInvalidator>*>(ptr);
- (*invalidator)->markShouldUnregisterFromPath();
- delete invalidator;
- };
- auto data = SkData::MakeWithProc(new sk_sp<PathInvalidator>(invalidator),
- sizeof(sk_sp<PathInvalidator>),
- invalidateInvalidator,
- nullptr);
- maskKey.setCustomData(std::move(data));
+ // delete or recycle the mask texture.
+ auto listener = GrMakeUniqueKeyInvalidationListener(&maskKey,
+ args.fContext->priv().contextID());
fProxyProvider->assignUniqueKeyToProxy(maskKey, view.asTextureProxy());
-
- args.fShape->addGenIDChangeListener(std::move(invalidator));
+ args.fShape->addGenIDChangeListener(std::move(listener));
}
}
SkASSERT(view);