diff --git a/RenderSystems/Vulkan/include/Windowing/Android/OgreVulkanAndroidWindow.h b/RenderSystems/Vulkan/include/Windowing/Android/OgreVulkanAndroidWindow.h index e7670b1633d..c4dac6f8b6f 100644 --- a/RenderSystems/Vulkan/include/Windowing/Android/OgreVulkanAndroidWindow.h +++ b/RenderSystems/Vulkan/include/Windowing/Android/OgreVulkanAndroidWindow.h @@ -67,6 +67,43 @@ namespace Ogre class _OgreVulkanExport VulkanAndroidWindow final : public VulkanWindowSwapChainBased { + public: + enum FramePacingSwappyModes + { + /// Try to honour the vSyncInterval set via Window::setVSync. + /// Pipelining is always on. This is the same behavior as Desktop APIs + /// (e.g. D3D11, Vulkan & GL on Windows and Linux). + PipelineForcedOn, + + /// Autocalculate vSyncInterval (see Window::setVSync). + /// The autocalculated vSyncInterval should be in the range [vSyncInterval; inf) where + /// vSyncInterval is the value passed to Window::setVSync. + /// + /// While this sounds convenient, beware that Swappy will often downgrade vSyncInterval + /// until it finds something that can be met & sustained. + /// That means if your game runs between 40fps and 60fps on a 60hz screen, after some time + /// swappy will downgrade vSyncInterval to 2 so that the game render at perfect 30fps. + /// + /// This may result in a better experience considering framerates jump a lot due to + /// thermal throttling on phones. But it may also cause undesired or unexplainable + /// "locked to 30fps for no aparent reason for a considerable time". + /// + /// Pipelining is always on. + AutoVSyncInterval_PipelineForcedOn, + + /// Autocalculate vSyncInterval (see Window::setVSync). + /// See AutoSwapInterval_PipelineForcedOn documentation. + /// + /// Use this mode when you know you have extremely fast render times (e.g. CPU + GPU time is + /// below half the monitor's refresh time, e.g. it takes <= 8ms to render in a 60hz screen) + /// which means Swappy will eventually disable pipelining. + /// + /// A disabled pipeline minimizes latency because the whole thing presented is ASAP by the + /// time the next VBLANK interval arrives. + AutoVSyncInterval_AutoPipeline, + }; + + private: ANativeWindow *mNativeWindow; #ifdef OGRE_VULKAN_USE_SWAPPY AndroidJniProvider *mJniProvider; @@ -87,6 +124,8 @@ namespace Ogre // consider Swappy busted on this device and disable it. int64 mFirstRecreateTimestamp; // In milliseconds. uint8 mRecreateCount; + + static FramePacingSwappyModes msFramePacingSwappyMode; #endif bool mVisible; @@ -95,6 +134,8 @@ namespace Ogre #ifdef OGRE_VULKAN_USE_SWAPPY void initSwappy(); + + static void setFramePacingSwappyAutoMode(); #endif void createSwapchain() override; @@ -121,41 +162,6 @@ namespace Ogre void setHidden( bool hidden ) override; bool isHidden() const override; - enum FramePacingSwappyModes - { - /// Try to honour the vSyncInterval set via Window::setVSync. - /// Pipelining is always on. This is the same behavior as Desktop APIs - /// (e.g. D3D11, Vulkan & GL on Windows and Linux). - PipelineForcedOn, - - /// Autocalculate vSyncInterval (see Window::setVSync). - /// The autocalculated vSyncInterval should be in the range [vSyncInterval; inf) where - /// vSyncInterval is the value passed to Window::setVSync. - /// - /// While this sounds convenient, beware that Swappy will often downgrade vSyncInterval - /// until it finds something that can be met & sustained. - /// That means if your game runs between 40fps and 60fps on a 60hz screen, after some time - /// swappy will downgrade vSyncInterval to 2 so that the game render at perfect 30fps. - /// - /// This may result in a better experience considering framerates jump a lot due to - /// thermal throttling on phones. But it may also cause undesired or unexplainable - /// "locked to 30fps for no aparent reason for a considerable time". - /// - /// Pipelining is always on. - AutoVSyncInterval_PipelineForcedOn, - - /// Autocalculate vSyncInterval (see Window::setVSync). - /// See AutoSwapInterval_PipelineForcedOn documentation. - /// - /// Use this mode when you know you have extremely fast render times (e.g. CPU + GPU time is - /// below half the monitor's refresh time, e.g. it takes <= 8ms to render in a 60hz screen) - /// which means Swappy will eventually disable pipelining. - /// - /// A disabled pipeline minimizes latency because the whole thing presented is ASAP by the - /// time the next VBLANK interval arrives. - AutoVSyncInterval_AutoPipeline, - }; - /** Sets Swappy auto swap interval and auto pipeline modes. See https://developer.android.com/games/sdk/frame-pacing @remarks diff --git a/RenderSystems/Vulkan/src/Windowing/Android/OgreVulkanAndroidWindow.cpp b/RenderSystems/Vulkan/src/Windowing/Android/OgreVulkanAndroidWindow.cpp index 02fc03d3b4f..1a4ab03326a 100644 --- a/RenderSystems/Vulkan/src/Windowing/Android/OgreVulkanAndroidWindow.cpp +++ b/RenderSystems/Vulkan/src/Windowing/Android/OgreVulkanAndroidWindow.cpp @@ -52,6 +52,12 @@ THE SOFTWARE. namespace Ogre { +#ifdef OGRE_VULKAN_USE_SWAPPY + // Same default as Swappy. + VulkanAndroidWindow::FramePacingSwappyModes VulkanAndroidWindow::msFramePacingSwappyMode = + VulkanAndroidWindow::AutoVSyncInterval_AutoPipeline; +#endif + VulkanAndroidWindow::VulkanAndroidWindow( const String &title, uint32 width, uint32 height, bool fullscreenMode ) : VulkanWindowSwapChainBased( title, width, height, fullscreenMode ), @@ -290,7 +296,15 @@ namespace Ogre void VulkanAndroidWindow::setFramePacingSwappyAutoMode( FramePacingSwappyModes mode ) { #ifdef OGRE_VULKAN_USE_SWAPPY - switch( mode ) + msFramePacingSwappyMode = mode; + setFramePacingSwappyAutoMode(); +#endif + } + //------------------------------------------------------------------------- +#ifdef OGRE_VULKAN_USE_SWAPPY + void VulkanAndroidWindow::setFramePacingSwappyAutoMode() + { + switch( msFramePacingSwappyMode ) { case AutoVSyncInterval_AutoPipeline: SwappyVk_setAutoSwapInterval( true ); @@ -309,8 +323,8 @@ namespace Ogre // SwappyVk_setAutoPipelineMode( true ); // Is ignored by Swappy as it makes no sense. } -#endif } +#endif //------------------------------------------------------------------------- #ifdef OGRE_VULKAN_USE_SWAPPY void VulkanAndroidWindow::_notifySwappyToggled() @@ -491,6 +505,8 @@ namespace Ogre mFrequencyDenominator = 0u; } SwappyVk_setSwapIntervalNS( mDevice->mDevice, mSwapchain, mRefreshDuration * mVSyncInterval ); + + setFramePacingSwappyAutoMode(); } #endif //-------------------------------------------------------------------------