1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_BackendTexture_DEFINED 9 #define skgpu_graphite_BackendTexture_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkSize.h" 13 #include "include/gpu/graphite/GraphiteTypes.h" 14 #include "include/gpu/graphite/TextureInfo.h" 15 16 #ifdef SK_DAWN 17 #include "include/gpu/graphite/dawn/DawnTypes.h" 18 #endif 19 20 #ifdef SK_METAL 21 #include "include/gpu/graphite/mtl/MtlGraphiteTypes.h" 22 #endif 23 24 #ifdef SK_VULKAN 25 #include "include/gpu/vk/VulkanTypes.h" 26 #include "include/private/gpu/vk/SkiaVulkan.h" 27 #endif 28 29 namespace skgpu { 30 class MutableTextureState; 31 } 32 33 namespace skgpu::graphite { 34 35 class SK_API BackendTexture { 36 public: 37 BackendTexture(); 38 #ifdef SK_DAWN 39 // Create a BackendTexture from a WGPUTexture. Texture info will be queried from the texture. 40 // 41 // This is the recommended way of specifying a BackendTexture for Dawn. See the note below on 42 // the constructor that takes a WGPUTextureView for a fuller explanation. 43 // 44 // The BackendTexture will not call retain or release on the passed in WGPUTexture. Thus, the 45 // client must keep the WGPUTexture valid until they are no longer using the BackendTexture. 46 // However, any SkImage or SkSurface that wraps the BackendTexture *will* retain and release 47 // the WGPUTexture. 48 BackendTexture(WGPUTexture texture); 49 50 // Create a BackendTexture from a WGPUTexture. Texture planeDimensions, plane aspect and 51 // info have to be provided. This is intended to be used only when accessing a plane 52 // of a WGPUTexture. 53 // 54 // The BackendTexture will not call retain or release on the passed in WGPUTexture. Thus, the 55 // client must keep the WGPUTexture valid until they are no longer using the BackendTexture. 56 // However, any SkImage or SkSurface that wraps the BackendTexture *will* retain and release 57 // the WGPUTexture. 58 BackendTexture(SkISize planeDimensions, const DawnTextureInfo& info, WGPUTexture texture); 59 60 // Create a BackendTexture from a WGPUTextureView. Texture dimensions and 61 // info have to be provided. 62 // 63 // Using a WGPUTextureView rather than a WGPUTexture is less effecient for operations that 64 // require buffer transfers to or from the texture (e.g. methods on graphite::Context that read 65 // pixels or SkSurface::writePixels). In such cases an intermediate copy to or from a 66 // WGPUTexture is required. Thus, it is recommended to use this functionality only for cases 67 // where a WGPUTexture is unavailable, in particular when using wgpu::SwapChain. 68 // 69 // The BackendTexture will not call retain or release on the passed in WGPUTextureView. Thus, 70 // the client must keep the WGPUTextureView valid until they are no longer using the 71 // BackendTexture. However, any SkImage or SkSurface that wraps the BackendTexture *will* retain 72 // and release the WGPUTextureView. 73 BackendTexture(SkISize dimensions, const DawnTextureInfo& info, WGPUTextureView textureView); 74 #endif 75 #ifdef SK_METAL 76 // The BackendTexture will not call retain or release on the passed in CFTypeRef. Thus the 77 // client must keep the CFTypeRef valid until they are no longer using the BackendTexture. 78 BackendTexture(SkISize dimensions, CFTypeRef mtlTexture); 79 #endif 80 81 #ifdef SK_VULKAN 82 BackendTexture(SkISize dimensions, 83 const VulkanTextureInfo&, 84 VkImageLayout, 85 uint32_t queueFamilyIndex, 86 VkImage, 87 VulkanAlloc); 88 #endif 89 90 BackendTexture(const BackendTexture&); 91 92 ~BackendTexture(); 93 94 BackendTexture& operator=(const BackendTexture&); 95 96 bool operator==(const BackendTexture&) const; 97 bool operator!=(const BackendTexture& that) const { return !(*this == that); } 98 isValid()99 bool isValid() const { return fInfo.isValid(); } backend()100 BackendApi backend() const { return fInfo.backend(); } 101 dimensions()102 SkISize dimensions() const { return fDimensions; } 103 info()104 const TextureInfo& info() const { return fInfo; } 105 106 // If the client changes any of the mutable backend of the GrBackendTexture they should call 107 // this function to inform Skia that those values have changed. The backend API specific state 108 // that can be set from this function are: 109 // 110 // Vulkan: VkImageLayout and QueueFamilyIndex 111 void setMutableState(const skgpu::MutableTextureState&); 112 113 #ifdef SK_DAWN 114 WGPUTexture getDawnTexturePtr() const; 115 WGPUTextureView getDawnTextureViewPtr() const; 116 #endif 117 #ifdef SK_METAL 118 CFTypeRef getMtlTexture() const; 119 #endif 120 121 #ifdef SK_VULKAN 122 VkImage getVkImage() const; 123 VkImageLayout getVkImageLayout() const; 124 uint32_t getVkQueueFamilyIndex() const; 125 const VulkanAlloc* getMemoryAlloc() const; 126 #endif 127 128 private: 129 friend class VulkanResourceProvider; // for getMutableState 130 sk_sp<MutableTextureState> getMutableState() const; 131 132 SkISize fDimensions; 133 TextureInfo fInfo; 134 135 sk_sp<MutableTextureState> fMutableState; 136 137 #ifdef SK_VULKAN 138 // fMemoryAlloc == VulkanAlloc() if the client has already created their own VkImage and 139 // will destroy it themselves as opposed to having Skia create/destroy it via 140 // Recorder::createBackendTexture and Context::deleteBackendTexture. 141 VulkanAlloc fMemoryAlloc = VulkanAlloc(); 142 #endif 143 144 union { 145 #ifdef SK_DAWN 146 struct { 147 WGPUTexture fDawnTexture; 148 WGPUTextureView fDawnTextureView; 149 }; 150 #endif 151 #ifdef SK_METAL 152 CFTypeRef fMtlTexture; 153 #endif 154 #ifdef SK_VULKAN 155 VkImage fVkImage = VK_NULL_HANDLE; 156 #endif 157 void* fEnsureUnionNonEmpty; 158 }; 159 }; 160 161 } // namespace skgpu::graphite 162 163 #endif // skgpu_graphite_BackendTexture_DEFINED 164 165