Flutter Impeller
impeller::AHBTextureSourceVK Class Referencefinal

A texture source that wraps an instance of AHardwareBuffer. More...

#include <ahb_texture_source_vk.h>

Inheritance diagram for impeller::AHBTextureSourceVK:
impeller::TextureSourceVK

Public Types

using AHBProperties = vk::StructureChain< vk::AndroidHardwareBufferPropertiesANDROID, vk::AndroidHardwareBufferFormatPropertiesANDROID >
 
using ImageViewInfo = vk::StructureChain< vk::ImageViewCreateInfo, vk::SamplerYcbcrConversionInfo >
 

Public Member Functions

 AHBTextureSourceVK (const std::shared_ptr< Context > &context, struct AHardwareBuffer *hardware_buffer, const AHardwareBuffer_Desc &hardware_buffer_desc)
 
 AHBTextureSourceVK (const std::shared_ptr< Context > &context, std::unique_ptr< android::HardwareBuffer > backing_store, bool is_swapchain_image)
 
 ~AHBTextureSourceVK () override
 
vk::Image GetImage () const override
 Get the image handle for this texture source. More...
 
vk::ImageView GetImageView () const override
 Retrieve the image view used for sampling/blitting/compute with this texture source. More...
 
vk::ImageView GetRenderTargetView (uint32_t mip_level, uint32_t array_layer) const override
 Retrieve the image view used to attach a specific subresource of this texture as a render target. More...
 
bool IsValid () const
 
bool IsSwapchainImage () const override
 Determines if swapchain image. That is, an image used as the root render target. More...
 
std::shared_ptr< YUVConversionVK > GetYUVConversion () const override
 When sampling from textures whose formats are not known to Vulkan, a custom conversion is necessary to setup custom samplers. This accessor provides this conversion if one is present. Most texture source have none. More...
 
const android::HardwareBuffer * GetBackingStore () const
 
- Public Member Functions inherited from impeller::TextureSourceVK
virtual ~TextureSourceVK ()
 
const TextureDescriptor & GetTextureDescriptor () const
 Gets the texture descriptor for this image source. More...
 
fml::Status SetLayout (const BarrierVK &barrier) const
 Encodes the layout transition barrier to barrier.cmd_buffer for the image. More...
 
vk::ImageLayout SetLayoutWithoutEncoding (vk::ImageLayout layout) const
 Store the layout of the image. More...
 
vk::ImageLayout GetLayout () const
 Get the last layout assigned to the TextureSourceVK. More...
 
void SetCachedFrameData (const FramebufferAndRenderPass &data, SampleCount sample_count, uint32_t mip_level=0u, uint32_t slice=0u)
 
FramebufferAndRenderPass GetCachedFrameData (SampleCount sample_count, uint32_t mip_level=0u, uint32_t slice=0u) const
 

Static Public Member Functions

static vk::UniqueImage CreateVKImageWrapperForAndroidHarwareBuffer (const vk::Device &device, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
 Create a VkImage that wraps an Android hardware buffer. More...
 
static ImageViewInfo CreateImageViewInfo (const vk::Image &image, const std::shared_ptr< YUVConversionVK > &yuv_conversion_wrapper, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
 

Additional Inherited Members

- Protected Member Functions inherited from impeller::TextureSourceVK
 TextureSourceVK (TextureDescriptor desc)
 
- Protected Attributes inherited from impeller::TextureSourceVK
const TextureDescriptor desc_
 

Detailed Description

A texture source that wraps an instance of AHardwareBuffer.

        The formats and conversions supported by Android Hardware
        Buffers are a superset of those supported by Impeller (and
        Vulkan for that matter). Impeller and Vulkan descriptors
        obtained from the these texture sources are advisory and it
        usually isn't possible to create copies of images and image
        views held in these texture sources using the inferred
        descriptors. The objects are meant to be used directly (either
        as render targets or sources for sampling), not copied.

Definition at line 32 of file ahb_texture_source_vk.h.

Member Typedef Documentation

◆ AHBProperties

using impeller::AHBTextureSourceVK::AHBProperties = vk::StructureChain< vk::AndroidHardwareBufferPropertiesANDROID, vk::AndroidHardwareBufferFormatPropertiesANDROID>

Definition at line 65 of file ahb_texture_source_vk.h.

◆ ImageViewInfo

using impeller::AHBTextureSourceVK::ImageViewInfo = vk::StructureChain<vk::ImageViewCreateInfo, vk::SamplerYcbcrConversionInfo>

Definition at line 71 of file ahb_texture_source_vk.h.

Constructor & Destructor Documentation

◆ AHBTextureSourceVK() [1/2]

impeller::AHBTextureSourceVK::AHBTextureSourceVK ( const std::shared_ptr< Context > &  context,
struct AHardwareBuffer *  hardware_buffer,
const AHardwareBuffer_Desc &  hardware_buffer_desc 
)

Definition at line 193 of file ahb_texture_source_vk.cc.

197  : TextureSourceVK(ToTextureDescriptor(ahb_desc)) {
198  if (!p_context) {
199  return;
200  }
201 
202  const auto& context = ContextVK::Cast(*p_context);
203  const auto& device = context.GetDevice();
204  const auto& physical_device = context.GetPhysicalDevice();
205 
206  AHBProperties ahb_props;
207 
208  if (device.getAndroidHardwareBufferPropertiesANDROID(ahb, &ahb_props.get()) !=
209  vk::Result::eSuccess) {
210  VALIDATION_LOG << "Could not determine properties of the Android hardware "
211  "buffer.";
212  return;
213  }
214 
215  const auto& ahb_format =
216  ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
217 
218  // Create an image to refer to our external image.
219  auto image =
220  CreateVKImageWrapperForAndroidHarwareBuffer(device, ahb_props, ahb_desc);
221  if (!image) {
222  return;
223  }
224 
225  // Create a device memory allocation to refer to our external image.
226  auto device_memory = ImportVKDeviceMemoryFromAndroidHarwareBuffer(
227  device, physical_device, image.get(), ahb, ahb_props);
228  if (!device_memory) {
229  return;
230  }
231 
232  // Bind the image to the image memory.
233  if (auto result = device.bindImageMemory(image.get(), device_memory.get(), 0);
234  result != vk::Result::eSuccess) {
235  VALIDATION_LOG << "Could not bind external device memory to image : "
236  << vk::to_string(result);
237  return;
238  }
239 
240  // Figure out how to perform YUV conversions.
241  needs_yuv_conversion_ = ahb_format.format == vk::Format::eUndefined ||
242  RequiresYCBCRConversion(ahb_format.format);
243  std::shared_ptr<YUVConversionVK> yuv_conversion;
244  if (needs_yuv_conversion_) {
245  yuv_conversion = CreateYUVConversion(context, ahb_props);
246  if (!yuv_conversion || !yuv_conversion->IsValid()) {
247  return;
248  }
249  }
250 
251  // Create image view for the newly created image.
252  auto image_info = CreateImageViewInfo(image.get(), //
253  yuv_conversion, //
254  ahb_props, //
255  ahb_desc //
256  );
257  auto image_view = device.createImageViewUnique(image_info.get());
258  if (image_view.result != vk::Result::eSuccess) {
259  VALIDATION_LOG << "Could not create external image view: "
260  << vk::to_string(image_view.result);
261  return;
262  }
263 
264  device_memory_ = std::move(device_memory);
265  image_ = std::move(image);
266  yuv_conversion_ = std::move(yuv_conversion);
267  image_view_ = std::move(image_view.value);
268 
269 #ifdef IMPELLER_DEBUG
270  context.SetDebugName(device_memory_.get(), "AHB Device Memory");
271  context.SetDebugName(image_.get(), "AHB Image");
272  if (yuv_conversion_) {
273  context.SetDebugName(yuv_conversion_->GetConversion(),
274  "AHB YUV Conversion");
275  }
276  context.SetDebugName(image_view_.get(), "AHB ImageView");
277 #endif // IMPELLER_DEBUG
278 
279  is_valid_ = true;
280 }
static vk::UniqueImage CreateVKImageWrapperForAndroidHarwareBuffer(const vk::Device &device, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
Create a VkImage that wraps an Android hardware buffer.
vk::StructureChain< vk::AndroidHardwareBufferPropertiesANDROID, vk::AndroidHardwareBufferFormatPropertiesANDROID > AHBProperties
static ImageViewInfo CreateImageViewInfo(const vk::Image &image, const std::shared_ptr< YUVConversionVK > &yuv_conversion_wrapper, const AHBProperties &ahb_props, const AHardwareBuffer_Desc &ahb_desc)
static ContextVK & Cast(Context &base)
Definition: backend_cast.h:13
TextureSourceVK(TextureDescriptor desc)
std::shared_ptr< ContextGLES > context
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::BackendCast< ContextVK, Context >::Cast(), context, CreateImageViewInfo(), CreateVKImageWrapperForAndroidHarwareBuffer(), and VALIDATION_LOG.

◆ AHBTextureSourceVK() [2/2]

impeller::AHBTextureSourceVK::AHBTextureSourceVK ( const std::shared_ptr< Context > &  context,
std::unique_ptr< android::HardwareBuffer >  backing_store,
bool  is_swapchain_image 
)

Definition at line 282 of file ahb_texture_source_vk.cc.

287  backing_store->GetHandle(),
288  backing_store->GetAndroidDescriptor()) {
289  backing_store_ = std::move(backing_store);
290  is_swapchain_image_ = is_swapchain_image;
291 }
AHBTextureSourceVK(const std::shared_ptr< Context > &context, struct AHardwareBuffer *hardware_buffer, const AHardwareBuffer_Desc &hardware_buffer_desc)

◆ ~AHBTextureSourceVK()

impeller::AHBTextureSourceVK::~AHBTextureSourceVK ( )
overridedefault

Member Function Documentation

◆ CreateImageViewInfo()

AHBTextureSourceVK::ImageViewInfo impeller::AHBTextureSourceVK::CreateImageViewInfo ( const vk::Image &  image,
const std::shared_ptr< YUVConversionVK > &  yuv_conversion_wrapper,
const AHBProperties &  ahb_props,
const AHardwareBuffer_Desc &  ahb_desc 
)
static

Create a VkImageViewCreateInfo that matches the properties of an Android hardware buffer.

Definition at line 405 of file ahb_texture_source_vk.cc.

409  {
410  const auto& ahb_format =
411  ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
412 
413  ImageViewInfo view_chain;
414 
415  auto& view_info = view_chain.get();
416 
417  view_info.image = image;
418  view_info.viewType = vk::ImageViewType::e2D;
419  view_info.format = ahb_format.format;
420  if (IsOpaque(static_cast<AHardwareBuffer_Format>(ahb_desc.format))) {
421  view_info.components.a = vk::ComponentSwizzle::eOne;
422  }
423  view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
424  view_info.subresourceRange.baseMipLevel = 0u;
425  view_info.subresourceRange.baseArrayLayer = 0u;
426  view_info.subresourceRange.levelCount =
427  (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
428  ? ISize{ahb_desc.width, ahb_desc.height}.MipCount()
429  : 1u;
430  view_info.subresourceRange.layerCount = ahb_desc.layers;
431 
432  // We need a custom YUV conversion only if we don't recognize the format.
433  if (view_info.format == vk::Format::eUndefined ||
434  RequiresYCBCRConversion(view_info.format)) {
435  view_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
436  yuv_conversion_wrapper->GetConversion();
437  } else {
438  view_chain.unlink<vk::SamplerYcbcrConversionInfo>();
439  }
440 
441  return view_chain;
442 }
vk::StructureChain< vk::ImageViewCreateInfo, vk::SamplerYcbcrConversionInfo > ImageViewInfo
ISize64 ISize
Definition: size.h:162
Type width
Definition: size.h:28

References impeller::TSize< T >::width.

Referenced by AHBTextureSourceVK(), and impeller::android::testing::TEST().

◆ CreateVKImageWrapperForAndroidHarwareBuffer()

vk::UniqueImage impeller::AHBTextureSourceVK::CreateVKImageWrapperForAndroidHarwareBuffer ( const vk::Device &  device,
const AHBProperties &  ahb_props,
const AHardwareBuffer_Desc &  ahb_desc 
)
static

Create a VkImage that wraps an Android hardware buffer.

Definition at line 332 of file ahb_texture_source_vk.cc.

335  {
336  const auto& ahb_format =
337  ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
338 
339  vk::StructureChain<vk::ImageCreateInfo,
340  // For VK_KHR_external_memory
341  vk::ExternalMemoryImageCreateInfo,
342  // For VK_ANDROID_external_memory_android_hardware_buffer
343  vk::ExternalFormatANDROID>
344  image_chain;
345 
346  auto& image_info = image_chain.get<vk::ImageCreateInfo>();
347 
348  vk::ImageUsageFlags image_usage_flags;
349  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
350  image_usage_flags |= vk::ImageUsageFlagBits::eSampled;
351  }
352  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) {
353  image_usage_flags |= vk::ImageUsageFlagBits::eColorAttachment;
354  image_usage_flags |= vk::ImageUsageFlagBits::eInputAttachment;
355  }
356 
357  vk::ImageCreateFlags image_create_flags;
358  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
359  image_create_flags |= vk::ImageCreateFlagBits::eProtected;
360  }
361  if (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP) {
362  image_create_flags |= vk::ImageCreateFlagBits::eCubeCompatible;
363  }
364 
365  image_info.imageType = vk::ImageType::e2D;
366  image_info.format = ahb_format.format;
367  image_info.extent.width = ahb_desc.width;
368  image_info.extent.height = ahb_desc.height;
369  image_info.extent.depth = 1;
370  image_info.mipLevels =
371  (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
372  ? ISize{ahb_desc.width, ahb_desc.height}.MipCount()
373  : 1u;
374  image_info.arrayLayers = ahb_desc.layers;
375  image_info.samples = vk::SampleCountFlagBits::e1;
376  image_info.tiling = vk::ImageTiling::eOptimal;
377  image_info.usage = image_usage_flags;
378  image_info.flags = image_create_flags;
379  image_info.sharingMode = vk::SharingMode::eExclusive;
380  image_info.initialLayout = vk::ImageLayout::eUndefined;
381 
382  image_chain.get<vk::ExternalMemoryImageCreateInfo>().handleTypes =
383  vk::ExternalMemoryHandleTypeFlagBits::eAndroidHardwareBufferANDROID;
384 
385  // If the format isn't natively supported by Vulkan (i.e, be a part of the
386  // base vkFormat enum), an untyped "external format" must be specified when
387  // creating the image and the image views. Usually includes YUV formats.
388  if (ahb_format.format == vk::Format::eUndefined) {
389  image_chain.get<vk::ExternalFormatANDROID>().externalFormat =
390  ahb_format.externalFormat;
391  } else {
392  image_chain.unlink<vk::ExternalFormatANDROID>();
393  }
394 
395  auto image = device.createImageUnique(image_chain.get());
396  if (image.result != vk::Result::eSuccess) {
397  VALIDATION_LOG << "Could not create image for external buffer: "
398  << vk::to_string(image.result);
399  return {};
400  }
401 
402  return std::move(image.value);
403 }
Vector3 e1

References e1, VALIDATION_LOG, and impeller::TSize< T >::width.

Referenced by AHBTextureSourceVK(), and impeller::android::testing::TEST().

◆ GetBackingStore()

const android::HardwareBuffer * impeller::AHBTextureSourceVK::GetBackingStore ( ) const

Definition at line 328 of file ahb_texture_source_vk.cc.

328  {
329  return backing_store_.get();
330 }

Referenced by impeller::glvk::CreateEGLImageFromAHBTexture().

◆ GetImage()

vk::Image impeller::AHBTextureSourceVK::GetImage ( ) const
overridevirtual

Get the image handle for this texture source.

Returns
The image.

Implements impeller::TextureSourceVK.

Definition at line 301 of file ahb_texture_source_vk.cc.

301  {
302  return image_.get();
303 }

◆ GetImageView()

vk::ImageView impeller::AHBTextureSourceVK::GetImageView ( ) const
overridevirtual

Retrieve the image view used for sampling/blitting/compute with this texture source.

Returns
The image view.

Implements impeller::TextureSourceVK.

Definition at line 306 of file ahb_texture_source_vk.cc.

306  {
307  return image_view_.get();
308 }

◆ GetRenderTargetView()

vk::ImageView impeller::AHBTextureSourceVK::GetRenderTargetView ( uint32_t  mip_level,
uint32_t  array_layer 
) const
overridevirtual

Retrieve the image view used to attach a specific subresource of this texture as a render target.

The returned view covers a single mip level and a single array layer (or cube map face), since attachment views cannot span multiple levels or layers.

Parameters
[in]mip_levelThe mip level to attach.
[in]array_layerThe array layer or cube map face to attach.
Returns
The render target view.

Implements impeller::TextureSourceVK.

Definition at line 311 of file ahb_texture_source_vk.cc.

313  {
314  // Hardware buffer textures are always a single 2D mip and layer.
315  return image_view_.get();
316 }

◆ GetYUVConversion()

std::shared_ptr< YUVConversionVK > impeller::AHBTextureSourceVK::GetYUVConversion ( ) const
overridevirtual

When sampling from textures whose formats are not known to Vulkan, a custom conversion is necessary to setup custom samplers. This accessor provides this conversion if one is present. Most texture source have none.

Returns
The sampler conversion.

Reimplemented from impeller::TextureSourceVK.

Definition at line 324 of file ahb_texture_source_vk.cc.

324  {
325  return needs_yuv_conversion_ ? yuv_conversion_ : nullptr;
326 }

Referenced by impeller::android::testing::TEST().

◆ IsSwapchainImage()

bool impeller::AHBTextureSourceVK::IsSwapchainImage ( ) const
overridevirtual

Determines if swapchain image. That is, an image used as the root render target.

Returns
Whether or not this is a swapchain image.

Implements impeller::TextureSourceVK.

Definition at line 319 of file ahb_texture_source_vk.cc.

319  {
320  return is_swapchain_image_;
321 }

◆ IsValid()

bool impeller::AHBTextureSourceVK::IsValid ( ) const

Definition at line 296 of file ahb_texture_source_vk.cc.

296  {
297  return is_valid_;
298 }

Referenced by impeller::android::testing::TEST().


The documentation for this class was generated from the following files: