[UI] Fixed issues with ImGui on Vulkan and few ASAN issues related to ImGui

- Simplified handling of notifications to faster version with ranges
- Removed usage of STB sprintf on checked due to ASAN violation
- Draw ImGui windows only when they're not in close_pending state
This commit is contained in:
Gliniak
2025-10-13 22:08:52 +02:00
parent f7ed633960
commit e27b1d1cb5
8 changed files with 40 additions and 36 deletions

View File

@@ -66,6 +66,9 @@ filter("configurations:Checked")
editandcontinue("Off") editandcontinue("Off")
staticruntime("Off") staticruntime("Off")
optimize("Off") optimize("Off")
removedefines({
"IMGUI_USE_STB_SPRINTF",
})
defines({ defines({
"DEBUG", "DEBUG",
}) })

View File

@@ -1459,7 +1459,11 @@ void EmulatorWindow::ToggleProfilesConfigDialog() {
} else { } else {
disable_hotkeys_ = false; disable_hotkeys_ = false;
emulator_->kernel_state()->BroadcastNotification(kXNotificationSystemUI, 0); emulator_->kernel_state()->BroadcastNotification(kXNotificationSystemUI, 0);
profile_config_dialog_.reset(); if (profile_config_dialog_->IsClosing()) {
profile_config_dialog_.release();
} else {
profile_config_dialog_.reset();
}
emulator_->kernel_state()->xam_state()->xam_dialogs_shown_--; emulator_->kernel_state()->xam_state()->xam_dialogs_shown_--;
} }
} }

View File

@@ -168,6 +168,16 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
return; return;
} }
// For whatever reason dialog wasn't opened. It's probably in closing state.
// We need to handle it here before it will make icons allocation.
if (!dialog_open) {
ImGui::CloseCurrentPopup();
Close();
ImGui::End();
emulator_window_->ToggleProfilesConfigDialog();
return;
}
if (profiles->empty()) { if (profiles->empty()) {
ImGui::TextUnformatted("No profiles found!"); ImGui::TextUnformatted("No profiles found!");
ImGui::Spacing(); ImGui::Spacing();
@@ -291,11 +301,6 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
} }
ImGui::End(); ImGui::End();
if (!dialog_open) {
emulator_window_->ToggleProfilesConfigDialog();
return;
}
} }
} // namespace app } // namespace app

View File

@@ -358,10 +358,7 @@ void D3D12ImmediateDrawer::Begin(UIDrawContext& ui_draw_context,
++it; ++it;
continue; continue;
} }
if (std::next(it) != textures_deleted_.end()) { it = textures_deleted_.erase(it);
*it = textures_deleted_.back();
}
textures_deleted_.pop_back();
} }
// Release upload buffers for completed texture uploads. // Release upload buffers for completed texture uploads.

View File

@@ -41,7 +41,9 @@ ImGuiIO& ImGuiDialog::GetIO() { return imgui_drawer()->GetIO(); }
void ImGuiDialog::Draw() { void ImGuiDialog::Draw() {
// Draw UI. // Draw UI.
OnDraw(GetIO()); if (!has_close_pending_) {
OnDraw(GetIO());
}
// Check to see if the UI closed itself and needs to be deleted. // Check to see if the UI closed itself and needs to be deleted.
if (has_close_pending_) { if (has_close_pending_) {

View File

@@ -34,6 +34,8 @@ class ImGuiDialog {
void Draw(); void Draw();
bool IsClosing() const { return has_close_pending_; }
protected: protected:
ImGuiDialog(ImGuiDrawer* imgui_drawer); ImGuiDialog(ImGuiDrawer* imgui_drawer);

View File

@@ -11,6 +11,7 @@
#include <cfloat> #include <cfloat>
#include <cstring> #include <cstring>
#include <ranges>
#include "third_party/imgui/imgui.h" #include "third_party/imgui/imgui.h"
#include "xenia/base/assert.h" #include "xenia/base/assert.h"
@@ -597,32 +598,25 @@ void ImGuiDrawer::Draw(UIDrawContext& ui_draw_context) {
dialog_loop_next_index_ = SIZE_MAX; dialog_loop_next_index_ = SIZE_MAX;
if (!notifications_.empty() && are_notifications_enabled_) { if (!notifications_.empty() && are_notifications_enabled_) {
std::vector<ui::ImGuiNotification*> guest_notifications = {}; auto guest_notifications =
std::vector<ui::ImGuiNotification*> host_notifications = {}; notifications_ | std::views::filter([](auto* notification) {
return notification->GetNotificationType() == NotificationType::Guest;
});
std::copy_if(notifications_.cbegin(), notifications_.cend(), auto host_notifications =
std::back_inserter(guest_notifications), notifications_ | std::views::filter([](auto* notification) {
[](ui::ImGuiNotification* notification) { return notification->GetNotificationType() == NotificationType::Host;
return notification->GetNotificationType() == });
NotificationType::Guest;
});
std::copy_if(notifications_.cbegin(), notifications_.cend(), if (!guest_notifications.empty()) {
std::back_inserter(host_notifications), guest_notifications.front()->Draw();
[](ui::ImGuiNotification* notification) {
return notification->GetNotificationType() ==
NotificationType::Host;
});
if (guest_notifications.size() > 0) {
guest_notifications.at(0)->Draw();
} }
if (host_notifications.size() > 0) { if (!host_notifications.empty()) {
host_notifications.at(0)->Draw(); host_notifications.front()->Draw();
if (host_notifications.size() > 1) { if (std::ranges::distance(host_notifications) > 1) {
host_notifications.at(0)->SetDeletionPending(); host_notifications.front()->SetDeletionPending();
} }
} }
} }

View File

@@ -223,10 +223,7 @@ void VulkanImmediateDrawer::Begin(UIDrawContext& ui_draw_context,
continue; continue;
} }
DestroyTextureResource(it->first); DestroyTextureResource(it->first);
if (std::next(it) != textures_deleted_.end()) { it = textures_deleted_.erase(it);
*it = textures_deleted_.back();
}
textures_deleted_.pop_back();
} }
// Release upload buffers for completed texture uploads. // Release upload buffers for completed texture uploads.