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

273 {
274 DestroySwapchain();
275 }
impeller::KHRSwapchainImplVK::DestroySwapchain
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain()
Definition: khr_swapchain_impl_vk.cc:325

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

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

416 {
417 const auto& sync = synchronizers_[current_frame_];
418 sync->final_cmd_buffer = std::move(cmd_buffer);
419 sync->has_onscreen = true;
420 }

## ◆ 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 }

## ◆ DestroySwapchain()

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

Definition at line 325 of file khr_swapchain_impl_vk.cc.

325 {
326 WaitIdle();
327 is_valid_ = false;
328 synchronizers_.clear();
329 images_.clear();
330 context_.reset();
331 return {std::move(surface_), std::move(swapchain_)};
332 }

Referenced by ~KHRSwapchainImplVK().

## ◆ GetContext()

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

Definition at line 338 of file khr_swapchain_impl_vk.cc.

338 {
339 return context_.lock();
340 }

## ◆ GetCurrentUnderlyingSurfaceSize()

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

Definition at line 281 of file khr_swapchain_impl_vk.cc.

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

277 {
278 return size_;
279 }

## ◆ GetSurfaceFormat()

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

Definition at line 334 of file khr_swapchain_impl_vk.cc.

334 {
335 return surface_format_;
336 }

## ◆ IsValid()

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

Definition at line 313 of file khr_swapchain_impl_vk.cc.

313 {
314 return is_valid_;
315 }

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