Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit a9cd8a3

Browse files
[Impeller] Don't perform final layout transition on worker thread. (#44510)
This can lead to flutter/flutter#131717 because the raster thread may access the Queue while the worker thread is doing the final layout transition. Moving the final layout transition back to the raster thread should be fine, its really the presentation that we want to run in a background worker. Fixes flutter/flutter#131717
1 parent 30e7780 commit a9cd8a3

File tree

1 file changed

+52
-51
lines changed

1 file changed

+52
-51
lines changed

impeller/renderer/backend/vulkan/swapchain_impl_vk.cc

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -392,64 +392,65 @@ bool SwapchainImplVK::Present(const std::shared_ptr<SwapchainImageVK>& image,
392392
}
393393

394394
const auto& context = ContextVK::Cast(*context_strong);
395+
const auto& sync = synchronizers_[current_frame_];
396+
397+
//----------------------------------------------------------------------------
398+
/// Transition the image to color-attachment-optimal.
399+
///
400+
sync->final_cmd_buffer = context.CreateCommandBuffer();
401+
if (!sync->final_cmd_buffer) {
402+
return false;
403+
}
404+
405+
auto vk_final_cmd_buffer = CommandBufferVK::Cast(*sync->final_cmd_buffer)
406+
.GetEncoder()
407+
->GetCommandBuffer();
408+
{
409+
BarrierVK barrier;
410+
barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
411+
barrier.cmd_buffer = vk_final_cmd_buffer;
412+
barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
413+
barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
414+
barrier.dst_access = {};
415+
barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
416+
417+
if (!image->SetLayout(barrier)) {
418+
return false;
419+
}
420+
421+
if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) {
422+
return false;
423+
}
424+
}
425+
426+
//----------------------------------------------------------------------------
427+
/// Signal that the presentation semaphore is ready.
428+
///
429+
{
430+
vk::SubmitInfo submit_info;
431+
vk::PipelineStageFlags wait_stage =
432+
vk::PipelineStageFlagBits::eColorAttachmentOutput;
433+
submit_info.setWaitDstStageMask(wait_stage);
434+
submit_info.setWaitSemaphores(*sync->render_ready);
435+
submit_info.setSignalSemaphores(*sync->present_ready);
436+
submit_info.setCommandBuffers(vk_final_cmd_buffer);
437+
auto result =
438+
context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire);
439+
if (result != vk::Result::eSuccess) {
440+
VALIDATION_LOG << "Could not wait on render semaphore: "
441+
<< vk::to_string(result);
442+
return false;
443+
}
444+
}
445+
395446
context.GetConcurrentWorkerTaskRunner()->PostTask(
396447
[&, index, image, current_frame = current_frame_] {
397448
auto context_strong = context_.lock();
398449
if (!context_strong) {
399450
return;
400451
}
401-
const auto& context = ContextVK::Cast(*context_strong);
402-
const auto& sync = synchronizers_[current_frame];
403-
404-
//----------------------------------------------------------------------------
405-
/// Transition the image to color-attachment-optimal.
406-
///
407-
sync->final_cmd_buffer = context.CreateCommandBuffer();
408-
if (!sync->final_cmd_buffer) {
409-
return;
410-
}
411-
412-
auto vk_final_cmd_buffer =
413-
CommandBufferVK::Cast(*sync->final_cmd_buffer)
414-
.GetEncoder()
415-
->GetCommandBuffer();
416-
{
417-
BarrierVK barrier;
418-
barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
419-
barrier.cmd_buffer = vk_final_cmd_buffer;
420-
barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
421-
barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
422-
barrier.dst_access = {};
423-
barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
424-
425-
if (!image->SetLayout(barrier)) {
426-
return;
427-
}
428-
429-
if (vk_final_cmd_buffer.end() != vk::Result::eSuccess) {
430-
return;
431-
}
432-
}
433452

434-
//----------------------------------------------------------------------------
435-
/// Signal that the presentation semaphore is ready.
436-
///
437-
{
438-
vk::SubmitInfo submit_info;
439-
vk::PipelineStageFlags wait_stage =
440-
vk::PipelineStageFlagBits::eColorAttachmentOutput;
441-
submit_info.setWaitDstStageMask(wait_stage);
442-
submit_info.setWaitSemaphores(*sync->render_ready);
443-
submit_info.setSignalSemaphores(*sync->present_ready);
444-
submit_info.setCommandBuffers(vk_final_cmd_buffer);
445-
auto result =
446-
context.GetGraphicsQueue()->Submit(submit_info, *sync->acquire);
447-
if (result != vk::Result::eSuccess) {
448-
VALIDATION_LOG << "Could not wait on render semaphore: "
449-
<< vk::to_string(result);
450-
return;
451-
}
452-
}
453+
const auto& sync = synchronizers_[current_frame];
453454

454455
//----------------------------------------------------------------------------
455456
/// Present the image.

0 commit comments

Comments
 (0)