Skip to content

Commit

Permalink
Fix setFramePacingSwappyAutoMode not always being honoured
Browse files Browse the repository at this point in the history
  • Loading branch information
darksylinc committed Apr 15, 2024
1 parent f26a087 commit a5e8d66
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -95,6 +134,8 @@ namespace Ogre

#ifdef OGRE_VULKAN_USE_SWAPPY
void initSwappy();

static void setFramePacingSwappyAutoMode();
#endif

void createSwapchain() override;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ),
Expand Down Expand Up @@ -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 );
Expand All @@ -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()
Expand Down Expand Up @@ -491,6 +505,8 @@ namespace Ogre
mFrequencyDenominator = 0u;
}
SwappyVk_setSwapIntervalNS( mDevice->mDevice, mSwapchain, mRefreshDuration * mVSyncInterval );

setFramePacingSwappyAutoMode();
}
#endif
//-------------------------------------------------------------------------
Expand Down

0 comments on commit a5e8d66

Please sign in to comment.