| Flutter Impeller |

Classes | Public Member Functions | Static Public Member Functions | List of all members
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< Context > | GetContext () const
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > | DestroySwapchain ()

## Static Public Member Functions
static std::shared_ptr< 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)

## 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 {
303 DestroySwapchain();
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/renderer/backend/vulkan/swapchain_impl_vk.h
- impeller/renderer/backend/vulkan/swapchain_impl_vk.cc

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