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 31 of file swapchain_impl_vk.h.

Constructor & Destructor Documentation

◆ ~SwapchainImplVK()

impeller::SwapchainImplVK::~SwapchainImplVK ( )

Definition at line 302 of file swapchain_impl_vk.cc.

302  {
304 }

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.

Record all subsequent cmd buffers as part of the current frame.

Definition at line 339 of file swapchain_impl_vk.cc.

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

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 140 of file swapchain_impl_vk.cc.

144  {
145  return std::shared_ptr<SwapchainImplVK>(new SwapchainImplVK(
146  context, std::move(surface), old_swapchain, last_transform));
147 }

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

◆ DestroySwapchain()

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

Definition at line 318 of file swapchain_impl_vk.cc.

318  {
319  WaitIdle();
320  is_valid_ = false;
321  synchronizers_.clear();
322  images_.clear();
323  context_.reset();
324  return {std::move(surface_), std::move(swapchain_)};
325 }

Referenced by ~SwapchainImplVK().

◆ GetContext()

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

Definition at line 335 of file swapchain_impl_vk.cc.

335  {
336  return context_.lock();
337 }

◆ GetLastTransform()

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

Definition at line 331 of file swapchain_impl_vk.cc.

331  {
332  return transform_if_changed_discard_swapchain_;
333 }

◆ GetSurfaceFormat()

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

Definition at line 327 of file swapchain_impl_vk.cc.

327  {
328  return surface_format_;
329 }

◆ IsValid()

bool impeller::SwapchainImplVK::IsValid ( ) const

Definition at line 306 of file swapchain_impl_vk.cc.

306  {
307  return is_valid_;
308 }

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