| Flutter Impeller |

Classes | Public Member Functions | Static Public Member Functions | List of all members
impeller::KHRSwapchainImplVK 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 <khr_swapchain_impl_vk.h>`

Inheritance diagram for impeller::KHRSwapchainImplVK:

## Classes
struct | AcquireResult

## Public Member Functions
| ~KHRSwapchainImplVK ()
bool | IsValid () const
AcquireResult | AcquireNextDrawable ()
vk::Format | GetSurfaceFormat () const
std::shared_ptr< Context > | GetContext () const
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > | DestroySwapchain ()
const ISize & | GetSize () const
void | AddFinalCommandBuffer (std::shared_ptr< CommandBuffer > cmd_buffer)

## Static Public Member Functions
static std::shared_ptr< KHRSwapchainImplVK > | Create (const std::shared_ptr< Context > &context, vk::UniqueSurfaceKHR surface, const ISize &size, bool enable_msaa=true, vk::SwapchainKHR old_swapchain=VK_NULL_HANDLE)

## 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 30 of file khr_swapchain_impl_vk.h.

## Constructor & Destructor Documentation

## ◆ ~KHRSwapchainImplVK()

impeller::KHRSwapchainImplVK::~KHRSwapchainImplVK | ( |  | ) |

Definition at line 274 of file khr_swapchain_impl_vk.cc.

274 {
275 DestroySwapchain();
276 }

References DestroySwapchain().

## Member Function Documentation

## ◆ AcquireNextDrawable()

KHRSwapchainImplVK::AcquireResult impeller::KHRSwapchainImplVK::AcquireNextDrawable | ( |  | ) |

Wait on the host for the synchronizer fence.

Get the next image index.

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

Definition at line 311 of file khr_swapchain_impl_vk.cc.

311 {
312 auto context_strong = context_.lock();
313 if (!context_strong) {
314 return KHRSwapchainImplVK::AcquireResult{};
315 }
316
317 const auto& context = ContextVK::Cast(*context_strong);
318
319 current_frame_ = (current_frame_ + 1u) % synchronizers_.size();
320
321 const auto& sync = synchronizers_[current_frame_];
322
323 //----------------------------------------------------------------------------
324 /// Wait on the host for the synchronizer fence.
325 ///
326 if (!sync->WaitForFence(context.GetDevice())) {
327 VALIDATION_LOG << "Could not wait for fence.";
328 return KHRSwapchainImplVK::AcquireResult{};
329 }
330
331 //----------------------------------------------------------------------------
332 /// Get the next image index.
333 ///
334 /// @bug Non-infinite timeouts are not supported on some older Android
335 /// devices and the only indication we get is log spam which serves to
336 /// add confusion. Just use an infinite timeout instead of being
337 /// defensive.
338 auto [acq_result, index] = context.GetDevice().acquireNextImageKHR(
339 *swapchain_, // swapchain
340 std::numeric_limits<uint64_t>::max(), // timeout (ns)
341 *sync->render_ready, // signal semaphore
342 nullptr // fence
343 );
344
345 switch (acq_result) {
346 case vk::Result::eSuccess:
347 // Keep going.
348 break;
349 case vk::Result::eSuboptimalKHR:
350 case vk::Result::eErrorOutOfDateKHR:
351 // A recoverable error. Just say we are out of date.
352 return AcquireResult{true /* out of date */};
353 break;
354 default:
355 // An unrecoverable error.
356 VALIDATION_LOG << "Could not acquire next swapchain image: "
357 << vk::to_string(acq_result);
358 return AcquireResult{false /* out of date */};
359 }
360
361 if (index >= images_.size()) {
362 VALIDATION_LOG << "Swapchain returned an invalid image index.";
363 return KHRSwapchainImplVK::AcquireResult{};
364 }
365
366 /// Record all subsequent cmd buffers as part of the current frame.
367 context.GetGPUTracer()->MarkFrameStart();
368
369 auto image = images_[index % images_.size()];
370 uint32_t image_index = index;
371 return AcquireResult{SurfaceVK::WrapSwapchainImage(
372 transients_, // transients
373 image, // swapchain image
374 [weak_swapchain = weak_from_this(), image, image_index]() -> bool {
375 auto swapchain = weak_swapchain.lock();
376 if (!swapchain) {
377 return false;
378 }
379 return swapchain->Present(image, image_index);
380 } // swap callback
381 )};
382 }

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

Referenced by impeller::KHRSwapchainVK::AcquireNextDrawable().

## ◆ AddFinalCommandBuffer()

void impeller::KHRSwapchainImplVK::AddFinalCommandBuffer | ( | std::shared_ptr< CommandBuffer > | cmd_buffer | ) |

Definition at line 384 of file khr_swapchain_impl_vk.cc.

385 {
386 const auto& sync = synchronizers_[current_frame_];
387 sync->final_cmd_buffer = std::move(cmd_buffer);
388 sync->has_onscreen = true;
389 }

## ◆ Create()

std::shared_ptr< KHRSwapchainImplVK > impeller::KHRSwapchainImplVK::Create | ( | const std::shared_ptr< Context > & | context,
|  | vk::UniqueSurfaceKHR | surface,
|  | const ISize & | size,
|  | bool | enable_msaa = `true`,
|  | vk::SwapchainKHR | old_swapchain = `VK_NULL_HANDLE`
| ) |  |
| static

Definition at line 115 of file khr_swapchain_impl_vk.cc.

120 {
121 return std::shared_ptr<KHRSwapchainImplVK>(new KHRSwapchainImplVK(
122 context, std::move(surface), size, enable_msaa, old_swapchain));
123 }

Referenced by impeller::KHRSwapchainVK::AcquireNextDrawable().

## ◆ DestroySwapchain()

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

Definition at line 294 of file khr_swapchain_impl_vk.cc.

294 {
295 WaitIdle();
296 is_valid_ = false;
297 synchronizers_.clear();
298 images_.clear();
299 context_.reset();
300 return {std::move(surface_), std::move(swapchain_)};
301 }

Referenced by ~KHRSwapchainImplVK().

## ◆ GetContext()

std::shared_ptr< Context > impeller::KHRSwapchainImplVK::GetContext | ( |  | ) | const

Definition at line 307 of file khr_swapchain_impl_vk.cc.

307 {
308 return context_.lock();
309 }

## ◆ GetSize()

const ISize & impeller::KHRSwapchainImplVK::GetSize | ( |  | ) | const

Definition at line 278 of file khr_swapchain_impl_vk.cc.

278 {
279 return size_;
280 }

## ◆ GetSurfaceFormat()

vk::Format impeller::KHRSwapchainImplVK::GetSurfaceFormat | ( |  | ) | const

Definition at line 303 of file khr_swapchain_impl_vk.cc.

303 {
304 return surface_format_;
305 }

## ◆ IsValid()

bool impeller::KHRSwapchainImplVK::IsValid | ( |  | ) | const

Definition at line 282 of file khr_swapchain_impl_vk.cc.

282 {
283 return is_valid_;
284 }

Referenced by impeller::KHRSwapchainVK::AcquireNextDrawable(), and impeller::KHRSwapchainVK::GetSurfaceFormat().

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

- impeller/renderer/backend/vulkan/swapchain/khr/khr_swapchain_impl_vk.h
- impeller/renderer/backend/vulkan/swapchain/khr/khr_swapchain_impl_vk.cc

impeller::SurfaceVK::WrapSwapchainImage
static std::unique_ptr< SurfaceVK > WrapSwapchainImage(const std::shared_ptr< SwapchainTransientsVK > &transients, const std::shared_ptr< TextureSourceVK > &swapchain_image, SwapCallback swap_callback)
Wrap the swapchain image in a Surface, which provides the additional configuration required for usage...
Definition: surface_vk.cc:13
impeller::KHRSwapchainImplVK::DestroySwapchain
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain()
Definition: khr_swapchain_impl_vk.cc:294
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::BackendCast< ContextVK, Context >::Cast
static ContextVK & Cast(Context &base)
Definition: backend_cast.h:13