inline GrSurfacePriv surfacePriv();
inline const GrSurfacePriv surfacePriv() const;
- typedef void* ReleaseCtx;
- typedef void (*ReleaseProc)(ReleaseCtx);
-
- void setRelease(ReleaseProc proc, ReleaseCtx ctx) {
- fReleaseProc = proc;
- fReleaseCtx = ctx;
- }
-
static size_t WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2 = false);
static size_t ComputeSize(const GrSurfaceDesc& desc, int colorSamplesPerPixel,
bool hasMIPMaps, bool useNextPow2 = false);
GrSurface(GrGpu* gpu, const GrSurfaceDesc& desc)
: INHERITED(gpu)
- , fDesc(desc)
- , fReleaseProc(nullptr)
- , fReleaseCtx(nullptr) {
+ , fDesc(desc) {
}
- ~GrSurface() override;
+ ~GrSurface() override {}
GrSurfaceDesc fDesc;
void onAbandon() override;
private:
- void invokeReleaseProc() {
- if (fReleaseProc) {
- fReleaseProc(fReleaseCtx);
- fReleaseProc = nullptr;
- }
- }
-
- ReleaseProc fReleaseProc;
- ReleaseCtx fReleaseCtx;
-
typedef GrGpuResource INHERITED;
};
}
#endif
+ // These match the definitions in SkImage, for whence they came
+ typedef void* ReleaseCtx;
+ typedef void (*ReleaseProc)(ReleaseCtx);
+
+ virtual void setRelease(ReleaseProc proc, ReleaseCtx ctx) = 0;
+
/** Access methods that are only to be used within Skia code. */
inline GrTexturePriv texturePriv();
inline const GrTexturePriv texturePriv() const;
#include "SkGr.h"
#include "SkMathPriv.h"
-GrSurface::~GrSurface() {
- // check that invokeReleaseProc has been called (if needed)
- SkASSERT(NULL == fReleaseProc);
-}
-
size_t GrSurface::WorstCaseSize(const GrSurfaceDesc& desc, bool useNextPow2) {
size_t size;
}
void GrSurface::onRelease() {
- this->invokeReleaseProc();
this->INHERITED::onRelease();
}
void GrSurface::onAbandon() {
- this->invokeReleaseProc();
this->INHERITED::onAbandon();
}
}
fInfo.fID = 0;
}
+ this->invokeReleaseProc();
INHERITED::onRelease();
}
void GrGLTexture::onAbandon() {
fInfo.fTarget = 0;
fInfo.fID = 0;
+ this->invokeReleaseProc();
INHERITED::onAbandon();
}
GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&,
bool wasMipMapDataProvided);
+ ~GrGLTexture() override {
+ // check that invokeReleaseProc has been called (if needed)
+ SkASSERT(!fReleaseProc);
+ }
+
GrBackendObject getTextureHandle() const override;
void textureParamsModified() override { fTexParams.invalidate(); }
+ void setRelease(ReleaseProc proc, ReleaseCtx ctx) override {
+ fReleaseProc = proc;
+ fReleaseCtx = ctx;
+ }
+
// These functions are used to track the texture parameters associated with the texture.
const TexParams& getCachedTexParams(GrGpu::ResetTimestamp* timestamp) const {
*timestamp = fTexParamsTimestamp;
std::unique_ptr<GrExternalTextureData> detachBackendTexture() override;
private:
+ void invokeReleaseProc() {
+ if (fReleaseProc) {
+ fReleaseProc(fReleaseCtx);
+ fReleaseProc = nullptr;
+ }
+ }
+
TexParams fTexParams;
GrGpu::ResetTimestamp fTexParamsTimestamp;
// Holds the texture target and ID. A pointer to this may be shared to external clients for
GrGLTextureInfo fInfo;
GrBackendObjectOwnership fTextureIDOwnership;
+ ReleaseProc fReleaseProc = nullptr;
+ ReleaseCtx fReleaseCtx = nullptr;
+
typedef GrTexture INHERITED;
};
this->onFreeGPUData(gpu);
}
-void GrVkCommandBuffer::abandonSubResources() const {
+void GrVkCommandBuffer::abandonGPUData() const {
for (int i = 0; i < fTrackedResources.count(); ++i) {
fTrackedResources[i]->unrefAndAbandon();
}
void freeGPUData(const GrVkGpu* gpu) const override;
virtual void onFreeGPUData(const GrVkGpu* gpu) const = 0;
- void abandonSubResources() const override;
+ void abandonGPUData() const override;
virtual void onReset(GrVkGpu* gpu) {}
gpu->resourceProvider().recycleDescriptorSet(this, fHandle);
}
-void GrVkDescriptorSet::abandonSubResources() const {
+void GrVkDescriptorSet::abandonGPUData() const {
fPool->unrefAndAbandon();
}
private:
void freeGPUData(const GrVkGpu* gpu) const override;
- void abandonSubResources() const override;
+ void abandonGPUData() const override;
void onRecycle(GrVkGpu* gpu) const override;
VkDescriptorSet fDescSet;
}
}
+void GrVkImage::setResourceRelease(ReleaseProc proc, ReleaseCtx ctx) {
+ // Forward the release proc on to GrVkImage::Resource
+ fResource->setRelease(proc, ctx);
+}
+
void GrVkImage::Resource::freeGPUData(const GrVkGpu* gpu) const {
+ SkASSERT(!fReleaseProc);
VK_CALL(gpu, DestroyImage(gpu->device(), fImage, nullptr));
bool isLinear = (VK_IMAGE_TILING_LINEAR == fImageTiling);
GrVkMemory::FreeImageMemory(gpu, isLinear, fAlloc);
}
void GrVkImage::BorrowedResource::freeGPUData(const GrVkGpu* gpu) const {
+ this->invokeReleaseProc();
}
+
+void GrVkImage::BorrowedResource::abandonGPUData() const {
+ this->invokeReleaseProc();
+}
+
// Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
+ // These match the definitions in SkImage, for whence they came
+ typedef void* ReleaseCtx;
+ typedef void (*ReleaseProc)(ReleaseCtx);
+
+ void setResourceRelease(ReleaseProc proc, ReleaseCtx ctx);
+
protected:
void releaseImage(const GrVkGpu* gpu);
void abandonImage();
public:
Resource()
: INHERITED()
+ , fReleaseProc(nullptr)
+ , fReleaseCtx(nullptr)
, fImage(VK_NULL_HANDLE) {
fAlloc.fMemory = VK_NULL_HANDLE;
fAlloc.fOffset = 0;
}
Resource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
- : fImage(image), fAlloc(alloc), fImageTiling(tiling) {}
-
- ~Resource() override {}
+ : fReleaseProc(nullptr)
+ , fReleaseCtx(nullptr)
+ , fImage(image)
+ , fAlloc(alloc)
+ , fImageTiling(tiling) {}
+
+ ~Resource() override {
+ SkASSERT(!fReleaseProc);
+ }
#ifdef SK_TRACE_VK_RESOURCES
void dumpInfo() const override {
SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
}
#endif
+ void setRelease(ReleaseProc proc, ReleaseCtx ctx) const {
+ fReleaseProc = proc;
+ fReleaseCtx = ctx;
+ }
+ protected:
+ mutable ReleaseProc fReleaseProc;
+ mutable ReleaseCtx fReleaseCtx;
+
private:
void freeGPUData(const GrVkGpu* gpu) const override;
+ void abandonGPUData() const override {
+ SkASSERT(!fReleaseProc);
+ }
VkImage fImage;
GrVkAlloc fAlloc;
: Resource(image, alloc, tiling) {
}
private:
+ void invokeReleaseProc() const {
+ if (fReleaseProc) {
+ fReleaseProc(fReleaseCtx);
+ fReleaseProc = nullptr;
+ }
+ }
+
void freeGPUData(const GrVkGpu* gpu) const override;
+ void abandonGPUData() const override;
};
const Resource* fResource;
This is nearly identical to SkRefCntBase. The exceptions are that unref()
takes a GrVkGpu, and any derived classes must implement freeGPUData() and
- possibly abandonSubResources().
+ possibly abandonGPUData().
*/
class GrVkResource : SkNoncopyable {
*/
virtual void freeGPUData(const GrVkGpu* gpu) const = 0;
- /** Must be overridden by subclasses that themselves store GrVkResources.
- * Will unrefAndAbandon those resources without deleting the underlying Vk data
+ /**
+ * Called from unrefAndAbandon. Resources should do any necessary cleanup without freeing
+ * underlying Vk objects. This must be overridden by subclasses that themselves store
+ * GrVkResources since those resource will need to be unrefed.
*/
- virtual void abandonSubResources() const {}
+ virtual void abandonGPUData() const {}
/**
* Called when the ref count goes to 0. Will free Vk resources.
* Internal_dispose without freeing Vk resources. Used when we've lost context.
*/
void internal_dispose() const {
- this->abandonSubResources();
+ this->abandonGPUData();
#ifdef SK_TRACE_VK_RESOURCES
fTrace.remove(this);
#endif
bool reallocForMipmap(GrVkGpu* gpu, uint32_t mipLevels);
+ // 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 {
+ // Forward the release proc on to GrVkImage
+ this->setResourceRelease(proc, ctx);
+ }
+
protected:
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, const GrVkImageInfo&, const GrVkImageView*,
GrVkImage::Wrapped wrapped);