Add ref counted wrapped around GrTexture ReleaseProc
Bug: skia: Change-Id: I0cd11a539fd6b16d4b3f9512694f84e0a429518c Reviewed-on: https://skia-review.googlesource.com/101341 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
aa71c899fd
commit
6a0176bf03
@ -55,11 +55,16 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
// These match the definitions in SkImage, for whence they came
|
||||
virtual void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) = 0;
|
||||
|
||||
// These match the definitions in SkImage, from whence they came.
|
||||
// TODO: Either move Chrome over to new api or remove their need to call this on GrTexture
|
||||
typedef void* ReleaseCtx;
|
||||
typedef void (*ReleaseProc)(ReleaseCtx);
|
||||
|
||||
virtual void setRelease(ReleaseProc proc, ReleaseCtx ctx) = 0;
|
||||
void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
|
||||
sk_sp<GrReleaseProcHelper> helper(new GrReleaseProcHelper(proc, ctx));
|
||||
this->setRelease(std::move(helper));
|
||||
}
|
||||
|
||||
/** Access methods that are only to be used within Skia code. */
|
||||
inline GrTexturePriv texturePriv();
|
||||
|
@ -1048,4 +1048,20 @@ static inline GrPixelConfigIsClamped GrGetPixelConfigIsClamped(GrPixelConfig con
|
||||
: GrPixelConfigIsClamped::kYes;
|
||||
}
|
||||
|
||||
class GrReleaseProcHelper : public SkRefCnt {
|
||||
public:
|
||||
// These match the definitions in SkImage, from whence they came
|
||||
typedef void* ReleaseCtx;
|
||||
typedef void (*ReleaseProc)(ReleaseCtx);
|
||||
|
||||
GrReleaseProcHelper(ReleaseProc proc, ReleaseCtx ctx) : fReleaseProc(proc), fReleaseCtx(ctx) {}
|
||||
~GrReleaseProcHelper() override {
|
||||
fReleaseProc(fReleaseCtx);
|
||||
}
|
||||
|
||||
private:
|
||||
ReleaseProc fReleaseProc;
|
||||
ReleaseCtx fReleaseCtx;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -229,7 +229,10 @@ sk_sp<GrTextureProxy> GrAHardwareBufferImageGenerator::makeProxy(GrContext* cont
|
||||
eglDestroyImageKHR(display, image);
|
||||
return nullptr;
|
||||
}
|
||||
tex->setRelease(deleteImageTexture, new BufferCleanupHelper(image, display));
|
||||
sk_sp<GrReleaseProcHelper> releaseHelper(
|
||||
new GrReleaseProcHelper(deleteImageTexture, new BufferCleanupHelper(image, display)));
|
||||
|
||||
tex->setRelease(std::move(releaseHelper));
|
||||
|
||||
// We fail this assert, if the context has changed. This will be fully handled after
|
||||
// skbug.com/6812 is ready.
|
||||
|
@ -162,9 +162,15 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
|
||||
}
|
||||
refHelper->fBorrowedTexture = tex.get();
|
||||
|
||||
sk_sp<GrReleaseProcHelper> releaseHelper(
|
||||
new GrReleaseProcHelper(ReleaseRefHelper_TextureReleaseProc, refHelper));
|
||||
|
||||
// By setting this release proc on the texture we are passing our ref on the
|
||||
// refHelper to the texture.
|
||||
tex->setRelease(ReleaseRefHelper_TextureReleaseProc, refHelper);
|
||||
// DDL TODO: Once we are start reusing Lazy Proxies, we need to add a ref to the
|
||||
// refHelper here, we'll still move the releaseHelper though since the texture
|
||||
// will be the only one ever calling that release proc.
|
||||
tex->setRelease(std::move(releaseHelper));
|
||||
}
|
||||
|
||||
return tex;
|
||||
|
@ -383,15 +383,18 @@ sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(
|
||||
desc.fConfig = backendTex.config();
|
||||
GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
|
||||
|
||||
sk_sp<GrReleaseProcHelper> releaseHelper;
|
||||
if (releaseProc) {
|
||||
releaseHelper.reset(new GrReleaseProcHelper(releaseProc, releaseCtx));
|
||||
}
|
||||
|
||||
sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
|
||||
[backendTex, ownership, releaseProc, releaseCtx]
|
||||
[backendTex, ownership, releaseHelper]
|
||||
(GrResourceProvider* resourceProvider, GrSurfaceOrigin* /*outOrigin*/) {
|
||||
if (!resourceProvider) {
|
||||
// This lazy proxy was never initialized. If it has a releaseProc we must call
|
||||
// it now so that the client knows they can free the underlying backend object.
|
||||
if (releaseProc) {
|
||||
releaseProc(releaseCtx);
|
||||
}
|
||||
// This lazy proxy was never initialized. If this had a releaseHelper it will
|
||||
// get unrefed when we delete this lambda and will call the release proc so that
|
||||
// the client knows they can free the underlying backend object.
|
||||
return sk_sp<GrTexture>();
|
||||
}
|
||||
|
||||
@ -400,8 +403,10 @@ sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(
|
||||
if (!tex) {
|
||||
return sk_sp<GrTexture>();
|
||||
}
|
||||
if (releaseProc) {
|
||||
tex->setRelease(releaseProc, releaseCtx);
|
||||
if (releaseHelper) {
|
||||
// DDL TODO: once we are reusing lazy proxies, remove this move and hold onto to
|
||||
// the ref till the lambda goes away.
|
||||
tex->setRelease(std::move(releaseHelper));
|
||||
}
|
||||
SkASSERT(!tex->asRenderTarget()); // Strictly a GrTexture
|
||||
// Make sure we match how we created the proxy with SkBudgeted::kNo
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
~GrGLTexture() override {
|
||||
// check that invokeReleaseProc has been called (if needed)
|
||||
SkASSERT(!fReleaseProc);
|
||||
SkASSERT(!fReleaseHelper);
|
||||
}
|
||||
|
||||
GrBackendObject getTextureHandle() const override;
|
||||
@ -44,9 +44,8 @@ public:
|
||||
|
||||
void textureParamsModified() override { fTexParams.invalidate(); }
|
||||
|
||||
void setRelease(ReleaseProc proc, ReleaseCtx ctx) override {
|
||||
fReleaseProc = proc;
|
||||
fReleaseCtx = ctx;
|
||||
void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
|
||||
fReleaseHelper = std::move(releaseHelper);
|
||||
}
|
||||
|
||||
// These functions are used to track the texture parameters associated with the texture.
|
||||
@ -90,9 +89,10 @@ protected:
|
||||
|
||||
private:
|
||||
void invokeReleaseProc() {
|
||||
if (fReleaseProc) {
|
||||
fReleaseProc(fReleaseCtx);
|
||||
fReleaseProc = nullptr;
|
||||
if (fReleaseHelper) {
|
||||
// Depending on the ref count of fReleaseHelper this may or may not actually trigger the
|
||||
// ReleaseProc to be called.
|
||||
fReleaseHelper.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,8 +104,7 @@ private:
|
||||
GrBackendObjectOwnership fTextureIDOwnership;
|
||||
bool fBaseLevelHasBeenBoundToFBO = false;
|
||||
|
||||
ReleaseProc fReleaseProc = nullptr;
|
||||
ReleaseCtx fReleaseCtx = nullptr;
|
||||
sk_sp<GrReleaseProcHelper> fReleaseHelper;
|
||||
|
||||
typedef GrTexture INHERITED;
|
||||
};
|
||||
|
@ -20,11 +20,8 @@ public:
|
||||
: GrMockTexture(gpu, desc, mipMapsStatus, info) {
|
||||
this->registerWithCache(budgeted);
|
||||
}
|
||||
~GrMockTexture() override {
|
||||
if (fReleaseProc) {
|
||||
fReleaseProc(fReleaseCtx);
|
||||
}
|
||||
}
|
||||
~GrMockTexture() override {}
|
||||
|
||||
GrBackendObject getTextureHandle() const override {
|
||||
return reinterpret_cast<GrBackendObject>(&fInfo);
|
||||
}
|
||||
@ -34,9 +31,8 @@ public:
|
||||
}
|
||||
|
||||
void textureParamsModified() override {}
|
||||
void setRelease(ReleaseProc proc, ReleaseCtx ctx) override {
|
||||
fReleaseProc = proc;
|
||||
fReleaseCtx = ctx;
|
||||
void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
|
||||
fReleaseHelper = std::move(releaseHelper);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -46,18 +42,15 @@ protected:
|
||||
: GrSurface(gpu, desc)
|
||||
, INHERITED(gpu, desc, kITexture2DSampler_GrSLType, GrSamplerState::Filter::kMipMap,
|
||||
mipMapsStatus)
|
||||
, fInfo(info)
|
||||
, fReleaseProc(nullptr)
|
||||
, fReleaseCtx(nullptr) {}
|
||||
, fInfo(info) {}
|
||||
|
||||
bool onStealBackendTexture(GrBackendTexture*, SkImage::BackendTextureReleaseProc*) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
GrMockTextureInfo fInfo;
|
||||
ReleaseProc fReleaseProc;
|
||||
ReleaseCtx fReleaseCtx;
|
||||
GrMockTextureInfo fInfo;
|
||||
sk_sp<GrReleaseProcHelper> fReleaseHelper;
|
||||
|
||||
typedef GrTexture INHERITED;
|
||||
};
|
||||
|
@ -33,12 +33,11 @@ public:
|
||||
|
||||
bool reallocForMipmap(GrMtlGpu* gpu, uint32_t mipLevels);
|
||||
|
||||
void setRelease(GrTexture::ReleaseProc proc, GrTexture::ReleaseCtx ctx) override {
|
||||
void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
|
||||
// Since all MTLResources are inherently ref counted, we can call the Release proc when we
|
||||
// delete the GrMtlTexture without worry of the MTLTexture getting deleted before it is done
|
||||
// on the GPU.
|
||||
fReleaseProc = proc;
|
||||
fReleaseCtx = ctx;
|
||||
fReleaseHelper = std::move(releaseHelper);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -64,8 +63,7 @@ private:
|
||||
|
||||
id<MTLTexture> fTexture;
|
||||
|
||||
ReleaseProc fReleaseProc = nullptr;
|
||||
ReleaseCtx fReleaseCtx = nullptr;
|
||||
sk_sp<GrReleaseProcHelper> fReleaseHelper;
|
||||
|
||||
typedef GrTexture INHERITED;
|
||||
};
|
||||
|
@ -152,13 +152,13 @@ void GrVkImage::abandonImage() {
|
||||
}
|
||||
}
|
||||
|
||||
void GrVkImage::setResourceRelease(ReleaseProc proc, ReleaseCtx ctx) {
|
||||
void GrVkImage::setResourceRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
|
||||
// Forward the release proc on to GrVkImage::Resource
|
||||
fResource->setRelease(proc, ctx);
|
||||
fResource->setRelease(std::move(releaseHelper));
|
||||
}
|
||||
|
||||
void GrVkImage::Resource::freeGPUData(const GrVkGpu* gpu) const {
|
||||
SkASSERT(!fReleaseProc);
|
||||
SkASSERT(!fReleaseHelper);
|
||||
VK_CALL(gpu, DestroyImage(gpu->device(), fImage, nullptr));
|
||||
bool isLinear = (VK_IMAGE_TILING_LINEAR == fImageTiling);
|
||||
GrVkMemory::FreeImageMemory(gpu, isLinear, fAlloc);
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
typedef void* ReleaseCtx;
|
||||
typedef void (*ReleaseProc)(ReleaseCtx);
|
||||
|
||||
void setResourceRelease(ReleaseProc proc, ReleaseCtx ctx);
|
||||
void setResourceRelease(sk_sp<GrReleaseProcHelper> releaseHelper);
|
||||
|
||||
protected:
|
||||
void releaseImage(const GrVkGpu* gpu);
|
||||
@ -98,23 +98,18 @@ private:
|
||||
class Resource : public GrVkResource {
|
||||
public:
|
||||
Resource()
|
||||
: INHERITED()
|
||||
, fReleaseProc(nullptr)
|
||||
, fReleaseCtx(nullptr)
|
||||
, fImage(VK_NULL_HANDLE) {
|
||||
: fImage(VK_NULL_HANDLE) {
|
||||
fAlloc.fMemory = VK_NULL_HANDLE;
|
||||
fAlloc.fOffset = 0;
|
||||
}
|
||||
|
||||
Resource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
|
||||
: fReleaseProc(nullptr)
|
||||
, fReleaseCtx(nullptr)
|
||||
, fImage(image)
|
||||
: fImage(image)
|
||||
, fAlloc(alloc)
|
||||
, fImageTiling(tiling) {}
|
||||
|
||||
~Resource() override {
|
||||
SkASSERT(!fReleaseProc);
|
||||
SkASSERT(!fReleaseHelper);
|
||||
}
|
||||
|
||||
#ifdef SK_TRACE_VK_RESOURCES
|
||||
@ -122,18 +117,16 @@ private:
|
||||
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
|
||||
}
|
||||
#endif
|
||||
void setRelease(ReleaseProc proc, ReleaseCtx ctx) const {
|
||||
fReleaseProc = proc;
|
||||
fReleaseCtx = ctx;
|
||||
void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
|
||||
fReleaseHelper = std::move(releaseHelper);
|
||||
}
|
||||
protected:
|
||||
mutable ReleaseProc fReleaseProc;
|
||||
mutable ReleaseCtx fReleaseCtx;
|
||||
mutable sk_sp<GrReleaseProcHelper> fReleaseHelper;
|
||||
|
||||
private:
|
||||
void freeGPUData(const GrVkGpu* gpu) const override;
|
||||
void abandonGPUData() const override {
|
||||
SkASSERT(!fReleaseProc);
|
||||
SkASSERT(!fReleaseHelper);
|
||||
}
|
||||
|
||||
VkImage fImage;
|
||||
@ -151,9 +144,10 @@ private:
|
||||
}
|
||||
private:
|
||||
void invokeReleaseProc() const {
|
||||
if (fReleaseProc) {
|
||||
fReleaseProc(fReleaseCtx);
|
||||
fReleaseProc = nullptr;
|
||||
if (fReleaseHelper) {
|
||||
// Depending on the ref count of fReleaseHelper this may or may not actually trigger
|
||||
// the ReleaseProc to be called.
|
||||
fReleaseHelper.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -161,7 +155,7 @@ private:
|
||||
void abandonGPUData() const override;
|
||||
};
|
||||
|
||||
const Resource* fResource;
|
||||
Resource* fResource;
|
||||
|
||||
friend class GrVkRenderTarget;
|
||||
};
|
||||
|
@ -39,9 +39,9 @@ public:
|
||||
|
||||
// In Vulkan we call the release proc after we are finished with the underlying
|
||||
// GrVkImage::Resource object (which occurs after the GPU has finsihed all work on it).
|
||||
void setRelease(GrTexture::ReleaseProc proc, GrTexture::ReleaseCtx ctx) override {
|
||||
void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) override {
|
||||
// Forward the release proc on to GrVkImage
|
||||
this->setResourceRelease(proc, ctx);
|
||||
this->setResourceRelease(std::move(releaseHelper));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user