Support for refresh rate and sync interval (#2989)

* Add support for querying the refresh rate and sync interval
This commit is contained in:
moudgils
2021-08-12 12:07:46 -07:00
committed by GitHub
parent 589a05062b
commit c2b8542bbd
18 changed files with 128 additions and 30 deletions
@@ -10,6 +10,17 @@
#include <AzCore/Console/IConsole.h>
void OnVsyncIntervalChanged(uint32_t const& interval)
{
AzFramework::WindowNotificationBus::Broadcast(
&AzFramework::WindowNotificationBus::Events::OnVsyncIntervalChanged, AZ::GetClamp(interval, 0u, 4u));
}
// NOTE: On change, broadcasts the new requested vsync interval to all windows.
// The value of the vsync interval is constrained between 0 and 4
// Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion)
AZ_CVAR(uint32_t, vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval");
namespace AzFramework
{
//////////////////////////////////////////////////////////////////////////
@@ -122,6 +133,16 @@ namespace AzFramework
return m_pimpl->GetDpiScaleFactor();
}
uint32_t NativeWindow::GetDisplayRefreshRate() const
{
return m_pimpl->GetDisplayRefreshRate();
}
uint32_t NativeWindow::GetSyncInterval() const
{
return vsync_interval;
}
/*static*/ bool NativeWindow::GetFullScreenStateOfDefaultWindow()
{
NativeWindowHandle defaultWindowHandle = nullptr;
@@ -240,4 +261,10 @@ namespace AzFramework
return 1.0f;
}
uint32_t NativeWindow::Implementation::GetDisplayRefreshRate() const
{
// Default to 60
return 60;
}
} // namespace AzFramework
@@ -130,6 +130,8 @@ namespace AzFramework
bool CanToggleFullScreenState() const override;
void ToggleFullScreenState() override;
float GetDpiScaleFactor() const override;
uint32_t GetSyncInterval() const override;
uint32_t GetDisplayRefreshRate() const override;
//! Get the full screen state of the default window.
//! \return True if the default window is currently in full screen, false otherwise.
@@ -172,6 +174,7 @@ namespace AzFramework
virtual void SetFullScreenState(bool fullScreenState);
virtual bool CanToggleFullScreenState() const;
virtual float GetDpiScaleFactor() const;
virtual uint32_t GetDisplayRefreshRate() const;
protected:
uint32_t m_width = 0;
@@ -74,6 +74,12 @@ namespace AzFramework
//! to a "standard" value of 96, the default for Windows in a DPI unaware setting. This can
//! be used to scale user interface elements to ensure legibility on high density displays.
virtual float GetDpiScaleFactor() const = 0;
//! Returns the sync interval which tells the drivers the number of v-blanks to synchronize with
virtual uint32_t GetSyncInterval() const = 0;
//! Returns the refresh rate of the main display
virtual uint32_t GetDisplayRefreshRate() const = 0;
};
using WindowRequestBus = AZ::EBus<WindowRequests>;
@@ -101,6 +107,9 @@ namespace AzFramework
//! This is called when vsync interval is changed.
virtual void OnVsyncIntervalChanged(uint32_t interval) { AZ_UNUSED(interval); };
//! This is called if the main display's refresh rate changes
virtual void OnRefreshRateChanged([[maybe_unused]] uint32_t refreshRate) {}
};
using WindowNotificationBus = AZ::EBus<WindowNotifications>;
@@ -25,7 +25,7 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
uint32_t GetDisplayRefreshRate() const override;
private:
ANativeWindow* m_nativeWindow = nullptr;
};
@@ -55,4 +55,9 @@ namespace AzFramework
return reinterpret_cast<NativeWindowHandle>(m_nativeWindow);
}
uint32_t NativeWindowImpl_Android::GetDisplayRefreshRate() const
{
// Using 60 for now until proper support is added
return 60;
}
} // namespace AzFramework
@@ -23,6 +23,7 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
uint32_t GetDisplayRefreshRate() const override;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -44,4 +45,9 @@ namespace AzFramework
return nullptr;
}
uint32_t NativeWindowImpl_Linux::GetDisplayRefreshRate() const
{
//Using 60 for now until proper support is added
return 60;
}
} // namespace AzFramework
@@ -34,12 +34,14 @@ namespace AzFramework
bool GetFullScreenState() const override;
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
uint32_t GetMainDisplayRefreshRate() const override;
private:
static NSWindowStyleMask ConvertToNSWindowStyleMask(const WindowStyleMasks& styleMasks);
NSWindow* m_nativeWindow;
NSString* m_windowTitle;
uint32_t m_mainDisplayRefreshRate = 0;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -76,6 +78,17 @@ namespace AzFramework
// Make the window active
[m_nativeWindow makeKeyAndOrderFront:nil];
m_nativeWindow.title = m_windowTitle;
CGDirectDisplayID display = CGMainDisplayID();
CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
m_mainDisplayRefreshRate = CGDisplayModeGetRefreshRate(currentMode);
// Assume 60hz if 0 is returned.
// This can happen on OSX. In future we can hopefully use maximumFramesPerSecond which wont have this issue
if (m_mainDisplayRefreshRate == 0)
{
m_mainDisplayRefreshRate = 60;
}
}
NativeWindowHandle NativeWindowImpl_Darwin::GetWindowHandle() const
@@ -128,4 +141,9 @@ namespace AzFramework
const NSWindowStyleMask defaultMask = NSWindowStyleMaskResizable | NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
return nativeMask ? nativeMask : defaultMask;
}
uint32_t NativeWindowImpl_Darwin::GetMainDisplayRefreshRate() const
{
return m_mainDisplayRefreshRate;
}
} // namespace AzFramework
@@ -37,6 +37,7 @@ namespace AzFramework
void SetFullScreenState(bool fullScreenState) override;
bool CanToggleFullScreenState() const override { return true; }
float GetDpiScaleFactor() const override;
uint32_t GetDisplayRefreshRate() const override;
private:
static DWORD ConvertToWin32WindowStyleMask(const WindowStyleMasks& styleMasks);
@@ -56,6 +57,7 @@ namespace AzFramework
using GetDpiForWindowType = UINT(HWND hwnd);
GetDpiForWindowType* m_getDpiFunction = nullptr;
uint32_t m_mainDisplayRefreshRate = 0;
};
const wchar_t* NativeWindowImpl_Win32::s_defaultClassName = L"O3DEWin32Class";
@@ -144,6 +146,10 @@ namespace AzFramework
{
SetWindowLongPtr(m_win32Handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
}
DEVMODE DisplayConfig;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig);
m_mainDisplayRefreshRate = DisplayConfig.dmDisplayFrequency;
}
void NativeWindowImpl_Win32::Activate()
@@ -263,6 +269,15 @@ namespace AzFramework
WindowNotificationBus::Event(nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnDpiScaleFactorChanged, newScaleFactor);
break;
}
case WM_WINDOWPOSCHANGED:
{
DEVMODE DisplayConfig;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &DisplayConfig);
uint32_t refreshRate = DisplayConfig.dmDisplayFrequency;
WindowNotificationBus::Event(
nativeWindowImpl->GetWindowHandle(), &WindowNotificationBus::Events::OnRefreshRateChanged, refreshRate);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
@@ -367,6 +382,11 @@ namespace AzFramework
return aznumeric_cast<float>(dotsPerInch) / aznumeric_cast<float>(defaultDotsPerInch);
}
uint32_t NativeWindowImpl_Win32::GetDisplayRefreshRate() const
{
return m_mainDisplayRefreshRate;
}
void NativeWindowImpl_Win32::EnterBorderlessWindowFullScreen()
{
if (m_isInBorderlessWindowFullScreenState)
@@ -27,9 +27,11 @@ namespace AzFramework
const WindowGeometry& geometry,
const WindowStyleMasks& styleMasks) override;
NativeWindowHandle GetWindowHandle() const override;
uint32_t GetMainDisplayRefreshRate() const override;
private:
UIWindow* m_nativeWindow;
uint32_t m_mainDisplayRefreshRate = 0;
};
NativeWindow::Implementation* NativeWindow::Implementation::Create()
@@ -56,6 +58,7 @@ namespace AzFramework
m_width = geometry.m_width;
m_height = geometry.m_height;
m_mainDisplayRefreshRate = [[UIScreen mainScreen] maximumFramesPerSecond];
}
NativeWindowHandle NativeWindowImpl_Ios::GetWindowHandle() const
@@ -63,5 +66,9 @@ namespace AzFramework
return m_nativeWindow;
}
uint32_t NativeWindowImpl_Ios::GetMainDisplayRefreshRate() const
{
return m_mainDisplayRefreshRate;
}
} // namespace AzFramework