mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 13:55:38 +00:00
System: Centralize frame presentation
This commit is contained in:
parent
358f87a74d
commit
afaf5ddafd
|
@ -275,7 +275,7 @@ void Host::UpdateDisplayWindow()
|
|||
|
||||
// If we're paused, re-present the current frame at the new window size.
|
||||
if (System::IsValid() && System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
System::InvalidateDisplay();
|
||||
}
|
||||
|
||||
void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
|
||||
|
@ -292,7 +292,7 @@ void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
|
|||
if (System::IsValid())
|
||||
{
|
||||
if (System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
System::InvalidateDisplay();
|
||||
|
||||
System::HostDisplayResized();
|
||||
}
|
||||
|
@ -338,50 +338,3 @@ std::unique_ptr<AudioStream> Host::CreateAudioStream(AudioBackend backend, u32 s
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Host::RenderDisplay(bool skip_present)
|
||||
{
|
||||
Host::BeginPresentFrame();
|
||||
|
||||
// acquire for IO.MousePos.
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
|
||||
if (!skip_present)
|
||||
{
|
||||
FullscreenUI::Render();
|
||||
ImGuiManager::RenderTextOverlays();
|
||||
ImGuiManager::RenderOSDMessages();
|
||||
ImGuiManager::RenderSoftwareCursors();
|
||||
}
|
||||
|
||||
// Debug windows are always rendered, otherwise mouse input breaks on skip.
|
||||
ImGuiManager::RenderOverlayWindows();
|
||||
ImGuiManager::RenderDebugWindows();
|
||||
|
||||
bool do_present;
|
||||
if (g_gpu && !skip_present)
|
||||
do_present = g_gpu->PresentDisplay();
|
||||
else
|
||||
do_present = g_gpu_device->BeginPresent(skip_present);
|
||||
|
||||
if (do_present)
|
||||
{
|
||||
g_gpu_device->RenderImGui();
|
||||
g_gpu_device->EndPresent();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still need to kick ImGui or it gets cranky.
|
||||
ImGui::Render();
|
||||
}
|
||||
|
||||
ImGuiManager::NewFrame();
|
||||
|
||||
if (g_gpu)
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
}
|
||||
|
||||
void Host::InvalidateDisplay()
|
||||
{
|
||||
RenderDisplay(false);
|
||||
}
|
||||
|
|
|
@ -104,10 +104,6 @@ void ReleaseGPUDevice();
|
|||
/// Called before drawing the OSD and other display elements.
|
||||
void BeginPresentFrame();
|
||||
|
||||
/// Provided by the host; renders the display.
|
||||
void RenderDisplay(bool skip_present);
|
||||
void InvalidateDisplay();
|
||||
|
||||
namespace Internal {
|
||||
/// Retrieves the base settings layer. Must call with lock held.
|
||||
SettingsInterface* GetBaseSettingsLayer();
|
||||
|
|
|
@ -55,7 +55,6 @@ static void HotkeyModifyResolutionScale(s32 increment)
|
|||
g_gpu->RestoreGraphicsAPIState();
|
||||
g_gpu->UpdateSettings();
|
||||
System::ClearMemorySaveStates();
|
||||
Host::InvalidateDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "util/audio_stream.h"
|
||||
#include "util/cd_image.h"
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/imgui_manager.h"
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/iso_reader.h"
|
||||
|
@ -54,6 +55,7 @@
|
|||
|
||||
#include "fmt/chrono.h"
|
||||
#include "fmt/format.h"
|
||||
#include "imgui.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
#include <cctype>
|
||||
|
@ -1109,6 +1111,7 @@ void System::PauseSystem(bool paused)
|
|||
PlatformMisc::ResumeScreensaver();
|
||||
|
||||
Host::OnSystemPaused();
|
||||
InvalidateDisplay();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1173,7 +1176,7 @@ bool System::LoadState(const char* filename)
|
|||
|
||||
ResetPerformanceCounters();
|
||||
ResetThrottler();
|
||||
Host::RenderDisplay(false);
|
||||
InvalidateDisplay();
|
||||
Log_VerbosePrintf("Loading state took %.2f msec", load_timer.GetTimeMilliseconds());
|
||||
return true;
|
||||
}
|
||||
|
@ -1764,6 +1767,15 @@ void System::FrameDone()
|
|||
if (s_cheat_list)
|
||||
s_cheat_list->Apply();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::FrameUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
if (s_frame_step_request)
|
||||
{
|
||||
s_frame_step_request = false;
|
||||
|
@ -1811,27 +1823,10 @@ void System::FrameDone()
|
|||
SaveRunaheadState();
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::FrameUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
const Common::Timer::Value current_time = Common::Timer::GetCurrentValue();
|
||||
if (current_time < s_next_frame_time || s_display_all_frames || s_last_frame_skipped)
|
||||
{
|
||||
s_last_frame_skipped = false;
|
||||
|
||||
const bool skip_present = g_gpu_device->ShouldSkipDisplayingFrame();
|
||||
Host::RenderDisplay(skip_present);
|
||||
if (!skip_present && g_gpu_device->IsGPUTimingEnabled())
|
||||
{
|
||||
s_accumulated_gpu_time += g_gpu_device->GetAndResetAccumulatedGPUTime();
|
||||
s_presents_since_last_update++;
|
||||
}
|
||||
s_last_frame_skipped = !PresentDisplay(true);
|
||||
}
|
||||
else if (current_time >= s_next_frame_time)
|
||||
{
|
||||
|
@ -1928,6 +1923,8 @@ void System::SingleStepCPU()
|
|||
g_gpu->FlushRender();
|
||||
SPU::GeneratePendingSamples();
|
||||
|
||||
InvalidateDisplay();
|
||||
|
||||
s_system_executing = false;
|
||||
}
|
||||
|
||||
|
@ -1966,7 +1963,7 @@ void System::RecreateSystem()
|
|||
|
||||
ResetPerformanceCounters();
|
||||
ResetThrottler();
|
||||
Host::RenderDisplay(false);
|
||||
InvalidateDisplay();
|
||||
|
||||
if (was_paused)
|
||||
PauseSystem(true);
|
||||
|
@ -3488,7 +3485,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
{
|
||||
// if debug device/threaded presentation change, we need to recreate the whole display
|
||||
const bool recreate_device = (g_settings.gpu_use_debug_device != old_settings.gpu_use_debug_device ||
|
||||
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation);
|
||||
g_settings.gpu_threaded_presentation != old_settings.gpu_threaded_presentation);
|
||||
|
||||
Host::AddFormattedOSDMessage(5.0f, TRANSLATE("OSDMessage", "Switching to %s%s GPU renderer."),
|
||||
Settings::GetRendererName(g_settings.gpu_renderer),
|
||||
|
@ -3594,7 +3591,7 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_settings.runahead_frames != old_settings.runahead_frames)
|
||||
{
|
||||
g_gpu->UpdateSettings();
|
||||
Host::InvalidateDisplay();
|
||||
InvalidateDisplay();
|
||||
}
|
||||
|
||||
if (g_settings.gpu_widescreen_hack != old_settings.gpu_widescreen_hack ||
|
||||
|
@ -3909,7 +3906,7 @@ void System::DoRewind()
|
|||
|
||||
s_next_frame_time += s_frame_period;
|
||||
|
||||
Host::RenderDisplay(false);
|
||||
InvalidateDisplay();
|
||||
Host::PumpMessagesOnCPUThread();
|
||||
|
||||
Throttle();
|
||||
|
@ -4578,7 +4575,6 @@ void System::ToggleSoftwareRendering()
|
|||
Host::AddKeyedFormattedOSDMessage("SoftwareRendering", 5.0f, TRANSLATE("OSDMessage", "Switching to %s renderer..."),
|
||||
Settings::GetRendererDisplayName(new_renderer));
|
||||
RecreateGPU(new_renderer);
|
||||
Host::InvalidateDisplay();
|
||||
ResetPerformanceCounters();
|
||||
}
|
||||
|
||||
|
@ -4644,6 +4640,63 @@ void System::HostDisplayResized()
|
|||
g_gpu->UpdateResolutionScale();
|
||||
}
|
||||
|
||||
bool System::PresentDisplay(bool allow_skip_present)
|
||||
{
|
||||
const bool skip_present = allow_skip_present && g_gpu_device->ShouldSkipDisplayingFrame();
|
||||
|
||||
Host::BeginPresentFrame();
|
||||
|
||||
// acquire for IO.MousePos.
|
||||
std::atomic_thread_fence(std::memory_order_acquire);
|
||||
|
||||
if (!skip_present)
|
||||
{
|
||||
FullscreenUI::Render();
|
||||
ImGuiManager::RenderTextOverlays();
|
||||
ImGuiManager::RenderOSDMessages();
|
||||
ImGuiManager::RenderSoftwareCursors();
|
||||
}
|
||||
|
||||
// Debug windows are always rendered, otherwise mouse input breaks on skip.
|
||||
ImGuiManager::RenderOverlayWindows();
|
||||
ImGuiManager::RenderDebugWindows();
|
||||
|
||||
bool do_present;
|
||||
if (g_gpu && !skip_present)
|
||||
do_present = g_gpu->PresentDisplay();
|
||||
else
|
||||
do_present = g_gpu_device->BeginPresent(skip_present);
|
||||
|
||||
if (do_present)
|
||||
{
|
||||
g_gpu_device->RenderImGui();
|
||||
g_gpu_device->EndPresent();
|
||||
|
||||
if (g_gpu_device->IsGPUTimingEnabled())
|
||||
{
|
||||
s_accumulated_gpu_time += g_gpu_device->GetAndResetAccumulatedGPUTime();
|
||||
s_presents_since_last_update++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still need to kick ImGui or it gets cranky.
|
||||
ImGui::Render();
|
||||
}
|
||||
|
||||
ImGuiManager::NewFrame();
|
||||
|
||||
if (g_gpu)
|
||||
g_gpu->RestoreGraphicsAPIState();
|
||||
|
||||
return do_present;
|
||||
}
|
||||
|
||||
void System::InvalidateDisplay()
|
||||
{
|
||||
PresentDisplay(false);
|
||||
}
|
||||
|
||||
void System::SetTimerResolutionIncreased(bool enabled)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
|
|
@ -448,6 +448,10 @@ void RequestDisplaySize(float scale = 0.0f);
|
|||
/// Call when host display size changes, use with "match display" aspect ratio setting.
|
||||
void HostDisplayResized();
|
||||
|
||||
/// Renders the display.
|
||||
bool PresentDisplay(bool allow_skip_present);
|
||||
void InvalidateDisplay();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Memory Save States (Rewind and Runahead)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -415,8 +415,6 @@ void EmuThread::applySettings(bool display_osd_messages /* = false */)
|
|||
}
|
||||
|
||||
System::ApplySettings(display_osd_messages);
|
||||
if (!FullscreenUI::IsInitialized() && System::IsPaused())
|
||||
redrawDisplayWindow();
|
||||
}
|
||||
|
||||
void EmuThread::reloadGameSettings(bool display_osd_messages /* = false */)
|
||||
|
@ -428,8 +426,6 @@ void EmuThread::reloadGameSettings(bool display_osd_messages /* = false */)
|
|||
}
|
||||
|
||||
System::ReloadGameSettings(display_osd_messages);
|
||||
if (!FullscreenUI::IsInitialized() && System::IsPaused())
|
||||
redrawDisplayWindow();
|
||||
}
|
||||
|
||||
void EmuThread::updateEmuFolders()
|
||||
|
@ -509,11 +505,7 @@ void EmuThread::bootSystem(std::shared_ptr<SystemBootParameters> params)
|
|||
|
||||
setInitialState(params->override_fullscreen);
|
||||
|
||||
if (!System::BootSystem(std::move(*params)))
|
||||
return;
|
||||
|
||||
// force a frame to be drawn to repaint the window
|
||||
Host::InvalidateDisplay();
|
||||
System::BootSystem(std::move(*params));
|
||||
}
|
||||
|
||||
void EmuThread::bootOrLoadState(std::string path)
|
||||
|
@ -606,7 +598,7 @@ void EmuThread::redrawDisplayWindow()
|
|||
if (!g_gpu_device || System::IsShutdown())
|
||||
return;
|
||||
|
||||
Host::RenderDisplay(false);
|
||||
System::InvalidateDisplay();
|
||||
}
|
||||
|
||||
void EmuThread::toggleFullscreen()
|
||||
|
@ -726,7 +718,6 @@ void Host::OnSystemPaused()
|
|||
{
|
||||
emit g_emu_thread->systemPaused();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
Host::InvalidateDisplay();
|
||||
}
|
||||
|
||||
void Host::OnSystemResumed()
|
||||
|
@ -1137,7 +1128,6 @@ void EmuThread::singleStepCPU()
|
|||
return;
|
||||
|
||||
System::SingleStepCPU();
|
||||
Host::InvalidateDisplay();
|
||||
}
|
||||
|
||||
void EmuThread::dumpRAM(const QString& filename)
|
||||
|
@ -1342,7 +1332,7 @@ void EmuThread::run()
|
|||
System::Internal::IdlePollUpdate();
|
||||
if (g_gpu_device)
|
||||
{
|
||||
Host::RenderDisplay(false);
|
||||
System::PresentDisplay(false);
|
||||
if (!g_gpu_device->IsVsyncEnabled())
|
||||
g_gpu_device->ThrottlePresentation();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue