1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-14 10:12:59 +02:00
vcmi/client/gui/FramerateManager.cpp

64 lines
1.9 KiB
C++
Raw Normal View History

/*
2024-03-29 07:48:52 +02:00
* FramerateManager.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "FramerateManager.h"
#include "../../lib/CConfigHandler.h"
#include <SDL_video.h>
FramerateManager::FramerateManager(int targetFrameRate)
: targetFrameTime(Duration(boost::chrono::seconds(1)) / targetFrameRate)
, lastFrameIndex(0)
, lastFrameTimes({})
, lastTimePoint(Clock::now())
, vsyncEnabled(settings["video"]["vsync"].Bool())
{
boost::range::fill(lastFrameTimes, targetFrameTime);
}
void FramerateManager::framerateDelay()
{
Duration timeSpentBusy = Clock::now() - lastTimePoint;
if(!vsyncEnabled && timeSpentBusy < targetFrameTime)
{
// if FPS is higher than it should be, then wait some time
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)
TimePoint currentTicks = Clock::now();
Duration timeElapsed = currentTicks - lastTimePoint;
if(timeElapsed > boost::chrono::milliseconds(100))
timeElapsed = boost::chrono::milliseconds(100);
lastTimePoint = currentTicks;
lastFrameIndex = (lastFrameIndex + 1) % lastFrameTimes.size();
lastFrameTimes[lastFrameIndex] = timeElapsed;
}
ui32 FramerateManager::getElapsedMilliseconds() const
{
return lastFrameTimes[lastFrameIndex] / boost::chrono::milliseconds(1);
}
ui32 FramerateManager::getFramerate() const
{
Duration accumulatedTime = std::accumulate(lastFrameTimes.begin(), lastFrameTimes.end(), Duration());
auto actualFrameTime = accumulatedTime / lastFrameTimes.size();
if(actualFrameTime == actualFrameTime.zero())
return 0;
return std::round(boost::chrono::duration<double>(1) / actualFrameTime);
};