mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] re-enable AHB swapchain. (flutter/engine#53978)
Fixes https://github.com/flutter/flutter/issues/148139 Block on the CPU rather than immediately beginning encoding. Seems to fix the synchronization issues that we knew about. We need to find a way to use AHB swapchains, as it seems like correct synchronization via either SurfaceView or a SurfaceControl hierarchy will require exposing our rendering as a SurfaceTransaction.
This commit is contained in:
parent
9e797d1461
commit
7b3144290f
@ -22,7 +22,7 @@ namespace impeller {
|
||||
/// The maximum number of presents pending in the compositor after which the
|
||||
/// acquire calls will block. This value is 2 images given to the system
|
||||
/// compositor and one for the raster thread, Because the semaphore is acquired
|
||||
/// when the CPU Begins working on the texture
|
||||
/// when the CPU begins working on the texture
|
||||
///
|
||||
static constexpr const size_t kMaxPendingPresents = 3u;
|
||||
|
||||
@ -68,7 +68,9 @@ AHBSwapchainImplVK::AHBSwapchainImplVK(
|
||||
}
|
||||
transients_ = std::make_shared<SwapchainTransientsVK>(
|
||||
context, ToSwapchainTextureDescriptor(desc_), enable_msaa);
|
||||
is_valid_ = true;
|
||||
|
||||
auto control = surface_control_.lock();
|
||||
is_valid_ = control && control->IsValid();
|
||||
}
|
||||
|
||||
AHBSwapchainImplVK::~AHBSwapchainImplVK() = default;
|
||||
@ -237,7 +239,7 @@ AHBSwapchainImplVK::SubmitSignalForPresentReady(
|
||||
return fence;
|
||||
}
|
||||
|
||||
vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore(
|
||||
vk::UniqueFence AHBSwapchainImplVK::CreateRenderReadyFence(
|
||||
const std::shared_ptr<fml::UniqueFD>& fd) const {
|
||||
if (!fd->is_valid()) {
|
||||
return {};
|
||||
@ -251,22 +253,22 @@ vk::UniqueSemaphore AHBSwapchainImplVK::CreateRenderReadySemaphore(
|
||||
const auto& context_vk = ContextVK::Cast(*context);
|
||||
const auto& device = context_vk.GetDevice();
|
||||
|
||||
auto signal_wait = device.createSemaphoreUnique({});
|
||||
auto signal_wait = device.createFenceUnique({});
|
||||
|
||||
if (signal_wait.result != vk::Result::eSuccess) {
|
||||
return {};
|
||||
}
|
||||
|
||||
context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadySemaphore");
|
||||
context_vk.SetDebugName(*signal_wait.value, "AHBRenderReadyFence");
|
||||
|
||||
vk::ImportSemaphoreFdInfoKHR import_info;
|
||||
import_info.semaphore = *signal_wait.value;
|
||||
vk::ImportFenceFdInfoKHR import_info;
|
||||
import_info.fence = *signal_wait.value;
|
||||
import_info.fd = fd->get();
|
||||
import_info.handleType = vk::ExternalSemaphoreHandleTypeFlagBits::eSyncFd;
|
||||
import_info.handleType = vk::ExternalFenceHandleTypeFlagBits::eSyncFd;
|
||||
// From the spec: Sync FDs can only be imported temporarily.
|
||||
import_info.flags = vk::SemaphoreImportFlagBitsKHR::eTemporary;
|
||||
import_info.flags = vk::FenceImportFlagBitsKHR::eTemporary;
|
||||
|
||||
const auto import_result = device.importSemaphoreFdKHR(import_info);
|
||||
const auto import_result = device.importFenceFdKHR(import_info);
|
||||
|
||||
if (import_result != vk::Result::eSuccess) {
|
||||
VALIDATION_LOG << "Could not import semaphore FD: "
|
||||
@ -297,63 +299,20 @@ bool AHBSwapchainImplVK::SubmitWaitForRenderReady(
|
||||
return false;
|
||||
}
|
||||
|
||||
auto completion_fence =
|
||||
ContextVK::Cast(*context).GetDevice().createFenceUnique({}).value;
|
||||
if (!completion_fence) {
|
||||
auto fence = CreateRenderReadyFence(render_ready_fence);
|
||||
|
||||
auto result = ContextVK::Cast(*context).GetDevice().waitForFences(
|
||||
*fence, // fence
|
||||
true, // wait all
|
||||
std::numeric_limits<uint64_t>::max() // timeout (ns)
|
||||
);
|
||||
|
||||
if (!(result == vk::Result::eSuccess || result == vk::Result::eTimeout)) {
|
||||
VALIDATION_LOG << "Fence waiter encountered an unexpected error. Tearing "
|
||||
"down the waiter thread.";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto command_buffer = context->CreateCommandBuffer();
|
||||
if (!command_buffer) {
|
||||
return false;
|
||||
}
|
||||
command_buffer->SetLabel("AHBSubmitWaitForRenderReadyCB");
|
||||
const auto& encoder = CommandBufferVK::Cast(*command_buffer).GetEncoder();
|
||||
|
||||
const auto command_buffer_vk = encoder->GetCommandBuffer();
|
||||
|
||||
BarrierVK barrier;
|
||||
barrier.cmd_buffer = command_buffer_vk;
|
||||
barrier.new_layout = vk::ImageLayout::eColorAttachmentOptimal;
|
||||
barrier.src_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
|
||||
barrier.src_access = {};
|
||||
barrier.dst_stage = vk::PipelineStageFlagBits::eTopOfPipe;
|
||||
barrier.dst_access = {};
|
||||
|
||||
if (!texture->SetLayout(barrier).ok()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto render_ready_semaphore =
|
||||
MakeSharedVK(CreateRenderReadySemaphore(render_ready_fence));
|
||||
encoder->Track(render_ready_semaphore);
|
||||
|
||||
if (!encoder->EndCommandBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
vk::SubmitInfo submit_info;
|
||||
|
||||
if (render_ready_semaphore) {
|
||||
static constexpr const auto kWaitStages =
|
||||
vk::PipelineStageFlagBits::eColorAttachmentOutput |
|
||||
vk::PipelineStageFlagBits::eFragmentShader |
|
||||
vk::PipelineStageFlagBits::eTransfer;
|
||||
submit_info.setWaitSemaphores(render_ready_semaphore->Get());
|
||||
submit_info.setWaitDstStageMask(kWaitStages);
|
||||
}
|
||||
|
||||
submit_info.setCommandBuffers(command_buffer_vk);
|
||||
|
||||
auto result = ContextVK::Cast(*context).GetGraphicsQueue()->Submit(
|
||||
submit_info, *completion_fence);
|
||||
if (result != vk::Result::eSuccess) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ContextVK::Cast(*context).GetFenceWaiter()->AddFence(
|
||||
std::move(completion_fence), [encoder]() {});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ class AHBSwapchainImplVK final
|
||||
bool Present(const AutoSemaSignaler& signaler,
|
||||
const std::shared_ptr<AHBTextureSourceVK>& texture);
|
||||
|
||||
vk::UniqueSemaphore CreateRenderReadySemaphore(
|
||||
vk::UniqueFence CreateRenderReadyFence(
|
||||
const std::shared_ptr<fml::UniqueFD>& fd) const;
|
||||
|
||||
bool SubmitWaitForRenderReady(
|
||||
|
||||
@ -55,28 +55,24 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO(148139): Fix synchronization issues on present.
|
||||
if constexpr (false) {
|
||||
// TODO(147533): AHB swapchains on emulators are not functional.
|
||||
const auto emulator =
|
||||
ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
|
||||
// TODO(147533): AHB swapchains on emulators are not functional.
|
||||
const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
|
||||
|
||||
// Try AHB swapchains first.
|
||||
if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) {
|
||||
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
|
||||
context, //
|
||||
window.GetHandle(), //
|
||||
surface, //
|
||||
window.GetSize(), //
|
||||
enable_msaa //
|
||||
));
|
||||
// Try AHB swapchains first.
|
||||
if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) {
|
||||
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
|
||||
context, //
|
||||
window.GetHandle(), //
|
||||
surface, //
|
||||
window.GetSize(), //
|
||||
enable_msaa //
|
||||
));
|
||||
|
||||
if (ahb_swapchain->IsValid()) {
|
||||
return ahb_swapchain;
|
||||
} else {
|
||||
VALIDATION_LOG
|
||||
<< "Could not create AHB swapchain. Falling back to KHR variant.";
|
||||
}
|
||||
if (ahb_swapchain->IsValid()) {
|
||||
return ahb_swapchain;
|
||||
} else {
|
||||
VALIDATION_LOG
|
||||
<< "Could not create AHB swapchain. Falling back to KHR variant.";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user