16 vk::AndroidHardwareBufferPropertiesANDROID,
18 vk::AndroidHardwareBufferFormatPropertiesANDROID>;
23 const AHardwareBuffer_Desc& ahb_desc) {
24 const auto& ahb_format =
25 ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
27 vk::StructureChain<vk::ImageCreateInfo,
29 vk::ExternalMemoryImageCreateInfo,
31 vk::ExternalFormatANDROID>
34 auto& image_info = image_chain.get<vk::ImageCreateInfo>();
36 vk::ImageUsageFlags image_usage_flags;
37 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
38 image_usage_flags |= vk::ImageUsageFlagBits::eSampled;
40 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
41 image_usage_flags |= vk::ImageUsageFlagBits::eColorAttachment;
43 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY) {
44 image_usage_flags |= vk::ImageUsageFlagBits::eColorAttachment;
45 image_usage_flags |= vk::ImageUsageFlagBits::eInputAttachment;
46 image_usage_flags |= vk::ImageUsageFlagBits::eTransferDst;
49 vk::ImageCreateFlags image_create_flags;
50 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
51 image_create_flags |= vk::ImageCreateFlagBits::eProtected;
53 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
54 image_create_flags |= vk::ImageCreateFlagBits::eCubeCompatible;
57 image_info.imageType = vk::ImageType::e2D;
58 image_info.format = ahb_format.format;
59 image_info.extent.width = ahb_desc.width;
60 image_info.extent.height = ahb_desc.height;
61 image_info.extent.depth = 1;
62 image_info.mipLevels =
63 (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
64 ?
ISize{ahb_desc.
width, ahb_desc.height}.MipCount()
66 image_info.arrayLayers = ahb_desc.layers;
68 image_info.tiling = vk::ImageTiling::eOptimal;
69 image_info.usage = image_usage_flags;
70 image_info.flags = image_create_flags;
71 image_info.sharingMode = vk::SharingMode::eExclusive;
72 image_info.initialLayout = vk::ImageLayout::eUndefined;
74 image_chain.get<vk::ExternalMemoryImageCreateInfo>().handleTypes =
75 vk::ExternalMemoryHandleTypeFlagBits::eAndroidHardwareBufferANDROID;
80 if (ahb_format.format == vk::Format::eUndefined) {
81 image_chain.get<vk::ExternalFormatANDROID>().externalFormat =
82 ahb_format.externalFormat;
84 image_chain.unlink<vk::ExternalFormatANDROID>();
87 auto image =
device.createImageUnique(image_chain.get());
88 if (
image.result != vk::Result::eSuccess) {
94 return std::move(
image.value);
103 vk::PhysicalDeviceMemoryProperties memory_properties;
106 ahb_props.get().memoryTypeBits, memory_properties);
107 if (memory_type_index < 0) {
108 VALIDATION_LOG <<
"Could not find memory type of external image.";
112 vk::StructureChain<vk::MemoryAllocateInfo,
114 vk::MemoryDedicatedAllocateInfo,
116 vk::ImportAndroidHardwareBufferInfoANDROID>
119 auto& mem_alloc_info = memory_chain.get<vk::MemoryAllocateInfo>();
120 mem_alloc_info.allocationSize = ahb_props.get().allocationSize;
121 mem_alloc_info.memoryTypeIndex = memory_type_index;
123 auto& dedicated_alloc_info =
124 memory_chain.get<vk::MemoryDedicatedAllocateInfo>();
125 dedicated_alloc_info.image =
image;
127 auto& ahb_import_info =
128 memory_chain.
get<vk::ImportAndroidHardwareBufferInfoANDROID>();
129 ahb_import_info.buffer = hardware_buffer;
131 auto device_memory =
device.allocateMemoryUnique(memory_chain.get());
132 if (device_memory.result != vk::Result::eSuccess) {
133 VALIDATION_LOG <<
"Could not allocate device memory for external image : "
138 return std::move(device_memory.value);
146 const auto& ahb_format =
147 ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
149 auto& conversion_info = conversion_chain.get();
151 conversion_info.format = ahb_format.format;
152 conversion_info.ycbcrModel = ahb_format.suggestedYcbcrModel;
153 conversion_info.ycbcrRange = ahb_format.suggestedYcbcrRange;
154 conversion_info.components = ahb_format.samplerYcbcrConversionComponents;
155 conversion_info.xChromaOffset = ahb_format.suggestedXChromaOffset;
156 conversion_info.yChromaOffset = ahb_format.suggestedYChromaOffset;
162 conversion_info.chromaFilter = vk::Filter::eNearest;
163 conversion_info.forceExplicitReconstruction =
false;
165 if (conversion_info.format == vk::Format::eUndefined) {
166 auto&
external_format = conversion_chain.get<vk::ExternalFormatANDROID>();
169 conversion_chain.unlink<vk::ExternalFormatANDROID>();
178 const vk::SamplerYcbcrConversion& yuv_conversion,
180 const AHardwareBuffer_Desc& ahb_desc) {
181 const auto& ahb_format =
182 ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
184 vk::StructureChain<vk::ImageViewCreateInfo,
186 vk::SamplerYcbcrConversionInfo>
189 auto& view_info = view_chain.get();
191 view_info.image =
image;
192 view_info.viewType = vk::ImageViewType::e2D;
193 view_info.format = ahb_format.format;
194 view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
195 view_info.subresourceRange.baseMipLevel = 0u;
196 view_info.subresourceRange.baseArrayLayer = 0u;
197 view_info.subresourceRange.levelCount =
198 (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
199 ?
ISize{ahb_desc.
width, ahb_desc.height}.MipCount()
201 view_info.subresourceRange.layerCount = ahb_desc.layers;
204 if (view_info.format == vk::Format::eUndefined) {
205 view_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
208 view_chain.unlink<vk::SamplerYcbcrConversionInfo>();
211 auto image_view =
device.createImageViewUnique(view_info);
212 if (image_view.result != vk::Result::eSuccess) {
218 return std::move(image_view.value);
223 case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
225 case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
227 case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
229 case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
231 case AHARDWAREBUFFER_FORMAT_S8_UINT:
233 case AHARDWAREBUFFER_FORMAT_R8_UNORM:
235 case AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM:
236 case AHARDWAREBUFFER_FORMAT_R16G16_UINT:
237 case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
238 case AHARDWAREBUFFER_FORMAT_R16_UINT:
239 case AHARDWAREBUFFER_FORMAT_D24_UNORM:
240 case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
241 case AHARDWAREBUFFER_FORMAT_YCbCr_P010:
242 case AHARDWAREBUFFER_FORMAT_BLOB:
243 case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
244 case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
245 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
246 case AHARDWAREBUFFER_FORMAT_D16_UNORM:
247 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
256 if (ahb_desc.layers == 1u) {
259 if (ahb_desc.layers % 6u == 0 &&
260 (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP)) {
269 const AHardwareBuffer_Desc& ahb_desc) {
270 const auto ahb_size =
ISize{ahb_desc.
width, ahb_desc.height};
276 ToPixelFormat(
static_cast<AHardwareBuffer_Format
>(ahb_desc.format));
277 desc.size = ahb_size;
281 desc.mip_count = (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
282 ? ahb_size.MipCount()
284 if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY) {
291 const std::shared_ptr<Context>& p_context,
293 const AHardwareBuffer_Desc& ahb_desc)
301 const auto&
device = context.GetDevice();
306 if (
device.getAndroidHardwareBufferPropertiesANDROID(ahb, &ahb_props.get()) !=
307 vk::Result::eSuccess) {
308 VALIDATION_LOG <<
"Could not determine properties of the Android hardware "
313 const auto& ahb_format =
314 ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
326 if (!device_memory) {
332 result != vk::Result::eSuccess) {
333 VALIDATION_LOG <<
"Could not bind external device memory to image : "
340 if (!yuv_conversion || !yuv_conversion->IsValid()) {
347 yuv_conversion->GetConversion(),
355 needs_yuv_conversion_ = ahb_format.format == vk::Format::eUndefined;
356 device_memory_ = std::move(device_memory);
357 image_ = std::move(
image);
358 yuv_conversion_ = std::move(yuv_conversion);
359 image_view_ = std::move(image_view);
362 context.SetDebugName(device_memory_.get(),
"AHB Device Memory");
363 context.SetDebugName(image_.get(),
"AHB Image");
364 context.SetDebugName(yuv_conversion_->GetConversion(),
"AHB YUV Conversion");
365 context.SetDebugName(image_view_.get(),
"AHB ImageView");
372 const std::shared_ptr<Context>& context,
373 std::unique_ptr<android::HardwareBuffer> backing_store,
374 bool is_swapchain_image)
376 backing_store->GetHandle(),
377 backing_store->GetAndroidDescriptor()) {
378 backing_store_ = std::move(backing_store);
379 is_swapchain_image_ = is_swapchain_image;
396 return image_view_.get();
401 return image_view_.get();
406 return is_swapchain_image_;
411 return needs_yuv_conversion_ ? yuv_conversion_ :
nullptr;
415 return backing_store_.get();
struct AHardwareBuffer AHardwareBuffer
A texture source that wraps an instance of AHardwareBuffer.
bool IsSwapchainImage() const override
Determines if swapchain image. That is, an image used as the root render target.
vk::Image GetImage() const override
Get the image handle for this texture source.
const android::HardwareBuffer * GetBackingStore() const
std::shared_ptr< YUVConversionVK > GetYUVConversion() const override
When sampling from textures whose formats are not known to Vulkan, a custom conversion is necessary t...
AHBTextureSourceVK(const std::shared_ptr< Context > &context, struct AHardwareBuffer *hardware_buffer, const AHardwareBuffer_Desc &hardware_buffer_desc)
~AHBTextureSourceVK() override
vk::ImageView GetImageView() const override
Retrieve the image view used for sampling/blitting/compute with this texture source.
vk::ImageView GetRenderTargetView() const override
Retrieve the image view used for render target attachments with this texture source.
static int32_t FindMemoryTypeIndex(uint32_t memory_type_bits_requirement, vk::PhysicalDeviceMemoryProperties &memory_properties)
Select a matching memory type for the given [memory_type_bits_requirement], or -1 if none is found.
static ContextVK & Cast(Context &base)
const std::shared_ptr< YUVConversionLibraryVK > & GetYUVConversionLibrary() const
Abstract base class that represents a vkImage and an vkImageView.
A wrapper for AHardwareBuffer https://developer.android.com/ndk/reference/group/a-hardware-buffer.
VkPhysicalDevice physical_device
uint32_t uint32_t * format
sk_sp< const SkImage > image
vk::StructureChain< vk::AndroidHardwareBufferPropertiesANDROID, vk::AndroidHardwareBufferFormatPropertiesANDROID > AHBProperties
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
constexpr GLenum ToTextureType(TextureType type)
static vk::UniqueImage CreateVKImageWrapperForAndroidHarwareBuffer(const vk::Device &device, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
static std::shared_ptr< YUVConversionVK > CreateYUVConversion(const ContextVK &context, const AHBProperties &ahb_props)
static vk::UniqueImageView CreateVKImageView(const vk::Device &device, const vk::Image &image, const vk::SamplerYcbcrConversion &yuv_conversion, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
static TextureDescriptor ToTextureDescriptor(const AHardwareBuffer_Desc &ahb_desc)
static PixelFormat ToPixelFormat(AHardwareBuffer_Format format)
vk::StructureChain< vk::SamplerYcbcrConversionCreateInfo > YUVConversionDescriptorVK
static vk::UniqueDeviceMemory ImportVKDeviceMemoryFromAndroidHarwareBuffer(const vk::Device &device, const vk::PhysicalDevice &physical_device, const vk::Image &image, struct AHardwareBuffer *hardware_buffer, const AHBProperties &ahb_props)
static SkString to_string(int n)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...