system: keep error dialogs open until dismissed

This commit is contained in:
nmzik
2026-09-06 08:34:58 +04:00
parent 44f982bca7
commit 997ad60c50
12 changed files with 466 additions and 156 deletions
+34 -31
View File
@@ -9,8 +9,8 @@
#include "graphics/host_gpu/renderer/renderContext.h"
#include "graphics/host_gpu/vma.h"
#include "graphics/host_gpu/vulkanCommon.h"
#include "graphics/presentation/imeOverlay.h"
#include "graphics/presentation/presenter.h"
#include "graphics/presentation/systemOverlay.h"
#include "graphics/presentation/videoOut.h"
#include "graphics/presentation/window/windowInternal.h"
@@ -293,8 +293,9 @@ public:
void Create();
void Recreate(bool surface_lost = false);
[[nodiscard]] Status AcquireNextImage();
[[nodiscard]] bool PrepareImeOverlay();
void RecordPresentCommands(CommandBuffer& command, VulkanImage& source, bool draw_ime_overlay);
[[nodiscard]] bool PrepareSystemOverlay();
void RecordPresentCommands(CommandBuffer& command, VulkanImage& source,
bool draw_system_overlay);
uint64_t Submit(CommandScheduler& scheduler);
[[nodiscard]] Status Present();
@@ -314,7 +315,7 @@ private:
std::vector<vk::ImageView> m_image_views;
std::vector<vk::Semaphore> m_image_acquired;
std::vector<vk::Semaphore> m_render_complete;
std::unique_ptr<ImeOverlay> m_ime_overlay;
std::unique_ptr<SystemOverlay> m_system_overlay;
uint32_t m_image_index = static_cast<uint32_t>(-1);
uint32_t m_frame_index = 0;
};
@@ -361,7 +362,7 @@ struct Presenter::Impl {
Swapchain swapchain;
CommandScheduler present_scheduler;
FramePool frames;
std::atomic<uint64_t> presented_ime_revision {0};
std::atomic<uint64_t> presented_overlay_revision {0};
};
void Swapchain::Create() {
@@ -504,8 +505,8 @@ void Swapchain::Destroy() {
Common::LockGuard queue_lock(graphics.queue_mutex);
RequireVulkanSuccess(graphics.queue.waitIdle(), "wait for swapchain queue");
}
if (m_ime_overlay != nullptr) {
m_ime_overlay->ReleaseVulkan();
if (m_system_overlay != nullptr) {
m_system_overlay->ReleaseVulkan();
}
for (const auto semaphore: m_image_acquired) {
@@ -579,15 +580,15 @@ Swapchain::Status Swapchain::AcquireNextImage() {
return Status::Success;
}
bool Swapchain::PrepareImeOverlay() {
if (m_ime_overlay == nullptr) {
m_ime_overlay = std::make_unique<ImeOverlay>(m_window.graphic_ctx);
bool Swapchain::PrepareSystemOverlay() {
if (m_system_overlay == nullptr) {
m_system_overlay = std::make_unique<SystemOverlay>(m_window.graphic_ctx);
}
return m_ime_overlay->PrepareFrame(m_extent, m_format, ImageCount());
return m_system_overlay->PrepareFrame(m_extent, m_format, ImageCount());
}
void Swapchain::RecordPresentCommands(CommandBuffer& command, VulkanImage& source,
bool draw_ime_overlay) {
bool draw_system_overlay) {
if (source.state.layout != vk::ImageLayout::eTransferSrcOptimal) {
EXIT("invalid prepared presentation image, vk_image=%p layout=%d\n",
static_cast<void*>(source.image), static_cast<int>(source.state.layout));
@@ -635,12 +636,12 @@ void Swapchain::RecordPresentCommands(CommandBuffer& command, VulkanImage& sourc
vk::ImageMemoryBarrier to_present {};
to_present.sType = vk::StructureType::eImageMemoryBarrier;
to_present.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
to_present.dstAccessMask = draw_ime_overlay ? vk::AccessFlagBits::eColorAttachmentRead |
vk::AccessFlagBits::eColorAttachmentWrite
: vk::AccessFlagBits::eMemoryRead;
to_present.dstAccessMask = draw_system_overlay ? vk::AccessFlagBits::eColorAttachmentRead |
vk::AccessFlagBits::eColorAttachmentWrite
: vk::AccessFlagBits::eMemoryRead;
to_present.oldLayout = vk::ImageLayout::eTransferDstOptimal;
to_present.newLayout = draw_ime_overlay ? vk::ImageLayout::eColorAttachmentOptimal
: vk::ImageLayout::ePresentSrcKHR;
to_present.newLayout = draw_system_overlay ? vk::ImageLayout::eColorAttachmentOptimal
: vk::ImageLayout::ePresentSrcKHR;
to_present.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
to_present.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
to_present.image = m_images[m_image_index];
@@ -649,13 +650,13 @@ void Swapchain::RecordPresentCommands(CommandBuffer& command, VulkanImage& sourc
to_present.subresourceRange.levelCount = 1;
to_present.subresourceRange.baseArrayLayer = 0;
to_present.subresourceRange.layerCount = 1;
vk_command.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer,
draw_ime_overlay ? vk::PipelineStageFlagBits::eColorAttachmentOutput
: vk::PipelineStageFlagBits::eAllCommands,
vk::DependencyFlagBits::eByRegion, 0, nullptr, 0, nullptr, 1,
&to_present);
if (draw_ime_overlay) {
m_ime_overlay->Record(vk_command, m_image_views[m_image_index]);
vk_command.pipelineBarrier(
vk::PipelineStageFlagBits::eTransfer,
draw_system_overlay ? vk::PipelineStageFlagBits::eColorAttachmentOutput
: vk::PipelineStageFlagBits::eAllCommands,
vk::DependencyFlagBits::eByRegion, 0, nullptr, 0, nullptr, 1, &to_present);
if (draw_system_overlay) {
m_system_overlay->Record(vk_command, m_image_views[m_image_index]);
to_present.srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite;
to_present.dstAccessMask = vk::AccessFlagBits::eMemoryRead;
to_present.oldLayout = vk::ImageLayout::eColorAttachmentOptimal;
@@ -762,10 +763,10 @@ bool Presenter::IsGuestPaused() const noexcept {
return m_impl->window.loop.paused.load(std::memory_order_acquire);
}
bool Presenter::NeedsImeRefresh() const noexcept {
const auto visual = GetImeVisualState();
bool Presenter::NeedsSystemOverlayRefresh() const noexcept {
const auto visual = GetSystemOverlayVisualState();
return visual.active ||
visual.revision != m_impl->presented_ime_revision.load(std::memory_order_acquire);
visual.revision != m_impl->presented_overlay_revision.load(std::memory_order_acquire);
}
RenderContext& Presenter::Renderer() const noexcept {
@@ -776,7 +777,7 @@ void Presenter::Present(Frame& frame, bool reuse) {
KYTY_PROFILER_FUNCTION();
m_impl->frames.ValidateForPresent(&frame, reuse);
const auto ime_visual = GetImeVisualState();
const auto overlay_visual = GetSystemOverlayVisualState();
auto& swapchain = m_impl->swapchain;
for (uint32_t attempt = 0; attempt < 2; attempt++) {
auto status = swapchain.AcquireNextImage();
@@ -787,8 +788,9 @@ void Presenter::Present(Frame& frame, bool reuse) {
{
Common::LockGuard render_lock(m_impl->renderer.GetMutex());
auto& command = m_impl->present_scheduler.BeginCommand();
const bool draw_ime_overlay = ime_visual.active && swapchain.PrepareImeOverlay();
swapchain.RecordPresentCommands(command, frame.image, draw_ime_overlay);
const bool draw_system_overlay =
overlay_visual.active && swapchain.PrepareSystemOverlay();
swapchain.RecordPresentCommands(command, frame.image, draw_system_overlay);
frame.present_tick = swapchain.Submit(m_impl->present_scheduler);
}
status = swapchain.Present();
@@ -797,7 +799,8 @@ void Presenter::Present(Frame& frame, bool reuse) {
continue;
}
m_impl->presented_ime_revision.store(ime_visual.revision, std::memory_order_release);
m_impl->presented_overlay_revision.store(overlay_visual.revision,
std::memory_order_release);
m_impl->window.UpdateTitle();
m_impl->frames.Release(&frame, true);
return;