mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 19:55:46 -04:00
HostDisplay: Manually throttle fullscreen UI presentation
Fixes flickering screen in fullscreen with Vulkan.
This commit is contained in:
@ -194,10 +194,10 @@ bool D3D11HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
|
||||
void D3D11HostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
m_vsync = enabled;
|
||||
m_vsync_enabled = enabled;
|
||||
}
|
||||
|
||||
bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi, bool vsync)
|
||||
{
|
||||
UINT create_flags = 0;
|
||||
if (g_settings.gpu_use_debug_device)
|
||||
@ -306,6 +306,7 @@ bool D3D11HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
}
|
||||
|
||||
m_window_info = wi;
|
||||
m_vsync_enabled = vsync;
|
||||
|
||||
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
||||
{
|
||||
@ -675,7 +676,7 @@ bool D3D11HostDisplay::Render(bool skip_present)
|
||||
// This blows our our GPU usage number considerably, so read the timestamp before the final blit
|
||||
// in this configuration. It does reduce accuracy a little, but better than seeing 100% all of
|
||||
// the time, when it's more like a couple of percent.
|
||||
if (m_vsync && m_gpu_timing_enabled)
|
||||
if (m_vsync_enabled && m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
RenderDisplay();
|
||||
@ -685,13 +686,13 @@ bool D3D11HostDisplay::Render(bool skip_present)
|
||||
|
||||
RenderSoftwareCursor();
|
||||
|
||||
if (!m_vsync && m_gpu_timing_enabled)
|
||||
if (!m_vsync_enabled && m_gpu_timing_enabled)
|
||||
PopTimestampQuery();
|
||||
|
||||
if (!m_vsync && m_using_allow_tearing)
|
||||
if (!m_vsync_enabled && m_using_allow_tearing)
|
||||
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
else
|
||||
m_swap_chain->Present(BoolToUInt32(m_vsync), 0);
|
||||
m_swap_chain->Present(BoolToUInt32(m_vsync_enabled), 0);
|
||||
|
||||
if (m_gpu_timing_enabled)
|
||||
KickTimestampQuery();
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, bool vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
@ -141,7 +141,6 @@ protected:
|
||||
bool m_allow_tearing_supported = false;
|
||||
bool m_using_flip_model_swap_chain = true;
|
||||
bool m_using_allow_tearing = false;
|
||||
bool m_vsync = true;
|
||||
|
||||
FrontendCommon::PostProcessingChain m_post_processing_chain;
|
||||
D3D11::Texture m_post_processing_input_texture;
|
||||
|
@ -139,10 +139,10 @@ bool D3D12HostDisplay::GetHostRefreshRate(float* refresh_rate)
|
||||
|
||||
void D3D12HostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
m_vsync = enabled;
|
||||
m_vsync_enabled = enabled;
|
||||
}
|
||||
|
||||
bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi, bool vsync)
|
||||
{
|
||||
ComPtr<IDXGIFactory> temp_dxgi_factory;
|
||||
HRESULT hr = CreateDXGIFactory(IID_PPV_ARGS(temp_dxgi_factory.GetAddressOf()));
|
||||
@ -198,6 +198,7 @@ bool D3D12HostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
}
|
||||
|
||||
m_window_info = wi;
|
||||
m_vsync_enabled = vsync;
|
||||
|
||||
if (m_window_info.type != WindowInfo::Type::Surfaceless && !CreateSwapChain(nullptr))
|
||||
{
|
||||
@ -599,10 +600,10 @@ bool D3D12HostDisplay::Render(bool skip_present)
|
||||
swap_chain_buf.TransitionToState(D3D12_RESOURCE_STATE_PRESENT);
|
||||
g_d3d12_context->ExecuteCommandList(false);
|
||||
|
||||
if (!m_vsync && m_using_allow_tearing)
|
||||
if (!m_vsync_enabled && m_using_allow_tearing)
|
||||
m_swap_chain->Present(0, DXGI_PRESENT_ALLOW_TEARING);
|
||||
else
|
||||
m_swap_chain->Present(BoolToUInt32(m_vsync), 0);
|
||||
m_swap_chain->Present(BoolToUInt32(m_vsync_enabled), 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public:
|
||||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, bool vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
@ -137,5 +137,4 @@ protected:
|
||||
|
||||
bool m_allow_tearing_supported = false;
|
||||
bool m_using_allow_tearing = false;
|
||||
bool m_vsync = true;
|
||||
};
|
||||
|
@ -638,7 +638,6 @@ void FullscreenUI::OnSystemDestroyed()
|
||||
if (!IsInitialized())
|
||||
return;
|
||||
|
||||
g_host_display->SetVSync(true);
|
||||
s_pause_menu_was_open = false;
|
||||
SwitchToLanding();
|
||||
}
|
||||
@ -668,15 +667,7 @@ void FullscreenUI::PauseForMenuOpen()
|
||||
{
|
||||
s_was_paused_on_quick_menu_open = (System::GetState() == System::State::Paused);
|
||||
if (g_settings.pause_on_menu && !s_was_paused_on_quick_menu_open)
|
||||
{
|
||||
Host::RunOnCPUThread([]() {
|
||||
System::PauseSystem(true);
|
||||
|
||||
// force vsync on when pausing
|
||||
if (g_host_display)
|
||||
g_host_display->SetVSync(true);
|
||||
});
|
||||
}
|
||||
Host::RunOnCPUThread([]() { System::PauseSystem(true); });
|
||||
|
||||
s_pause_menu_was_open = true;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ bool OpenGLHostDisplay::SupportsTextureFormat(GPUTexture::Format format) const
|
||||
|
||||
void OpenGLHostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
if (m_gl_context->GetWindowInfo().type == WindowInfo::Type::Surfaceless)
|
||||
if (m_vsync_enabled == enabled || m_gl_context->GetWindowInfo().type == WindowInfo::Type::Surfaceless)
|
||||
return;
|
||||
|
||||
// Window framebuffer has to be bound to call SetSwapInterval.
|
||||
@ -218,6 +218,7 @@ void OpenGLHostDisplay::SetVSync(bool enabled)
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
m_gl_context->SetSwapInterval(enabled ? 1 : 0);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo);
|
||||
m_vsync_enabled = enabled;
|
||||
}
|
||||
|
||||
const char* OpenGLHostDisplay::GetGLSLVersionString() const
|
||||
@ -281,7 +282,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, bool vsync)
|
||||
{
|
||||
m_gl_context = GL::Context::Create(wi);
|
||||
if (!m_gl_context)
|
||||
@ -292,6 +293,7 @@ bool OpenGLHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
}
|
||||
|
||||
m_window_info = m_gl_context->GetWindowInfo();
|
||||
SetVSync(vsync);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -328,9 +330,6 @@ bool OpenGLHostDisplay::SetupDevice()
|
||||
if (!CreateResources())
|
||||
return false;
|
||||
|
||||
// Start with vsync on.
|
||||
SetVSync(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, bool vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
@ -95,6 +95,7 @@ bool VulkanHostDisplay::ChangeWindow(const WindowInfo& new_wi)
|
||||
}
|
||||
|
||||
m_window_info = m_swap_chain->GetWindowInfo();
|
||||
m_vsync_enabled = m_swap_chain->IsVSyncEnabled();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -106,6 +107,7 @@ void VulkanHostDisplay::ResizeWindow(s32 new_window_width, s32 new_window_height
|
||||
Panic("Failed to resize swap chain");
|
||||
|
||||
m_window_info = m_swap_chain->GetWindowInfo();
|
||||
m_vsync_enabled = m_swap_chain->IsVSyncEnabled();
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::SupportsFullscreen() const
|
||||
@ -206,19 +208,31 @@ bool VulkanHostDisplay::SupportsTextureFormat(GPUTexture::Format format) const
|
||||
|
||||
void VulkanHostDisplay::SetVSync(bool enabled)
|
||||
{
|
||||
if (!m_swap_chain)
|
||||
if (!m_swap_chain || m_swap_chain->IsVSyncEnabled() == enabled)
|
||||
return;
|
||||
|
||||
// This swap chain should not be used by the current buffer, thus safe to destroy.
|
||||
g_vulkan_context->WaitForGPUIdle();
|
||||
m_swap_chain->SetVSync(enabled);
|
||||
m_vsync_enabled = m_swap_chain->IsVSyncEnabled();
|
||||
}
|
||||
|
||||
bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi, bool vsync)
|
||||
{
|
||||
WindowInfo local_wi(wi);
|
||||
if (!Vulkan::Context::Create(g_settings.gpu_adapter, &local_wi, &m_swap_chain, g_settings.gpu_threaded_presentation,
|
||||
g_settings.gpu_use_debug_device, false))
|
||||
bool result =
|
||||
Vulkan::Context::Create(g_settings.gpu_adapter, &local_wi, &m_swap_chain, g_settings.gpu_threaded_presentation,
|
||||
g_settings.gpu_use_debug_device, g_settings.gpu_use_debug_device, vsync);
|
||||
|
||||
// If validation layers were enabled, try without.
|
||||
if (!result && g_settings.gpu_use_debug_device)
|
||||
{
|
||||
Log_WarningPrintf("Failed to create Vulkan context with validation layers, trying without.");
|
||||
result = Vulkan::Context::Create(g_settings.gpu_adapter, &local_wi, &m_swap_chain,
|
||||
g_settings.gpu_threaded_presentation, false, false, vsync);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
Log_ErrorPrintf("Failed to create Vulkan context");
|
||||
m_window_info = {};
|
||||
@ -231,6 +245,7 @@ bool VulkanHostDisplay::CreateDevice(const WindowInfo& wi)
|
||||
g_vulkan_context->GetDeviceDriverProperties().driverID == VK_DRIVER_ID_QUALCOMM_PROPRIETARY);
|
||||
|
||||
m_window_info = m_swap_chain ? m_swap_chain->GetWindowInfo() : local_wi;
|
||||
m_vsync_enabled = m_swap_chain ? m_swap_chain->IsVSyncEnabled() : false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
bool HasDevice() const override;
|
||||
bool HasSurface() const override;
|
||||
|
||||
bool CreateDevice(const WindowInfo& wi) override;
|
||||
bool CreateDevice(const WindowInfo& wi, bool vsync) override;
|
||||
bool SetupDevice() override;
|
||||
|
||||
bool MakeCurrent() override;
|
||||
|
Reference in New Issue
Block a user