mirror of https://github.com/PCSX2/pcsx2.git
GS: Manually throttle fullscreen UI rendering
Fixes rendering at thousands of FPS when pausing if FSUI is active. Avoids flickering when recreating swap chain in vulkan on menu open, because we're no longer doing it.
This commit is contained in:
parent
aea6a9f534
commit
77e9938f0f
|
@ -265,7 +265,8 @@ bool Host::AcquireHostDisplay(RenderAPI api, bool clear_state_on_fail)
|
|||
if (!g_host_display)
|
||||
return false;
|
||||
|
||||
if (!g_host_display->CreateDevice(wi.value()) || !g_host_display->MakeCurrent() || !g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||
if (!g_host_display->CreateDevice(wi.value(), Host::GetEffectiveVSyncMode()) ||
|
||||
!g_host_display->MakeCurrent() || !g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||
{
|
||||
ReleaseHostDisplay(clear_state_on_fail);
|
||||
return false;
|
||||
|
@ -283,12 +284,6 @@ void Host::ReleaseHostDisplay(bool clear_state)
|
|||
g_host_display.reset();
|
||||
}
|
||||
|
||||
VsyncMode Host::GetEffectiveVSyncMode()
|
||||
{
|
||||
// Never vsync! We want to finish as quickly as possible.
|
||||
return VsyncMode::Off;
|
||||
}
|
||||
|
||||
bool Host::BeginPresentFrame(bool frame_skip)
|
||||
{
|
||||
if (g_host_display->BeginPresent(frame_skip))
|
||||
|
|
|
@ -2012,7 +2012,7 @@ DisplayWidget* MainWindow::createDisplay(bool fullscreen, bool render_to_main)
|
|||
|
||||
g_emu_thread->connectDisplaySignals(m_display_widget);
|
||||
|
||||
if (!g_host_display->CreateDevice(wi.value()))
|
||||
if (!g_host_display->CreateDevice(wi.value(), Host::GetEffectiveVSyncMode()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("Failed to create host display device context."));
|
||||
destroyDisplayWidget(true);
|
||||
|
|
|
@ -931,26 +931,6 @@ void Host::ReleaseHostDisplay(bool clear_state)
|
|||
g_emu_thread->releaseHostDisplay(clear_state);
|
||||
}
|
||||
|
||||
VsyncMode Host::GetEffectiveVSyncMode()
|
||||
{
|
||||
// Force vsync on when running big picture UI, and paused or no VM.
|
||||
// We check the "running FSUI" flag here, because that way we set the initial vsync
|
||||
// state when initalizing to on, avoiding an unnecessary switch.
|
||||
if (FullscreenUI::HasActiveWindow() || (!FullscreenUI::IsInitialized() && g_emu_thread->isRunningFullscreenUI()))
|
||||
{
|
||||
const VMState state = VMManager::GetState();
|
||||
if (state == VMState::Shutdown || state == VMState::Paused)
|
||||
return VsyncMode::On;
|
||||
}
|
||||
|
||||
// Force vsync off when not running at 100% speed.
|
||||
if (EmuConfig.GS.LimitScalar != 1.0f)
|
||||
return VsyncMode::Off;
|
||||
|
||||
// Otherwise use the config setting.
|
||||
return EmuConfig.GS.VsyncEnable;
|
||||
}
|
||||
|
||||
bool Host::BeginPresentFrame(bool frame_skip)
|
||||
{
|
||||
if (!g_host_display->BeginPresent(frame_skip))
|
||||
|
|
|
@ -346,7 +346,6 @@ void CommonHost::OnVMDestroyed()
|
|||
void CommonHost::OnVMPaused()
|
||||
{
|
||||
InputManager::PauseVibration();
|
||||
FullscreenUI::OnVMPaused();
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::OnPaused(true);
|
||||
|
@ -357,8 +356,6 @@ void CommonHost::OnVMPaused()
|
|||
|
||||
void CommonHost::OnVMResumed()
|
||||
{
|
||||
FullscreenUI::OnVMResumed();
|
||||
|
||||
#ifdef ENABLE_ACHIEVEMENTS
|
||||
Achievements::OnPaused(false);
|
||||
#endif
|
||||
|
|
|
@ -46,7 +46,6 @@ static void HotkeyAdjustTargetSpeed(double delta)
|
|||
EmuConfig.Framerate.NominalScalar = std::max(min_speed, EmuConfig.GS.LimitScalar + delta);
|
||||
VMManager::SetLimiterMode(LimiterModeType::Nominal);
|
||||
gsUpdateFrequency(EmuConfig);
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
Host::AddIconOSDMessage("SpeedChanged", ICON_FA_CLOCK,
|
||||
fmt::format("Target speed set to {:.0f}%.", std::round(EmuConfig.Framerate.NominalScalar * 100.0)), Host::OSD_QUICK_DURATION);
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ void D3D11HostDisplay::SetVSync(VsyncMode mode)
|
|||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi, VsyncMode vsync)
|
||||
{
|
||||
UINT create_flags = 0;
|
||||
if (EmuConfig.GS.UseDebugDevice)
|
||||
|
@ -314,7 +314,7 @@ bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi)
|
|||
}
|
||||
|
||||
m_window_info = wi;
|
||||
m_vsync_mode = Host::GetEffectiveVSyncMode();
|
||||
m_vsync_mode = vsync;
|
||||
|
||||
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
||||
return false;
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
|
|
@ -136,7 +136,7 @@ void D3D12HostDisplay::SetVSync(VsyncMode mode)
|
|||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi, VsyncMode vsync)
|
||||
{
|
||||
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
||||
HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.put()));
|
||||
|
@ -190,7 +190,7 @@ bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi)
|
|||
}
|
||||
|
||||
m_window_info = wi;
|
||||
m_vsync_mode = Host::GetEffectiveVSyncMode();
|
||||
m_vsync_mode = vsync;
|
||||
|
||||
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
||||
return false;
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
|
|
@ -623,24 +623,6 @@ void FullscreenUI::OnVMStarted()
|
|||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::OnVMPaused()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
// Force vsync on.
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
}
|
||||
|
||||
void FullscreenUI::OnVMResumed()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
// Restore game vsync.
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
}
|
||||
|
||||
void FullscreenUI::OnVMDestroyed()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
|
@ -652,7 +634,6 @@ void FullscreenUI::OnVMDestroyed()
|
|||
|
||||
s_pause_menu_was_open = false;
|
||||
SwitchToLanding();
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,6 @@ namespace FullscreenUI
|
|||
bool HasActiveWindow();
|
||||
void CheckForConfigChanges(const Pcsx2Config& old_config);
|
||||
void OnVMStarted();
|
||||
void OnVMPaused();
|
||||
void OnVMResumed();
|
||||
void OnVMDestroyed();
|
||||
void OnRunningGameChanged(std::string path, std::string serial, std::string title, u32 crc);
|
||||
void OpenPauseMenu();
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
|
||||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) override;
|
||||
bool SetupDevice() override;
|
||||
bool MakeCurrent() override;
|
||||
bool DoneCurrent() override;
|
||||
|
|
|
@ -103,7 +103,7 @@ void MetalHostDisplay::DetachSurfaceOnMainThread()
|
|||
m_layer = nullptr;
|
||||
}
|
||||
|
||||
bool MetalHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool MetalHostDisplay::CreateDevice(const WindowInfo& wi, VsyncMode vsync)
|
||||
{ @autoreleasepool {
|
||||
m_window_info = wi;
|
||||
pxAssertRel(!m_dev.dev, "Device already created!");
|
||||
|
@ -152,7 +152,7 @@ bool MetalHostDisplay::CreateDevice(const WindowInfo& wi)
|
|||
{
|
||||
AttachSurfaceOnMainThread();
|
||||
});
|
||||
SetVSync(Host::GetEffectiveVSyncMode());
|
||||
SetVSync(vsync);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -143,7 +143,7 @@ void OpenGLHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y,
|
|||
|
||||
void OpenGLHostDisplay::SetVSync(VsyncMode mode)
|
||||
{
|
||||
if (m_gl_context->GetWindowInfo().type == WindowInfo::Type::Surfaceless)
|
||||
if (m_vsync_mode == mode || m_gl_context->GetWindowInfo().type == WindowInfo::Type::Surfaceless)
|
||||
return;
|
||||
|
||||
// Window framebuffer has to be bound to call SetSwapInterval.
|
||||
|
@ -155,6 +155,7 @@ void OpenGLHostDisplay::SetVSync(VsyncMode mode)
|
|||
m_gl_context->SetSwapInterval(static_cast<s32>(mode != VsyncMode::Off));
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo);
|
||||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
const char* OpenGLHostDisplay::GetGLSLVersionString() const
|
||||
|
@ -198,7 +199,7 @@ bool OpenGLHostDisplay::HasSurface() const
|
|||
return m_window_info.type != WindowInfo::Type::Surfaceless;
|
||||
}
|
||||
|
||||
bool OpenGLHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool OpenGLHostDisplay::CreateDevice(const WindowInfo& wi, VsyncMode vsync)
|
||||
{
|
||||
m_gl_context = GL::Context::Create(wi);
|
||||
if (!m_gl_context)
|
||||
|
@ -209,7 +210,7 @@ bool OpenGLHostDisplay::CreateDevice(const WindowInfo& wi)
|
|||
}
|
||||
|
||||
m_window_info = m_gl_context->GetWindowInfo();
|
||||
m_vsync_mode = Host::GetEffectiveVSyncMode();
|
||||
m_vsync_mode = vsync;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
|
|
@ -274,10 +274,9 @@ void VulkanHostDisplay::SetVSync(VsyncMode mode)
|
|||
m_vsync_mode = mode;
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi, VsyncMode vsync)
|
||||
{
|
||||
WindowInfo local_wi(wi);
|
||||
const VsyncMode vsync = Host::GetEffectiveVSyncMode();
|
||||
const bool debug_device = EmuConfig.GS.UseDebugDevice;
|
||||
if (!Vulkan::Context::Create(EmuConfig.GS.Adapter, &local_wi, &m_swap_chain, GetPreferredPresentModeForVsyncMode(vsync),
|
||||
EmuConfig.GS.ThreadedPresentation, debug_device, debug_device))
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
|
|
@ -74,6 +74,10 @@ void gsUpdateFrequency(Pcsx2Config& config)
|
|||
config.GS.LimitScalar = 0.0f;
|
||||
}
|
||||
|
||||
#ifdef PCSX2_CORE
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
#endif
|
||||
|
||||
UpdateVSyncRate();
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,7 @@ static HRESULT s_hr = E_FAIL;
|
|||
Pcsx2Config::GSOptions GSConfig;
|
||||
|
||||
static RenderAPI s_render_api;
|
||||
static u64 s_next_manual_present_time;
|
||||
|
||||
int GSinit()
|
||||
{
|
||||
|
@ -554,6 +555,33 @@ void GSPresentCurrentFrame()
|
|||
g_gs_renderer->PresentCurrentFrame();
|
||||
}
|
||||
|
||||
void GSThrottlePresentation()
|
||||
{
|
||||
if (g_host_display->GetVsyncMode() != VsyncMode::Off)
|
||||
{
|
||||
// Let vsync take care of throttling.
|
||||
return;
|
||||
}
|
||||
|
||||
// Manually throttle presentation when vsync isn't enabled, so we don't try to render the
|
||||
// fullscreen UI at thousands of FPS and make the gpu go brrrrrrrr.
|
||||
const float surface_refresh_rate = g_host_display->GetWindowInfo().surface_refresh_rate;
|
||||
const float throttle_rate = (surface_refresh_rate > 0.0f) ? surface_refresh_rate : 60.0f;
|
||||
|
||||
const u64 sleep_period = static_cast<u64>(static_cast<double>(GetTickFrequency()) / static_cast<double>(throttle_rate));
|
||||
const u64 current_ts = GetCPUTicks();
|
||||
|
||||
// Allow it to fall behind/run ahead up to 2*period. Sleep isn't that precise, plus we need to
|
||||
// allow time for the actual rendering.
|
||||
const u64 max_variance = sleep_period * 2;
|
||||
if (static_cast<u64>(std::abs(static_cast<s64>(current_ts - s_next_manual_present_time))) > max_variance)
|
||||
s_next_manual_present_time = current_ts + sleep_period;
|
||||
else
|
||||
s_next_manual_present_time += sleep_period;
|
||||
|
||||
Threading::SleepUntil(s_next_manual_present_time);
|
||||
}
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
|
||||
void GSkeyEvent(const HostKeyEvent& e)
|
||||
|
|
|
@ -72,6 +72,7 @@ int GSfreeze(FreezeAction mode, freezeData* data);
|
|||
void GSQueueSnapshot(const std::string& path, u32 gsdump_frames = 0);
|
||||
void GSStopGSDump();
|
||||
void GSPresentCurrentFrame();
|
||||
void GSThrottlePresentation();
|
||||
#ifndef PCSX2_CORE
|
||||
void GSkeyEvent(const HostKeyEvent& e);
|
||||
void GSconfigure();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
struct HostKeyEvent
|
||||
{
|
||||
enum class Type
|
||||
|
@ -43,6 +44,7 @@ struct HostKeyEvent
|
|||
Type type;
|
||||
u32 key;
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace Host
|
||||
{
|
||||
|
|
|
@ -16,9 +16,15 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "HostDisplay.h"
|
||||
|
||||
#ifdef PCSX2_CORE
|
||||
#include "VMManager.h"
|
||||
#endif
|
||||
|
||||
#include "common/Assertions.h"
|
||||
#include "common/Console.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
@ -128,6 +134,22 @@ std::string HostDisplay::GetFullscreenModeString(u32 width, u32 height, float re
|
|||
return StringUtil::StdStringFromFormat("%u x %u @ %f hz", width, height, refresh_rate);
|
||||
}
|
||||
|
||||
VsyncMode Host::GetEffectiveVSyncMode()
|
||||
{
|
||||
#ifdef PCSX2_CORE
|
||||
const bool has_vm = VMManager::GetState() != VMState::Shutdown;
|
||||
#else
|
||||
const bool has_vm = false;
|
||||
#endif
|
||||
|
||||
// Force vsync off when not running at 100% speed.
|
||||
if (has_vm && EmuConfig.GS.LimitScalar != 1.0f)
|
||||
return VsyncMode::Off;
|
||||
|
||||
// Otherwise use the config setting.
|
||||
return EmuConfig.GS.VsyncEnable;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_OPENGL
|
||||
#include "Frontend/OpenGLHostDisplay.h"
|
||||
#endif
|
||||
|
@ -173,4 +195,3 @@ std::unique_ptr<HostDisplay> HostDisplay::CreateForAPI(RenderAPI api)
|
|||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
__fi s32 GetWindowWidth() const { return static_cast<s32>(m_window_info.surface_width); }
|
||||
__fi s32 GetWindowHeight() const { return static_cast<s32>(m_window_info.surface_height); }
|
||||
__fi float GetWindowScale() const { return m_window_info.surface_scale; }
|
||||
__fi VsyncMode GetVsyncMode() const { return m_vsync_mode; }
|
||||
|
||||
/// Changes the alignment for this display (screen positioning).
|
||||
__fi Alignment GetDisplayAlignment() const { return m_display_alignment; }
|
||||
|
@ -98,7 +99,7 @@ public:
|
|||
virtual bool HasSurface() const = 0;
|
||||
|
||||
/// Creates the rendering/GPU device. This should be called on the thread which owns the window.
|
||||
virtual bool CreateDevice(const WindowInfo& wi) = 0;
|
||||
virtual bool CreateDevice(const WindowInfo& wi, VsyncMode vsync) = 0;
|
||||
|
||||
/// Fully initializes the rendering device. This should be called on the GS thread.
|
||||
virtual bool SetupDevice() = 0;
|
||||
|
|
|
@ -298,16 +298,14 @@ void SysMtgsThread::MainLoop()
|
|||
|
||||
while (true)
|
||||
{
|
||||
|
||||
// Performance note: Both of these perform cancellation tests, but pthread_testcancel
|
||||
// is very optimized (only 1 instruction test in most cases), so no point in trying
|
||||
// to avoid it.
|
||||
|
||||
#ifdef PCSX2_CORE
|
||||
if (m_run_idle_flag.load(std::memory_order_acquire) && VMManager::GetState() != VMState::Running)
|
||||
{
|
||||
if (!m_sem_event.CheckForWork())
|
||||
{
|
||||
GSPresentCurrentFrame();
|
||||
GSThrottlePresentation();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -27,11 +27,16 @@ void PADclose();
|
|||
u8 PADstartPoll(int port, int slot);
|
||||
u8 PADpoll(u8 value);
|
||||
bool PADcomplete();
|
||||
HostKeyEvent* PADkeyEvent();
|
||||
void PADconfigure();
|
||||
s32 PADfreeze(FreezeAction mode, freezeData* data);
|
||||
s32 PADsetSlot(u8 port, u8 slot);
|
||||
|
||||
#ifndef PCSX2_CORE
|
||||
|
||||
HostKeyEvent* PADkeyEvent();
|
||||
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
void PADWriteEvent(HostKeyEvent& evt);
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1393,7 +1393,6 @@ void VMManager::SetLimiterMode(LimiterModeType type)
|
|||
|
||||
EmuConfig.LimiterMode = type;
|
||||
gsUpdateFrequency(EmuConfig);
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
}
|
||||
|
||||
void VMManager::FrameAdvance(u32 num_frames /*= 1*/)
|
||||
|
@ -1635,7 +1634,6 @@ void VMManager::CheckForFramerateConfigChanges(const Pcsx2Config& old_config)
|
|||
gsUpdateFrequency(EmuConfig);
|
||||
UpdateVSyncRate();
|
||||
frameLimitReset();
|
||||
GetMTGS().UpdateVSyncMode();
|
||||
}
|
||||
|
||||
void VMManager::CheckForPatchConfigChanges(const Pcsx2Config& old_config)
|
||||
|
|
|
@ -129,7 +129,8 @@ bool Host::AcquireHostDisplay(RenderAPI api, bool clear_state_on_fail)
|
|||
if (!g_host_display)
|
||||
return false;
|
||||
|
||||
if (!g_host_display->CreateDevice(g_gs_window_info) || !g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||
if (!g_host_display->CreateDevice(g_gs_window_info, Host::GetEffectiveVSyncMode()) ||
|
||||
!g_host_display->SetupDevice() || !ImGuiManager::Initialize())
|
||||
{
|
||||
g_host_display.reset();
|
||||
return false;
|
||||
|
@ -151,16 +152,6 @@ void Host::ReleaseHostDisplay(bool clear_state_on_fail)
|
|||
sApp.CloseGsPanel();
|
||||
}
|
||||
|
||||
VsyncMode Host::GetEffectiveVSyncMode()
|
||||
{
|
||||
// Force vsync off when not running at 100% speed.
|
||||
if (EmuConfig.GS.LimitScalar != 1.0f)
|
||||
return VsyncMode::Off;
|
||||
|
||||
// Otherwise use the config setting.
|
||||
return EmuConfig.GS.VsyncEnable;
|
||||
}
|
||||
|
||||
bool Host::BeginPresentFrame(bool frame_skip)
|
||||
{
|
||||
CheckForGSWindowResize();
|
||||
|
|
Loading…
Reference in New Issue