/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrVkImage_DEFINED #define GrVkImage_DEFINED #include "GrVkResource.h" #include "GrTypesPriv.h" #include "SkTypes.h" #include "vk/GrVkDefines.h" #include "vk/GrVkTypes.h" class GrVkGpu; class GrVkImage : SkNoncopyable { private: class Resource; public: GrVkImage(const GrVkImageInfo& info, GrBackendObjectOwnership ownership) : fInfo(info) , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) { if (fIsBorrowed) { fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling); } else { fResource = new Resource(info.fImage, info.fAlloc, info.fImageTiling); } } virtual ~GrVkImage(); VkImage image() const { return fInfo.fImage; } const GrVkAlloc& alloc() const { return fInfo.fAlloc; } VkFormat imageFormat() const { return fInfo.fFormat; } uint32_t mipLevels() const { return fInfo.fLevelCount; } const Resource* resource() const { return fResource; } bool isLinearTiled() const { return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling); } bool isBorrowed() const { return fIsBorrowed; } VkImageLayout currentLayout() const { return fInfo.fImageLayout; } void setImageLayout(const GrVkGpu* gpu, VkImageLayout newLayout, VkAccessFlags dstAccessMask, VkPipelineStageFlags dstStageMask, bool byRegion, bool releaseFamilyQueue = false); struct ImageDesc { VkImageType fImageType; VkFormat fFormat; uint32_t fWidth; uint32_t fHeight; uint32_t fLevels; uint32_t fSamples; VkImageTiling fImageTiling; VkImageUsageFlags fUsageFlags; VkFlags fMemProps; ImageDesc() : fImageType(VK_IMAGE_TYPE_2D) , fFormat(VK_FORMAT_UNDEFINED) , fWidth(0) , fHeight(0) , fLevels(1) , fSamples(1) , fImageTiling(VK_IMAGE_TILING_OPTIMAL) , fUsageFlags(0) , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {} }; static bool InitImageInfo(const GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*); // 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(sk_sp<GrReleaseProcHelper> releaseHelper); protected: void releaseImage(const GrVkGpu* gpu); void abandonImage(); void setNewResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling); GrVkImageInfo fInfo; bool fIsBorrowed; private: class Resource : public GrVkResource { public: Resource() : 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 { SkASSERT(!fReleaseHelper); } #ifdef SK_TRACE_VK_RESOURCES void dumpInfo() const override { SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt()); } #endif void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) { fReleaseHelper = std::move(releaseHelper); } protected: mutable sk_sp<GrReleaseProcHelper> fReleaseHelper; private: void freeGPUData(const GrVkGpu* gpu) const override; void abandonGPUData() const override { SkASSERT(!fReleaseHelper); } VkImage fImage; GrVkAlloc fAlloc; VkImageTiling fImageTiling; typedef GrVkResource INHERITED; }; // for wrapped textures class BorrowedResource : public Resource { public: BorrowedResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling) : Resource(image, alloc, tiling) { } private: void invokeReleaseProc() const { if (fReleaseHelper) { // Depending on the ref count of fReleaseHelper this may or may not actually trigger // the ReleaseProc to be called. fReleaseHelper.reset(); } } void freeGPUData(const GrVkGpu* gpu) const override; void abandonGPUData() const override; }; Resource* fResource; friend class GrVkRenderTarget; }; #endif