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 () const override
 Retrieve the image view used for render target attachments with this texture source. 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< YUVConversionVKGetYUVConversion () 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::HardwareBufferGetBackingStore () const
 
- Public Member Functions inherited from impeller::TextureSourceVK
virtual ~TextureSourceVK ()
 
const TextureDescriptorGetTextureDescriptor () 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)
 
const FramebufferAndRenderPassGetCachedFrameData (SampleCount sample_count) 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 64 of file ahb_texture_source_vk.h.

◆ ImageViewInfo

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

Definition at line 70 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)
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::BackendCast< ContextVK, Context >::Cast(), 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.

286  : AHBTextureSourceVK(context,
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 402 of file ahb_texture_source_vk.cc.

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

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

325  {
326  return backing_store_.get();
327 }

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 ( ) const
overridevirtual

Retrieve the image view used for render target attachments with this texture source.

ImageViews used as render target attachments cannot have any mip levels. In cases where we want to generate mipmaps with the result of this texture, we need to create multiple image views.

Returns
The render target view.

Implements impeller::TextureSourceVK.

Definition at line 311 of file ahb_texture_source_vk.cc.

311  {
312  return image_view_.get();
313 }

◆ 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 321 of file ahb_texture_source_vk.cc.

321  {
322  return needs_yuv_conversion_ ? yuv_conversion_ : nullptr;
323 }

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 316 of file ahb_texture_source_vk.cc.

316  {
317  return is_swapchain_image_;
318 }

◆ 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: