Flutter Impeller
impeller::SwapchainImplVK Class Referencefinal

An instance of a swapchain that does NOT adapt to going out of date with the underlying surface. Errors will be indicated when the next drawable is acquired from this implementation of the swapchain. If the error is due the swapchain going out of date, the caller must recreate another instance by optionally stealing this implementations guts. More...

#include <swapchain_impl_vk.h>

Inheritance diagram for impeller::SwapchainImplVK:

Classes

struct  AcquireResult
 

Public Member Functions

 ~SwapchainImplVK ()
 
bool IsValid () const
 
AcquireResult AcquireNextDrawable ()
 
vk::Format GetSurfaceFormat () const
 
vk::SurfaceTransformFlagBitsKHR GetLastTransform () const
 
std::shared_ptr< ContextGetContext () const
 
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain ()
 

Static Public Member Functions

static std::shared_ptr< SwapchainImplVKCreate (const std::shared_ptr< Context > &context, vk::UniqueSurfaceKHR surface, vk::SwapchainKHR old_swapchain=VK_NULL_HANDLE, vk::SurfaceTransformFlagBitsKHR last_transform=vk::SurfaceTransformFlagBitsKHR::eIdentity)
 

Detailed Description

An instance of a swapchain that does NOT adapt to going out of date with the underlying surface. Errors will be indicated when the next drawable is acquired from this implementation of the swapchain. If the error is due the swapchain going out of date, the caller must recreate another instance by optionally stealing this implementations guts.

Definition at line 29 of file swapchain_impl_vk.h.

Constructor & Destructor Documentation

◆ ~SwapchainImplVK()

impeller::SwapchainImplVK::~SwapchainImplVK ( )

Definition at line 291 of file swapchain_impl_vk.cc.

291  {
293 }

References DestroySwapchain().

Member Function Documentation

◆ AcquireNextDrawable()

SwapchainImplVK::AcquireResult impeller::SwapchainImplVK::AcquireNextDrawable ( )

Wait on the host for the synchronizer fence.

Poll to see if the orientation has changed.

https://developer.android.com/games/optimize/vulkan-prerotation#using_polling

Get the next image index.

Definition at line 328 of file swapchain_impl_vk.cc.

328  {
329  auto context_strong = context_.lock();
330  if (!context_strong) {
331  return {};
332  }
333 
334  const auto& context = ContextVK::Cast(*context_strong);
335 
336  current_frame_ = (current_frame_ + 1u) % synchronizers_.size();
337 
338  const auto& sync = synchronizers_[current_frame_];
339 
340  //----------------------------------------------------------------------------
341  /// Wait on the host for the synchronizer fence.
342  ///
343  if (!sync->WaitForFence(context.GetDevice())) {
344  VALIDATION_LOG << "Could not wait for fence.";
345  return {};
346  }
347 
348  //----------------------------------------------------------------------------
349  /// Poll to see if the orientation has changed.
350  ///
351  /// https://developer.android.com/games/optimize/vulkan-prerotation#using_polling
352  current_transform_poll_count_++;
353  if (current_transform_poll_count_ >= kPollFramesForOrientation) {
354  current_transform_poll_count_ = 0u;
355  auto [caps_result, caps] =
356  context.GetPhysicalDevice().getSurfaceCapabilitiesKHR(*surface_);
357  if (caps_result != vk::Result::eSuccess) {
358  VALIDATION_LOG << "Could not get surface capabilities: "
359  << vk::to_string(caps_result);
360  return {};
361  }
362  if (caps.currentTransform != transform_if_changed_discard_swapchain_) {
363  transform_if_changed_discard_swapchain_ = caps.currentTransform;
364  return AcquireResult{true /* out of date */};
365  }
366  }
367 
368  //----------------------------------------------------------------------------
369  /// Get the next image index.
370  ///
371  auto [acq_result, index] = context.GetDevice().acquireNextImageKHR(
372  *swapchain_, // swapchain
373  1'000'000'000, // timeout (ns) 1000ms
374  *sync->render_ready, // signal semaphore
375  nullptr // fence
376  );
377 
378  switch (acq_result) {
379  case vk::Result::eSuccess:
380  // Keep going.
381  break;
382  case vk::Result::eSuboptimalKHR:
383  case vk::Result::eErrorOutOfDateKHR:
384  // A recoverable error. Just say we are out of date.
385  return AcquireResult{true /* out of date */};
386  break;
387  default:
388  // An unrecoverable error.
389  VALIDATION_LOG << "Could not acquire next swapchain image: "
390  << vk::to_string(acq_result);
391  return AcquireResult{false /* out of date */};
392  }
393 
394  if (index >= images_.size()) {
395  VALIDATION_LOG << "Swapchain returned an invalid image index.";
396  return {};
397  }
398 
399  auto image = images_[index % images_.size()];
400  uint32_t image_index = index;
401  return AcquireResult{SurfaceVK::WrapSwapchainImage(
402  context_strong, // context
403  image, // swapchain image
404  [weak_swapchain = weak_from_this(), image, image_index]() -> bool {
405  auto swapchain = weak_swapchain.lock();
406  if (!swapchain) {
407  return false;
408  }
409  return swapchain->Present(image, image_index);
410  } // swap callback
411  )};
412 }

References impeller::BackendCast< ContextVK, Context >::Cast(), impeller::kPollFramesForOrientation, and VALIDATION_LOG.

◆ Create()

std::shared_ptr< SwapchainImplVK > impeller::SwapchainImplVK::Create ( const std::shared_ptr< Context > &  context,
vk::UniqueSurfaceKHR  surface,
vk::SwapchainKHR  old_swapchain = VK_NULL_HANDLE,
vk::SurfaceTransformFlagBitsKHR  last_transform = vk::SurfaceTransformFlagBitsKHR::eIdentity 
)
static

Definition at line 130 of file swapchain_impl_vk.cc.

134  {
135  return std::shared_ptr<SwapchainImplVK>(new SwapchainImplVK(
136  context, std::move(surface), old_swapchain, last_transform));
137 }

Referenced by impeller::SwapchainVK::AcquireNextDrawable(), and impeller::SwapchainVK::Create().

◆ DestroySwapchain()

std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > impeller::SwapchainImplVK::DestroySwapchain ( )

Definition at line 307 of file swapchain_impl_vk.cc.

307  {
308  WaitIdle();
309  is_valid_ = false;
310  synchronizers_.clear();
311  images_.clear();
312  context_.reset();
313  return {std::move(surface_), std::move(swapchain_)};
314 }

Referenced by ~SwapchainImplVK().

◆ GetContext()

std::shared_ptr< Context > impeller::SwapchainImplVK::GetContext ( ) const

Definition at line 324 of file swapchain_impl_vk.cc.

324  {
325  return context_.lock();
326 }

◆ GetLastTransform()

vk::SurfaceTransformFlagBitsKHR impeller::SwapchainImplVK::GetLastTransform ( ) const

Definition at line 320 of file swapchain_impl_vk.cc.

320  {
321  return transform_if_changed_discard_swapchain_;
322 }

◆ GetSurfaceFormat()

vk::Format impeller::SwapchainImplVK::GetSurfaceFormat ( ) const

Definition at line 316 of file swapchain_impl_vk.cc.

316  {
317  return surface_format_;
318 }

◆ IsValid()

bool impeller::SwapchainImplVK::IsValid ( ) const

Definition at line 295 of file swapchain_impl_vk.cc.

295  {
296  return is_valid_;
297 }

The documentation for this class was generated from the following files:
impeller::kPollFramesForOrientation
static constexpr size_t kPollFramesForOrientation
Definition: swapchain_impl_vk.cc:22
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::BackendCast< ContextVK, Context >::Cast
static ContextVK & Cast(Context &base)
Definition: backend_cast.h:14
impeller::SwapchainImplVK::DestroySwapchain
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain()
Definition: swapchain_impl_vk.cc:307