mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-04 05:04:33 +00:00
ImGuiManager: Run idle when OSD messages are present
So we don't miss them.
This commit is contained in:
@@ -1485,6 +1485,22 @@ void GPUThread::SetRunIdleReason(RunIdleReason reason, bool enabled)
|
||||
if (((s_state.run_idle_reasons & bit) != 0) == enabled)
|
||||
return;
|
||||
|
||||
if (Log::IsLogVisible(Log::Level::Dev, Log::Channel::GPUThread))
|
||||
{
|
||||
static constexpr const std::array reason_strings = {
|
||||
"NoGPUBackend", "SystemPaused", "OSDMessagesActive", "FullscreenUIActive",
|
||||
"NotificationsActive", "LoadingScreenActive", "AchievementOverlaysActive",
|
||||
};
|
||||
for (u32 i = 0; i < reason_strings.size(); ++i)
|
||||
{
|
||||
if (static_cast<RunIdleReason>(1u << i) == reason)
|
||||
{
|
||||
DEV_COLOR_LOG(StrongYellow, "Setting run idle reason '{}' to {}", reason_strings[i], enabled);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s_state.run_idle_reasons = enabled ? (s_state.run_idle_reasons | bit) : (s_state.run_idle_reasons & ~bit);
|
||||
UpdateRunIdle();
|
||||
}
|
||||
@@ -1508,8 +1524,9 @@ void GPUThread::UpdateRunIdle()
|
||||
static_cast<u8>(RunIdleReason::SystemPaused) |
|
||||
static_cast<u8>(RunIdleReason::LoadingScreenActive);
|
||||
static constexpr u8 ACTIVATE_MASK =
|
||||
static_cast<u8>(RunIdleReason::FullscreenUIActive) | static_cast<u8>(RunIdleReason::NotificationsActive) |
|
||||
static_cast<u8>(RunIdleReason::LoadingScreenActive) | static_cast<u8>(RunIdleReason::AchievementOverlaysActive);
|
||||
static_cast<u8>(RunIdleReason::OSDMessagesActive) | static_cast<u8>(RunIdleReason::FullscreenUIActive) |
|
||||
static_cast<u8>(RunIdleReason::NotificationsActive) | static_cast<u8>(RunIdleReason::LoadingScreenActive) |
|
||||
static_cast<u8>(RunIdleReason::AchievementOverlaysActive);
|
||||
|
||||
const bool new_flag = (g_gpu_device && ((s_state.run_idle_reasons & REQUIRE_MASK) != 0) &&
|
||||
((s_state.run_idle_reasons & ACTIVATE_MASK) != 0));
|
||||
|
||||
@@ -36,10 +36,11 @@ enum class RunIdleReason : u8
|
||||
{
|
||||
NoGPUBackend = (1 << 0),
|
||||
SystemPaused = (1 << 1),
|
||||
FullscreenUIActive = (1 << 2),
|
||||
NotificationsActive = (1 << 3),
|
||||
LoadingScreenActive = (1 << 4),
|
||||
AchievementOverlaysActive = (1 << 5),
|
||||
OSDMessagesActive = (1 << 2),
|
||||
FullscreenUIActive = (1 << 3),
|
||||
NotificationsActive = (1 << 4),
|
||||
LoadingScreenActive = (1 << 5),
|
||||
AchievementOverlaysActive = (1 << 6),
|
||||
};
|
||||
|
||||
/// Starts Big Picture UI.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "core/gpu_thread.h"
|
||||
#include "core/host.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/system_private.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/bitutils.h"
|
||||
@@ -24,6 +25,7 @@
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/thirdparty/usb_key_code_data.h"
|
||||
#include "common/threading.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
#include "IconsEmoji.h"
|
||||
@@ -101,6 +103,7 @@ static void AddOSDMessage(OSDMessageType type, std::string key, std::string icon
|
||||
std::string message);
|
||||
static void RemoveKeyedOSDMessage(std::string key);
|
||||
static void ClearOSDMessages();
|
||||
static void UpdateOSDMessageRunIdle(const std::unique_lock<std::mutex>& lock);
|
||||
static void AcquirePendingOSDMessages(Timer::Value current_time);
|
||||
static void DrawOSDMessages(Timer::Value current_time);
|
||||
static void CreateSoftwareCursorTextures();
|
||||
@@ -868,6 +871,41 @@ void ImGuiManager::AddOSDMessage(OSDMessageType type, std::string key, std::stri
|
||||
.text = std::move(message),
|
||||
.type = type,
|
||||
});
|
||||
|
||||
// trigger run idle on first message
|
||||
if (s_state.osd_posted_messages.size() == 1)
|
||||
UpdateOSDMessageRunIdle(lock);
|
||||
}
|
||||
|
||||
void ImGuiManager::UpdateOSDMessageRunIdle(const std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
static constexpr auto cb = []() {
|
||||
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::OSDMessagesActive,
|
||||
(!s_state.osd_active_messages.empty() || !s_state.osd_posted_messages.empty()));
|
||||
};
|
||||
|
||||
if (GPUThread::IsOnThread())
|
||||
{
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
|
||||
if (System::GetCoreThreadHandle().IsCallingThread())
|
||||
{
|
||||
GPUThread::RunOnThread([]() {
|
||||
const std::unique_lock lock(s_state.osd_messages_lock);
|
||||
cb();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::RunOnCoreThread([]() {
|
||||
GPUThread::RunOnThread([]() {
|
||||
const std::unique_lock lock(s_state.osd_messages_lock);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiManager::RemoveKeyedOSDMessage(std::string key)
|
||||
@@ -880,6 +918,8 @@ void ImGuiManager::RemoveKeyedOSDMessage(std::string key)
|
||||
.text = {},
|
||||
.type = OSDMessageType::MaxCount,
|
||||
});
|
||||
if (s_state.osd_posted_messages.size() == 1)
|
||||
UpdateOSDMessageRunIdle(lock);
|
||||
}
|
||||
|
||||
void ImGuiManager::ClearOSDMessages()
|
||||
@@ -894,16 +934,8 @@ void ImGuiManager::ClearOSDMessages()
|
||||
|
||||
void ImGuiManager::AcquirePendingOSDMessages(Timer::Value current_time)
|
||||
{
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
if (s_state.osd_posted_messages.empty())
|
||||
return;
|
||||
|
||||
std::unique_lock lock(s_state.osd_messages_lock);
|
||||
for (;;)
|
||||
while (!s_state.osd_posted_messages.empty())
|
||||
{
|
||||
if (s_state.osd_posted_messages.empty())
|
||||
break;
|
||||
|
||||
PostedOSDMessage& new_msg = s_state.osd_posted_messages.front();
|
||||
|
||||
// MaxCount is used to indicate removal of a message.
|
||||
@@ -1151,9 +1183,22 @@ void ImGuiManager::DrawOSDMessages(Timer::Value current_time)
|
||||
|
||||
void ImGuiManager::RenderOSDMessages()
|
||||
{
|
||||
s_state.osd_messages_lock.lock();
|
||||
if (s_state.osd_posted_messages.empty() && s_state.osd_active_messages.empty())
|
||||
{
|
||||
s_state.osd_messages_lock.unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
const Timer::Value current_time = Timer::GetCurrentValue();
|
||||
AcquirePendingOSDMessages(current_time);
|
||||
s_state.osd_messages_lock.unlock();
|
||||
|
||||
DrawOSDMessages(current_time);
|
||||
|
||||
// last one displayed?
|
||||
if (s_state.osd_active_messages.empty())
|
||||
GPUThread::SetRunIdleReason(GPUThread::RunIdleReason::OSDMessagesActive, false);
|
||||
}
|
||||
|
||||
void Host::AddOSDMessage(OSDMessageType type, std::string message)
|
||||
|
||||
Reference in New Issue
Block a user