[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")
staticruntime("Off")
optimize("Off")
removedefines({
"IMGUI_USE_STB_SPRINTF",
})
defines({
"DEBUG",
})

View File

@@ -1459,7 +1459,11 @@ void EmulatorWindow::ToggleProfilesConfigDialog() {
} else {
disable_hotkeys_ = false;
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_--;
}
}

View File

@@ -168,6 +168,16 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
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()) {
ImGui::TextUnformatted("No profiles found!");
ImGui::Spacing();
@@ -291,11 +301,6 @@ void ProfileConfigDialog::OnDraw(ImGuiIO& io) {
}
ImGui::End();
if (!dialog_open) {
emulator_window_->ToggleProfilesConfigDialog();
return;
}
}
} // namespace app

View File

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

View File

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

View File

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

View File

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

View File

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