Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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.
 
vk::ImageView GetImageView () const override
 Retrieve the image view used for sampling/blitting/compute with this texture source.
 
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.
 
bool IsValid () const
 
bool IsSwapchainImage () const override
 Determines if swapchain image. That is, an image used as the root render target.
 
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.
 
const android::HardwareBufferGetBackingStore () const
 
- Public Member Functions inherited from impeller::TextureSourceVK
virtual ~TextureSourceVK ()
 
const TextureDescriptorGetTextureDescriptor () const
 Gets the texture descriptor for this image source.
 
fml::Status SetLayout (const BarrierVK &barrier) const
 Encodes the layout transition barrier to barrier.cmd_buffer for the image.
 
vk::ImageLayout SetLayoutWithoutEncoding (vk::ImageLayout layout) const
 Store the layout of the image.
 
vk::ImageLayout GetLayout () const
 Get the last layout assigned to the TextureSourceVK.
 
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.
 
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 33 of file ahb_texture_source_vk.h.

Member Typedef Documentation

◆ AHBProperties

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

Definition at line 66 of file ahb_texture_source_vk.h.

◆ ImageViewInfo

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

Definition at line 72 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 =
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_holder_ = context.GetDeviceHolder();
265 device_memory_ = std::move(device_memory);
266 image_ = std::move(image);
267 yuv_conversion_ = std::move(yuv_conversion);
268 image_view_ = std::move(image_view.value);
269
270#ifdef IMPELLER_DEBUG
271 context.SetDebugName(device_memory_.get(), "AHB Device Memory");
272 context.SetDebugName(image_.get(), "AHB Image");
273 if (yuv_conversion_) {
274 context.SetDebugName(yuv_conversion_->GetConversion(),
275 "AHB YUV Conversion");
276 }
277 context.SetDebugName(image_view_.get(), "AHB ImageView");
278#endif // IMPELLER_DEBUG
279
280 is_valid_ = true;
281}
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)
TextureSourceVK(TextureDescriptor desc)
FlutterVulkanImage * image
VkPhysicalDevice physical_device
Definition main.cc:67
VkDevice device
Definition main.cc:69
std::shared_ptr< ContextGLES > context
#define VALIDATION_LOG
Definition validation.h:91

References impeller::BackendCast< ContextVK, Context >::Cast(), context, CreateImageViewInfo(), CreateVKImageWrapperForAndroidHarwareBuffer(), device, image, physical_device, 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 283 of file ahb_texture_source_vk.cc.

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

◆ ~AHBTextureSourceVK()

impeller::AHBTextureSourceVK::~AHBTextureSourceVK ( )
override

Definition at line 295 of file ahb_texture_source_vk.cc.

295 {
296 // The ASurfaceTransaction completion callback may hold the last reference
297 // to the AHBTextureSourceVK and can be deleted after the ContextVK and
298 // VkDevice have been destroyed. If the VkDevice is gone, then do not call
299 // APIs to delete Vulkan objects.
300 if (auto device = device_holder_.lock(); !device) {
301 image_view_.release();
302 image_.release();
303 device_memory_.release();
304 }
305}

References device.

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

420 {
421 const auto& ahb_format =
422 ahb_props.get<vk::AndroidHardwareBufferFormatPropertiesANDROID>();
423
424 ImageViewInfo view_chain;
425
426 auto& view_info = view_chain.get();
427
428 view_info.image = image;
429 view_info.viewType = vk::ImageViewType::e2D;
430 view_info.format = ahb_format.format;
431 if (IsOpaque(static_cast<AHardwareBuffer_Format>(ahb_desc.format))) {
432 view_info.components.a = vk::ComponentSwizzle::eOne;
433 }
434 view_info.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
435 view_info.subresourceRange.baseMipLevel = 0u;
436 view_info.subresourceRange.baseArrayLayer = 0u;
437 view_info.subresourceRange.levelCount =
438 (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE)
439 ? ISize{ahb_desc.width, ahb_desc.height}.MipCount()
440 : 1u;
441 view_info.subresourceRange.layerCount = ahb_desc.layers;
442
443 // We need a custom YUV conversion only if we don't recognize the format.
444 if (view_info.format == vk::Format::eUndefined ||
445 RequiresYCBCRConversion(view_info.format)) {
446 view_chain.get<vk::SamplerYcbcrConversionInfo>().conversion =
447 yuv_conversion_wrapper->GetConversion();
448 } else {
449 view_chain.unlink<vk::SamplerYcbcrConversionInfo>();
450 }
451
452 return view_chain;
453}
vk::StructureChain< vk::ImageViewCreateInfo, vk::SamplerYcbcrConversionInfo > ImageViewInfo
ISize64 ISize
Definition size.h:162
uint32_t format
The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM).
Definition embedder.h:940
Type width
Definition size.h:28

References FlutterVulkanImage::format, image, and 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 343 of file ahb_texture_source_vk.cc.

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

References device, image, 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 339 of file ahb_texture_source_vk.cc.

339 {
340 return backing_store_.get();
341}

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

312 {
313 return image_.get();
314}

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

317 {
318 return image_view_.get();
319}

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

324 {
325 // Hardware buffer textures are always a single 2D mip and layer.
326 return image_view_.get();
327}

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

335 {
336 return needs_yuv_conversion_ ? yuv_conversion_ : nullptr;
337}

Referenced by impeller::android::testing::TEST(), and 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 330 of file ahb_texture_source_vk.cc.

330 {
331 return is_swapchain_image_;
332}

◆ IsValid()

bool impeller::AHBTextureSourceVK::IsValid ( ) const

Definition at line 307 of file ahb_texture_source_vk.cc.

307 {
308 return is_valid_;
309}

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


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