1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef GrVkImage_DEFINED
9cb93a386Sopenharmony_ci#define GrVkImage_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
12cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h"
13cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h"
14cb93a386Sopenharmony_ci#include "include/private/GrTypesPriv.h"
15cb93a386Sopenharmony_ci#include "include/private/GrVkTypesPriv.h"
16cb93a386Sopenharmony_ci#include "src/gpu/GrAttachment.h"
17cb93a386Sopenharmony_ci#include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
18cb93a386Sopenharmony_ci#include "src/gpu/GrManagedResource.h"
19cb93a386Sopenharmony_ci#include "src/gpu/GrRefCnt.h"
20cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h"
21cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSet.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci#include <cinttypes>
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ciclass GrVkGpu;
26cb93a386Sopenharmony_ciclass GrVkImageView;
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_ciclass SK_API GrVkImage : public GrAttachment {
29cb93a386Sopenharmony_ciprivate:
30cb93a386Sopenharmony_ci    class Resource;
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_cipublic:
33cb93a386Sopenharmony_ci    static sk_sp<GrVkImage> MakeStencil(GrVkGpu* gpu,
34cb93a386Sopenharmony_ci                                        SkISize dimensions,
35cb93a386Sopenharmony_ci                                        int sampleCnt,
36cb93a386Sopenharmony_ci                                        VkFormat format);
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci    static sk_sp<GrVkImage> MakeMSAA(GrVkGpu* gpu,
39cb93a386Sopenharmony_ci                                     SkISize dimensions,
40cb93a386Sopenharmony_ci                                     int numSamples,
41cb93a386Sopenharmony_ci                                     VkFormat format,
42cb93a386Sopenharmony_ci                                     GrProtected isProtected,
43cb93a386Sopenharmony_ci                                     GrMemoryless memoryless);
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci    static sk_sp<GrVkImage> MakeTexture(GrVkGpu* gpu,
46cb93a386Sopenharmony_ci                                        SkISize dimensions,
47cb93a386Sopenharmony_ci                                        VkFormat format,
48cb93a386Sopenharmony_ci                                        uint32_t mipLevels,
49cb93a386Sopenharmony_ci                                        GrRenderable renderable,
50cb93a386Sopenharmony_ci                                        int numSamples,
51cb93a386Sopenharmony_ci                                        SkBudgeted budgeted,
52cb93a386Sopenharmony_ci                                        GrProtected isProtected);
53cb93a386Sopenharmony_ci
54cb93a386Sopenharmony_ci    static sk_sp<GrVkImage> MakeWrapped(GrVkGpu* gpu,
55cb93a386Sopenharmony_ci                                        SkISize dimensions,
56cb93a386Sopenharmony_ci                                        const GrVkImageInfo&,
57cb93a386Sopenharmony_ci                                        sk_sp<GrBackendSurfaceMutableStateImpl>,
58cb93a386Sopenharmony_ci                                        UsageFlags attachmentUsages,
59cb93a386Sopenharmony_ci                                        GrWrapOwnership,
60cb93a386Sopenharmony_ci                                        GrWrapCacheable,
61cb93a386Sopenharmony_ci                                        bool forSecondaryCB = false);
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    // OH ISSUE: Integrate Destroy and Free
64cb93a386Sopenharmony_ci    static void DestroyAndFreeImageMemory(const GrVkGpu* gpu, const GrVkAlloc& alloc, const VkImage& image);
65cb93a386Sopenharmony_ci
66cb93a386Sopenharmony_ci    ~GrVkImage() override;
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    VkImage image() const {
69cb93a386Sopenharmony_ci        // Should only be called when we have a real fResource object, i.e. never when being used as
70cb93a386Sopenharmony_ci        // a RT in an external secondary command buffer.
71cb93a386Sopenharmony_ci        SkASSERT(fResource);
72cb93a386Sopenharmony_ci        return fInfo.fImage;
73cb93a386Sopenharmony_ci    }
74cb93a386Sopenharmony_ci    const GrVkAlloc& alloc() const {
75cb93a386Sopenharmony_ci        // Should only be called when we have a real fResource object, i.e. never when being used as
76cb93a386Sopenharmony_ci        // a RT in an external secondary command buffer.
77cb93a386Sopenharmony_ci        SkASSERT(fResource);
78cb93a386Sopenharmony_ci        return fInfo.fAlloc;
79cb93a386Sopenharmony_ci    }
80cb93a386Sopenharmony_ci    const GrVkImageInfo& vkImageInfo() const { return fInfo; }
81cb93a386Sopenharmony_ci    VkFormat imageFormat() const { return fInfo.fFormat; }
82cb93a386Sopenharmony_ci    GrBackendFormat backendFormat() const override {
83cb93a386Sopenharmony_ci        bool usesDRMModifier =
84cb93a386Sopenharmony_ci                this->vkImageInfo().fImageTiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT;
85cb93a386Sopenharmony_ci        if (fResource && this->ycbcrConversionInfo().isValid()) {
86cb93a386Sopenharmony_ci            SkASSERT(this->imageFormat() == this->ycbcrConversionInfo().fFormat);
87cb93a386Sopenharmony_ci            return GrBackendFormat::MakeVk(this->ycbcrConversionInfo(), usesDRMModifier);
88cb93a386Sopenharmony_ci        }
89cb93a386Sopenharmony_ci        SkASSERT(this->imageFormat() != VK_FORMAT_UNDEFINED);
90cb93a386Sopenharmony_ci        return GrBackendFormat::MakeVk(this->imageFormat(), usesDRMModifier);
91cb93a386Sopenharmony_ci    }
92cb93a386Sopenharmony_ci    uint32_t mipLevels() const { return fInfo.fLevelCount; }
93cb93a386Sopenharmony_ci    const GrVkYcbcrConversionInfo& ycbcrConversionInfo() const {
94cb93a386Sopenharmony_ci        // Should only be called when we have a real fResource object, i.e. never when being used as
95cb93a386Sopenharmony_ci        // a RT in an external secondary command buffer.
96cb93a386Sopenharmony_ci        SkASSERT(fResource);
97cb93a386Sopenharmony_ci        return fInfo.fYcbcrConversionInfo;
98cb93a386Sopenharmony_ci    }
99cb93a386Sopenharmony_ci    VkImageUsageFlags vkUsageFlags() { return fInfo.fImageUsageFlags; }
100cb93a386Sopenharmony_ci    bool supportsInputAttachmentUsage() const {
101cb93a386Sopenharmony_ci        return fInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
102cb93a386Sopenharmony_ci    }
103cb93a386Sopenharmony_ci
104cb93a386Sopenharmony_ci    const GrVkImageView* framebufferView() const { return fFramebufferView.get(); }
105cb93a386Sopenharmony_ci    const GrVkImageView* textureView() const { return fTextureView.get(); }
106cb93a386Sopenharmony_ci
107cb93a386Sopenharmony_ci    // So that we don't need to rewrite descriptor sets each time, we keep cached input descriptor
108cb93a386Sopenharmony_ci    // sets on the attachment and simply reuse those descriptor sets for this attachment only. These
109cb93a386Sopenharmony_ci    // calls will fail if the attachment does not support being used as an input attachment. These
110cb93a386Sopenharmony_ci    // calls do not ref the GrVkDescriptorSet so they called will need to manually ref them if they
111cb93a386Sopenharmony_ci    // need to be kept alive.
112cb93a386Sopenharmony_ci    gr_rp<const GrVkDescriptorSet> inputDescSetForBlending(GrVkGpu* gpu);
113cb93a386Sopenharmony_ci    // Input descripotr set used when needing to read a resolve attachment to load data into a
114cb93a386Sopenharmony_ci    // discardable msaa attachment.
115cb93a386Sopenharmony_ci    gr_rp<const GrVkDescriptorSet> inputDescSetForMSAALoad(GrVkGpu* gpu);
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    const Resource* resource() const {
118cb93a386Sopenharmony_ci        SkASSERT(fResource);
119cb93a386Sopenharmony_ci        return fResource;
120cb93a386Sopenharmony_ci    }
121cb93a386Sopenharmony_ci    bool isLinearTiled() const {
122cb93a386Sopenharmony_ci        // Should only be called when we have a real fResource object, i.e. never when being used as
123cb93a386Sopenharmony_ci        // a RT in an external secondary command buffer.
124cb93a386Sopenharmony_ci        SkASSERT(fResource);
125cb93a386Sopenharmony_ci        return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
126cb93a386Sopenharmony_ci    }
127cb93a386Sopenharmony_ci    bool isBorrowed() const { return fIsBorrowed; }
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ci    sk_sp<GrBackendSurfaceMutableStateImpl> getMutableState() const { return fMutableState; }
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci    VkImageLayout currentLayout() const { return fMutableState->getImageLayout(); }
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci    void setImageLayoutAndQueueIndex(const GrVkGpu* gpu,
134cb93a386Sopenharmony_ci                                     VkImageLayout newLayout,
135cb93a386Sopenharmony_ci                                     VkAccessFlags dstAccessMask,
136cb93a386Sopenharmony_ci                                     VkPipelineStageFlags dstStageMask,
137cb93a386Sopenharmony_ci                                     bool byRegion,
138cb93a386Sopenharmony_ci                                     uint32_t newQueueFamilyIndex);
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ci    void setImageLayout(const GrVkGpu* gpu,
141cb93a386Sopenharmony_ci                        VkImageLayout newLayout,
142cb93a386Sopenharmony_ci                        VkAccessFlags dstAccessMask,
143cb93a386Sopenharmony_ci                        VkPipelineStageFlags dstStageMask,
144cb93a386Sopenharmony_ci                        bool byRegion) {
145cb93a386Sopenharmony_ci        this->setImageLayoutAndQueueIndex(gpu, newLayout, dstAccessMask, dstStageMask, byRegion,
146cb93a386Sopenharmony_ci                                          VK_QUEUE_FAMILY_IGNORED);
147cb93a386Sopenharmony_ci    }
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci    uint32_t currentQueueFamilyIndex() const { return fMutableState->getQueueFamilyIndex(); }
150cb93a386Sopenharmony_ci
151cb93a386Sopenharmony_ci    void setQueueFamilyIndex(uint32_t queueFamilyIndex) {
152cb93a386Sopenharmony_ci        fMutableState->setQueueFamilyIndex(queueFamilyIndex);
153cb93a386Sopenharmony_ci    }
154cb93a386Sopenharmony_ci
155cb93a386Sopenharmony_ci    // Returns the image to its original queue family and changes the layout to present if the queue
156cb93a386Sopenharmony_ci    // family is not external or foreign.
157cb93a386Sopenharmony_ci    void prepareForPresent(GrVkGpu* gpu);
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ci    // Returns the image to its original queue family
160cb93a386Sopenharmony_ci    void prepareForExternal(GrVkGpu* gpu);
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ci    // This simply updates our tracking of the image layout and does not actually do any gpu work.
163cb93a386Sopenharmony_ci    // This is only used for mip map generation where we are manually changing the layouts as we
164cb93a386Sopenharmony_ci    // blit each layer, and then at the end need to update our tracking.
165cb93a386Sopenharmony_ci    void updateImageLayout(VkImageLayout newLayout) {
166cb93a386Sopenharmony_ci        // Should only be called when we have a real fResource object, i.e. never when being used as
167cb93a386Sopenharmony_ci        // a RT in an external secondary command buffer.
168cb93a386Sopenharmony_ci        SkASSERT(fResource);
169cb93a386Sopenharmony_ci        fMutableState->setImageLayout(newLayout);
170cb93a386Sopenharmony_ci    }
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ci    struct ImageDesc {
173cb93a386Sopenharmony_ci        VkImageType         fImageType;
174cb93a386Sopenharmony_ci        VkFormat            fFormat;
175cb93a386Sopenharmony_ci        uint32_t            fWidth;
176cb93a386Sopenharmony_ci        uint32_t            fHeight;
177cb93a386Sopenharmony_ci        uint32_t            fLevels;
178cb93a386Sopenharmony_ci        uint32_t            fSamples;
179cb93a386Sopenharmony_ci        VkImageTiling       fImageTiling;
180cb93a386Sopenharmony_ci        VkImageUsageFlags   fUsageFlags;
181cb93a386Sopenharmony_ci        VkFlags             fMemProps;
182cb93a386Sopenharmony_ci        GrProtected         fIsProtected;
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci        ImageDesc()
185cb93a386Sopenharmony_ci                : fImageType(VK_IMAGE_TYPE_2D)
186cb93a386Sopenharmony_ci                , fFormat(VK_FORMAT_UNDEFINED)
187cb93a386Sopenharmony_ci                , fWidth(0)
188cb93a386Sopenharmony_ci                , fHeight(0)
189cb93a386Sopenharmony_ci                , fLevels(1)
190cb93a386Sopenharmony_ci                , fSamples(1)
191cb93a386Sopenharmony_ci                , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
192cb93a386Sopenharmony_ci                , fUsageFlags(0)
193cb93a386Sopenharmony_ci                , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
194cb93a386Sopenharmony_ci                , fIsProtected(GrProtected::kNo) {}
195cb93a386Sopenharmony_ci    };
196cb93a386Sopenharmony_ci
197cb93a386Sopenharmony_ci    static bool InitImageInfo(GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*);
198cb93a386Sopenharmony_ci    // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
199cb93a386Sopenharmony_ci    static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    // These match the definitions in SkImage, for whence they came
202cb93a386Sopenharmony_ci    typedef void* ReleaseCtx;
203cb93a386Sopenharmony_ci    typedef void (*ReleaseProc)(ReleaseCtx);
204cb93a386Sopenharmony_ci
205cb93a386Sopenharmony_ci    void setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper);
206cb93a386Sopenharmony_ci
207cb93a386Sopenharmony_ci    // Helpers to use for setting the layout of the VkImage
208cb93a386Sopenharmony_ci    static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout);
209cb93a386Sopenharmony_ci    static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ci    size_t onGpuMemorySize() const override;
212cb93a386Sopenharmony_ci#if GR_TEST_UTILS
213cb93a386Sopenharmony_ci    void setCurrentQueueFamilyToGraphicsQueue(GrVkGpu* gpu);
214cb93a386Sopenharmony_ci#endif
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ci#ifdef SKIA_OHOS
217cb93a386Sopenharmony_ci    SkBudgeted GetBudgeted() const { return fBudgeted; }
218cb93a386Sopenharmony_ci#endif
219cb93a386Sopenharmony_ci
220cb93a386Sopenharmony_ciprivate:
221cb93a386Sopenharmony_ci    static sk_sp<GrVkImage> Make(GrVkGpu* gpu,
222cb93a386Sopenharmony_ci                                 SkISize dimensions,
223cb93a386Sopenharmony_ci                                 UsageFlags attachmentUsages,
224cb93a386Sopenharmony_ci                                 int sampleCnt,
225cb93a386Sopenharmony_ci                                 VkFormat format,
226cb93a386Sopenharmony_ci                                 uint32_t mipLevels,
227cb93a386Sopenharmony_ci                                 VkImageUsageFlags vkUsageFlags,
228cb93a386Sopenharmony_ci                                 GrProtected isProtected,
229cb93a386Sopenharmony_ci                                 GrMemoryless,
230cb93a386Sopenharmony_ci                                 SkBudgeted);
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ci    GrVkImage(GrVkGpu* gpu,
233cb93a386Sopenharmony_ci              SkISize dimensions,
234cb93a386Sopenharmony_ci              UsageFlags supportedUsages,
235cb93a386Sopenharmony_ci              const GrVkImageInfo&,
236cb93a386Sopenharmony_ci              sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
237cb93a386Sopenharmony_ci              sk_sp<const GrVkImageView> framebufferView,
238cb93a386Sopenharmony_ci              sk_sp<const GrVkImageView> textureView,
239cb93a386Sopenharmony_ci              SkBudgeted);
240cb93a386Sopenharmony_ci
241cb93a386Sopenharmony_ci    GrVkImage(GrVkGpu* gpu,
242cb93a386Sopenharmony_ci              SkISize dimensions,
243cb93a386Sopenharmony_ci              UsageFlags supportedUsages,
244cb93a386Sopenharmony_ci              const GrVkImageInfo&,
245cb93a386Sopenharmony_ci              sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
246cb93a386Sopenharmony_ci              sk_sp<const GrVkImageView> framebufferView,
247cb93a386Sopenharmony_ci              sk_sp<const GrVkImageView> textureView,
248cb93a386Sopenharmony_ci              GrBackendObjectOwnership,
249cb93a386Sopenharmony_ci              GrWrapCacheable,
250cb93a386Sopenharmony_ci              bool forSecondaryCB);
251cb93a386Sopenharmony_ci
252cb93a386Sopenharmony_ci    void init(GrVkGpu*, bool forSecondaryCB);
253cb93a386Sopenharmony_ci
254cb93a386Sopenharmony_ci    void onRelease() override;
255cb93a386Sopenharmony_ci    void onAbandon() override;
256cb93a386Sopenharmony_ci
257cb93a386Sopenharmony_ci    void releaseImage();
258cb93a386Sopenharmony_ci    bool hasResource() const { return fResource; }
259cb93a386Sopenharmony_ci
260cb93a386Sopenharmony_ci    GrVkGpu* getVkGpu() const;
261cb93a386Sopenharmony_ci
262cb93a386Sopenharmony_ci    GrVkImageInfo                           fInfo;
263cb93a386Sopenharmony_ci    uint32_t                                fInitialQueueFamily;
264cb93a386Sopenharmony_ci    sk_sp<GrBackendSurfaceMutableStateImpl> fMutableState;
265cb93a386Sopenharmony_ci
266cb93a386Sopenharmony_ci    sk_sp<const GrVkImageView>              fFramebufferView;
267cb93a386Sopenharmony_ci    sk_sp<const GrVkImageView>              fTextureView;
268cb93a386Sopenharmony_ci
269cb93a386Sopenharmony_ci#ifdef SKIA_OHOS
270cb93a386Sopenharmony_ci    SkBudgeted fBudgeted = SkBudgeted::kNo;
271cb93a386Sopenharmony_ci#endif
272cb93a386Sopenharmony_ci    bool fIsBorrowed;
273cb93a386Sopenharmony_ci
274cb93a386Sopenharmony_ci    // Descriptor set used when this is used as an input attachment for reading the dst in blending.
275cb93a386Sopenharmony_ci    gr_rp<const GrVkDescriptorSet> fCachedBlendingInputDescSet;
276cb93a386Sopenharmony_ci    // Descriptor set used when this is used as an input attachment for loading an msaa attachment.
277cb93a386Sopenharmony_ci    gr_rp<const GrVkDescriptorSet> fCachedMSAALoadInputDescSet;
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ci    class Resource : public GrTextureResource {
280cb93a386Sopenharmony_ci    public:
281cb93a386Sopenharmony_ci        explicit Resource(const GrVkGpu* gpu)
282cb93a386Sopenharmony_ci                : fGpu(gpu)
283cb93a386Sopenharmony_ci                , fImage(VK_NULL_HANDLE) {
284cb93a386Sopenharmony_ci            fAlloc.fMemory = VK_NULL_HANDLE;
285cb93a386Sopenharmony_ci            fAlloc.fOffset = 0;
286cb93a386Sopenharmony_ci        }
287cb93a386Sopenharmony_ci
288cb93a386Sopenharmony_ci        Resource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
289cb93a386Sopenharmony_ci            : fGpu(gpu)
290cb93a386Sopenharmony_ci            , fImage(image)
291cb93a386Sopenharmony_ci            , fAlloc(alloc) {}
292cb93a386Sopenharmony_ci
293cb93a386Sopenharmony_ci        ~Resource() override {}
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ci#ifdef SK_TRACE_MANAGED_RESOURCES
296cb93a386Sopenharmony_ci        void dumpInfo() const override {
297cb93a386Sopenharmony_ci            SkDebugf("GrVkImage: %" PRIdPTR " (%d refs)\n", (intptr_t)fImage, this->getRefCnt());
298cb93a386Sopenharmony_ci        }
299cb93a386Sopenharmony_ci#endif
300cb93a386Sopenharmony_ci
301cb93a386Sopenharmony_ci#ifdef SK_DEBUG
302cb93a386Sopenharmony_ci        const GrManagedResource* asVkImageResource() const override { return this; }
303cb93a386Sopenharmony_ci#endif
304cb93a386Sopenharmony_ci
305cb93a386Sopenharmony_ci    private:
306cb93a386Sopenharmony_ci        void freeGPUData() const override;
307cb93a386Sopenharmony_ci
308cb93a386Sopenharmony_ci        const GrVkGpu* fGpu;
309cb93a386Sopenharmony_ci        VkImage        fImage;
310cb93a386Sopenharmony_ci        GrVkAlloc      fAlloc;
311cb93a386Sopenharmony_ci
312cb93a386Sopenharmony_ci        using INHERITED = GrTextureResource;
313cb93a386Sopenharmony_ci    };
314cb93a386Sopenharmony_ci
315cb93a386Sopenharmony_ci    // for wrapped textures
316cb93a386Sopenharmony_ci    class BorrowedResource : public Resource {
317cb93a386Sopenharmony_ci    public:
318cb93a386Sopenharmony_ci        BorrowedResource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc,
319cb93a386Sopenharmony_ci                         VkImageTiling tiling)
320cb93a386Sopenharmony_ci            : Resource(gpu, image, alloc, tiling) {
321cb93a386Sopenharmony_ci        }
322cb93a386Sopenharmony_ci    private:
323cb93a386Sopenharmony_ci        void freeGPUData() const override;
324cb93a386Sopenharmony_ci    };
325cb93a386Sopenharmony_ci
326cb93a386Sopenharmony_ci    Resource* fResource;
327cb93a386Sopenharmony_ci
328cb93a386Sopenharmony_ci    friend class GrVkRenderTarget;
329cb93a386Sopenharmony_ci};
330cb93a386Sopenharmony_ci
331cb93a386Sopenharmony_ci#endif
332