| 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 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 {
292 DestroySwapchain();
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/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: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