mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Fix stuttering animations when using high frame rate limit or vsync
This commit is contained in:
@@ -12,27 +12,36 @@
|
||||
#include "FramerateManager.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include <SDL_video.h>
|
||||
|
||||
FramerateManager::FramerateManager(int targetFrameRate)
|
||||
: targetFrameTime(Duration(boost::chrono::seconds(1)) / targetFrameRate)
|
||||
, lastFrameIndex(0)
|
||||
: lastFrameIndex(0)
|
||||
, lastFrameTimes({})
|
||||
, lastTimePoint(Clock::now())
|
||||
, vsyncEnabled(settings["video"]["vsync"].Bool())
|
||||
{
|
||||
if(vsyncEnabled)
|
||||
{
|
||||
static int display_in_use = 0;
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetCurrentDisplayMode(display_in_use, &mode);
|
||||
int displayRefreshRate = mode.refresh_rate;
|
||||
logGlobal->info("Display refresh rate is %d", displayRefreshRate);
|
||||
targetFrameTime = Duration(boost::chrono::seconds(1)) / displayRefreshRate;
|
||||
} else
|
||||
{
|
||||
targetFrameTime = Duration(boost::chrono::seconds(1)) / targetFrameRate;
|
||||
}
|
||||
boost::range::fill(lastFrameTimes, targetFrameTime);
|
||||
}
|
||||
|
||||
void FramerateManager::framerateDelay()
|
||||
{
|
||||
if(!vsyncEnabled)
|
||||
{
|
||||
Duration timeSpentBusy = Clock::now() - lastTimePoint;
|
||||
|
||||
// FPS is higher than it should be, then wait some time
|
||||
if(timeSpentBusy < targetFrameTime)
|
||||
boost::this_thread::sleep_for(targetFrameTime - timeSpentBusy);
|
||||
}
|
||||
|
||||
// compute actual timeElapsed taking into account actual sleep interval
|
||||
// limit it to 100 ms to avoid breaking animation in case of huge lag (e.g. triggered breakpoint)
|
||||
|
Reference in New Issue
Block a user