36 auto acquire_res =
device.createFenceUnique(
37 vk::FenceCreateInfo{vk::FenceCreateFlagBits::eSignaled});
38 auto render_res =
device.createSemaphoreUnique({});
39 auto present_res =
device.createSemaphoreUnique({});
40 if (acquire_res.result != vk::Result::eSuccess ||
41 render_res.result != vk::Result::eSuccess ||
42 present_res.result != vk::Result::eSuccess) {
46 acquire = std::move(acquire_res.value);
60 result != vk::Result::eSuccess) {
65 result != vk::Result::eSuccess) {
74 vk::SurfaceFormatKHR
format) {
75 return std::find(formats.begin(), formats.end(),
format) != formats.end();
79 const std::vector<vk::SurfaceFormatKHR>& formats,
81 const auto colorspace = vk::ColorSpaceKHR::eSrgbNonlinear;
82 const auto vk_preference =
88 std::vector<vk::SurfaceFormatKHR>
options = {
89 {vk::Format::eB8G8R8A8Unorm, colorspace},
90 {vk::Format::eR8G8B8A8Unorm, colorspace}};
101 vk::CompositeAlphaFlagsKHR
flags) {
102 if (
flags & vk::CompositeAlphaFlagBitsKHR::eInherit) {
103 return vk::CompositeAlphaFlagBitsKHR::eInherit;
105 if (
flags & vk::CompositeAlphaFlagBitsKHR::ePreMultiplied) {
106 return vk::CompositeAlphaFlagBitsKHR::ePreMultiplied;
108 if (
flags & vk::CompositeAlphaFlagBitsKHR::ePostMultiplied) {
109 return vk::CompositeAlphaFlagBitsKHR::ePostMultiplied;
111 if (
flags & vk::CompositeAlphaFlagBitsKHR::eOpaque) {
112 return vk::CompositeAlphaFlagBitsKHR::eOpaque;
119 const std::shared_ptr<Context>& context,
123 vk::SwapchainKHR old_swapchain) {
125 context, std::move(
surface),
size, enable_msaa, old_swapchain));
128KHRSwapchainImplVK::KHRSwapchainImplVK(
const std::shared_ptr<Context>& context,
132 vk::SwapchainKHR old_swapchain) {
140 const auto [caps_result, surface_caps] =
141 vk_context.GetPhysicalDevice().getSurfaceCapabilitiesKHR(*
surface);
142 if (caps_result != vk::Result::eSuccess) {
148 auto [formats_result, formats] =
149 vk_context.GetPhysicalDevice().getSurfaceFormatsKHR(*
surface);
150 if (formats_result != vk::Result::eSuccess) {
157 formats, vk_context.GetCapabilities()->GetDefaultColorFormat());
158 if (!
format.has_value()) {
164 const auto composite =
166 if (!composite.has_value()) {
171 vk::SwapchainCreateInfoKHR swapchain_info;
172 swapchain_info.surface = *
surface;
173 swapchain_info.imageFormat =
format.value().format;
174 swapchain_info.imageColorSpace =
format.value().colorSpace;
175 swapchain_info.presentMode = vk::PresentModeKHR::eFifo;
176 swapchain_info.imageExtent = vk::Extent2D{
178 surface_caps.minImageExtent.width,
179 surface_caps.maxImageExtent.width),
181 surface_caps.minImageExtent.height,
182 surface_caps.maxImageExtent.height),
184 swapchain_info.minImageCount =
186 surface_caps.minImageCount,
187 surface_caps.maxImageCount == 0u
188 ? surface_caps.minImageCount + 1u
189 : surface_caps.maxImageCount
191 swapchain_info.imageArrayLayers = 1u;
194 swapchain_info.imageUsage = vk::ImageUsageFlagBits::eColorAttachment |
195 vk::ImageUsageFlagBits::eTransferDst |
196 vk::ImageUsageFlagBits::eInputAttachment;
197 swapchain_info.preTransform = vk::SurfaceTransformFlagBitsKHR::eIdentity;
198 swapchain_info.compositeAlpha = composite.value();
202 swapchain_info.clipped =
true;
205 swapchain_info.imageSharingMode = vk::SharingMode::eExclusive;
206 swapchain_info.oldSwapchain = old_swapchain;
209 vk_context.GetDevice().createSwapchainKHRUnique(swapchain_info);
210 if (swapchain_result != vk::Result::eSuccess) {
216 auto [images_result,
images] =
217 vk_context.GetDevice().getSwapchainImagesKHR(*
swapchain);
218 if (images_result != vk::Result::eSuccess) {
223 TextureDescriptor texture_desc;
226 texture_desc.format =
ToPixelFormat(swapchain_info.imageFormat);
227 texture_desc.size =
ISize::MakeWH(swapchain_info.imageExtent.width,
228 swapchain_info.imageExtent.height);
232 auto swapchain_image = std::make_shared<KHRSwapchainImageVK>(
234 vk_context.GetDevice(),
237 if (!swapchain_image->IsValid()) {
242 vk_context.GetDevice(), swapchain_image->GetImage(),
245 vk_context.GetDevice(), swapchain_image->GetImageView(),
251 std::vector<std::unique_ptr<KHRFrameSynchronizerVK>> synchronizers;
254 std::make_unique<KHRFrameSynchronizerVK>(vk_context.GetDevice());
255 if (!sync->is_valid) {
259 synchronizers.emplace_back(std::move(sync));
265 surface_format_ = swapchain_info.imageFormat;
267 transients_ = std::make_shared<SwapchainTransientsVK>(context, texture_desc,
270 synchronizers_ = std::move(synchronizers);
271 current_frame_ = synchronizers_.size() - 1u;
273 enable_msaa_ = enable_msaa;
289void KHRSwapchainImplVK::WaitIdle()
const {
290 if (
auto context = context_.lock()) {
291 [[maybe_unused]]
auto result =
296std::pair<vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR>
300 synchronizers_.clear();
303 return {std::move(surface_), std::move(swapchain_)};
307 return surface_format_;
311 return context_.lock();
315 auto context_strong = context_.lock();
316 if (!context_strong) {
322 current_frame_ = (current_frame_ + 1u) % synchronizers_.size();
324 const auto& sync = synchronizers_[current_frame_];
329 if (!sync->WaitForFence(context.GetDevice())) {
337 auto [acq_result, index] = context.GetDevice().acquireNextImageKHR(
344 switch (acq_result) {
345 case vk::Result::eSuccess:
348 case vk::Result::eSuboptimalKHR:
349 case vk::Result::eErrorOutOfDateKHR:
360 if (index >= images_.size()) {
366 context.GetGPUTracer()->MarkFrameStart();
368 auto image = images_[index % images_.size()];
369 uint32_t image_index = index;
373 [weak_swapchain = weak_from_this(),
image, image_index]() ->
bool {
383bool KHRSwapchainImplVK::Present(
384 const std::shared_ptr<KHRSwapchainImageVK>&
image,
386 auto context_strong = context_.lock();
387 if (!context_strong) {
392 const auto& sync = synchronizers_[current_frame_];
393 context.GetGPUTracer()->MarkFrameEnd();
398 sync->final_cmd_buffer = context.CreateCommandBuffer();
399 if (!sync->final_cmd_buffer) {
405 ->GetCommandBuffer();
408 barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
409 barrier.cmd_buffer = vk_final_cmd_buffer;
410 barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
411 barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
412 barrier.dst_access = {};
413 barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
415 if (!
image->SetLayout(barrier).ok()) {
419 if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) {
428 vk::SubmitInfo submit_info;
430 vk::PipelineStageFlagBits::eColorAttachmentOutput;
431 submit_info.setWaitDstStageMask(wait_stage);
432 submit_info.setWaitSemaphores(*sync->render_ready);
433 submit_info.setSignalSemaphores(*sync->present_ready);
434 submit_info.setCommandBuffers(vk_final_cmd_buffer);
436 context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire);
437 if (
result != vk::Result::eSuccess) {
447 uint32_t indices[] = {
static_cast<uint32_t
>(index)};
449 vk::PresentInfoKHR present_info;
450 present_info.setSwapchains(*swapchain_);
451 present_info.setImageIndices(indices);
452 present_info.setWaitSemaphores(*sync->present_ready);
454 auto result = context.GetGraphicsQueue()->Present(present_info);
457 case vk::Result::eErrorOutOfDateKHR:
460 case vk::Result::eErrorSurfaceLostKHR:
464 case vk::Result::eSuboptimalKHR:
470 case vk::Result::eSuccess:
static unsigned clamp(SkFixed fx, int max)
int find(T *array, int N, T item)
static ContextVK & Cast(Context &base)
const std::shared_ptr< CommandEncoderVK > & GetEncoder()
bool SetDebugName(T handle, std::string_view label) const
const vk::Device & GetDevice() const
An instance of a swapchain that does NOT adapt to going out of date with the underlying surface....
std::shared_ptr< Context > GetContext() const
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)
AcquireResult AcquireNextDrawable()
vk::Format GetSurfaceFormat() const
std::pair< vk::UniqueSurfaceKHR, vk::UniqueSwapchainKHR > DestroySwapchain()
const ISize & GetSize() const
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...
std::vector< VkImage > swapchain_images
FlutterSemanticsFlag flags
uint32_t uint32_t * format
#define FML_DCHECK(condition)
static float max(float r, float g, float b)
std::array< MockImage, 3 > images
sk_sp< const SkImage > image
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static std::optional< vk::SurfaceFormatKHR > ChooseSurfaceFormat(const std::vector< vk::SurfaceFormatKHR > &formats, PixelFormat preference)
static constexpr size_t kMaxFramesInFlight
static bool ContainsFormat(const std::vector< vk::SurfaceFormatKHR > &formats, vk::SurfaceFormatKHR format)
static std::optional< vk::CompositeAlphaFlagBitsKHR > ChooseAlphaCompositionMode(vk::CompositeAlphaFlagsKHR flags)
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
static constexpr size_t kPollFramesForOrientation
constexpr vk::Format ToVKImageFormat(PixelFormat format)
static PixelFormat ToPixelFormat(AHardwareBuffer_Format format)
def Format(template, **parameters)
static SkString to_string(int n)
vk::UniqueSemaphore render_ready
bool WaitForFence(const vk::Device &device)
KHRFrameSynchronizerVK(const vk::Device &device)
~KHRFrameSynchronizerVK()=default
vk::UniqueSemaphore present_ready
std::shared_ptr< CommandBuffer > final_cmd_buffer
static constexpr TSize MakeWH(Type width, Type height)