| 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)
std::optional< ISize > | GetCurrentUnderlyingSurfaceSize () const

## 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 278 of file khr_swapchain_impl_vk.cc.

278 {
279 DestroySwapchain();
280 }
impeller::KHRSwapchainImplVK::DestroySwapchain
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain()
Definition: khr_swapchain_impl_vk.cc:330

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 347 of file khr_swapchain_impl_vk.cc.

347 {
348 auto context_strong = context_.lock();
349 if (!context_strong) {
350 return KHRSwapchainImplVK::AcquireResult{};
351 }
352
353 const auto& context = ContextVK::Cast(*context_strong);
354
355 current_frame_ = (current_frame_ + 1u) % synchronizers_.size();
356
357 const auto& sync = synchronizers_[current_frame_];
358
359 //----------------------------------------------------------------------------
360 /// Wait on the host for the synchronizer fence.
361 ///
362 if (!sync->WaitForFence(context.GetDevice())) {
363 VALIDATION_LOG << "Could not wait for fence.";
364 return KHRSwapchainImplVK::AcquireResult{};
365 }
366
367 //----------------------------------------------------------------------------
368 /// Get the next image index.
369 ///
370 /// @bug Non-infinite timeouts are not supported on some older Android
371 /// devices and the only indication we get is log spam which serves to
372 /// add confusion. Just use an infinite timeout instead of being
373 /// defensive.
374 auto [acq_result, index] = context.GetDevice().acquireNextImageKHR(
375 *swapchain_, // swapchain
376 std::numeric_limits<uint64_t>::max(), // timeout (ns)
377 *sync->render_ready, // signal semaphore
378 nullptr // fence
379 );
380
381 switch (acq_result) {
382 case vk::Result::eSuccess:
383 // Keep going.
384 break;
385 case vk::Result::eSuboptimalKHR:
386 case vk::Result::eErrorOutOfDateKHR:
387 // A recoverable error. Just say we are out of date.
388 return AcquireResult{true /* out of date */};
389 break;
390 default:
391 // An unrecoverable error.
392 VALIDATION_LOG << "Could not acquire next swapchain image: "
393 << vk::to_string(acq_result);
394 return AcquireResult{false /* out of date */};
395 }
396
397 if (index >= images_.size()) {
398 VALIDATION_LOG << "Swapchain returned an invalid image index.";
399 return KHRSwapchainImplVK::AcquireResult{};
400 }
401
402 /// Record all subsequent cmd buffers as part of the current frame.
403 context.GetGPUTracer()->MarkFrameStart();
404
405 auto image = images_[index % images_.size()];
406 uint32_t image_index = index;
407 return AcquireResult{SurfaceVK::WrapSwapchainImage(
408 transients_, // transients
409 image, // swapchain image
410 [weak_swapchain = weak_from_this(), image, image_index]() -> bool {
411 auto swapchain = weak_swapchain.lock();
412 if (!swapchain) {
413 return false;
414 }
415 return swapchain->Present(image, image_index);
416 } // swap callback
417 )};
418 }
impeller::BackendCast< ContextVK, Context >::Cast
static ContextVK & Cast(Context &base)
Definition: backend_cast.h:13
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
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91

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

## ◆ AddFinalCommandBuffer()

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

Definition at line 420 of file khr_swapchain_impl_vk.cc.

421 {
422 const auto& sync = synchronizers_[current_frame_];
423 sync->final_cmd_buffer = std::move(cmd_buffer);
424 sync->has_onscreen = true;
425 }

## ◆ 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 111 of file khr_swapchain_impl_vk.cc.

116 {
117 return std::shared_ptr<KHRSwapchainImplVK>(new KHRSwapchainImplVK(
118 context, std::move(surface), size, enable_msaa, old_swapchain));
119 }

## ◆ DestroySwapchain()

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

Definition at line 330 of file khr_swapchain_impl_vk.cc.

330 {
331 WaitIdle();
332 is_valid_ = false;
333 synchronizers_.clear();
334 images_.clear();
335 context_.reset();
336 return {std::move(surface_), std::move(swapchain_)};
337 }

Referenced by ~KHRSwapchainImplVK().

## ◆ GetContext()

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

Definition at line 343 of file khr_swapchain_impl_vk.cc.

343 {
344 return context_.lock();
345 }

## ◆ GetCurrentUnderlyingSurfaceSize()

std::optional< ISize > impeller::KHRSwapchainImplVK::GetCurrentUnderlyingSurfaceSize | ( |  | ) | const

Definition at line 286 of file khr_swapchain_impl_vk.cc.

287 {
288 if (!IsValid()) {
289 return std::nullopt;
290 }
291
292 auto context = context_.lock();
293 if (!context) {
294 return std::nullopt;
295 }
296
297 auto& vk_context = ContextVK::Cast(*context);
298 const auto [result, surface_caps] =
299 vk_context.GetPhysicalDevice().getSurfaceCapabilitiesKHR(surface_.get());
300 if (result != vk::Result::eSuccess) {
301 return std::nullopt;
302 }
303
304 // From the spec: `currentExtent` is the current width and height of the
305 // surface, or the special value (0xFFFFFFFF, 0xFFFFFFFF) indicating that the
306 // surface size will be determined by the extent of a swapchain targeting the
307 // surface.
308 constexpr uint32_t kCurrentExtentsPlaceholder = 0xFFFFFFFF;
309 if (surface_caps.currentExtent.width == kCurrentExtentsPlaceholder ||
310 surface_caps.currentExtent.height == kCurrentExtentsPlaceholder) {
311 return std::nullopt;
312 }
313
314 return ISize::MakeWH(surface_caps.currentExtent.width,
315 surface_caps.currentExtent.height);
316 }
impeller::KHRSwapchainImplVK::IsValid
bool IsValid() const
Definition: khr_swapchain_impl_vk.cc:318
impeller::TSize::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:43

References impeller::BackendCast< ContextVK, Context >::Cast(), IsValid(), and impeller::TSize< T >::MakeWH().

## ◆ GetSize()

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

Definition at line 282 of file khr_swapchain_impl_vk.cc.

282 {
283 return size_;
284 }

## ◆ GetSurfaceFormat()

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

Definition at line 339 of file khr_swapchain_impl_vk.cc.

339 {
340 return surface_format_;
341 }

## ◆ IsValid()

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

Definition at line 318 of file khr_swapchain_impl_vk.cc.

318 {
319 return is_valid_;
320 }

Referenced by GetCurrentUnderlyingSurfaceSize().

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