mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-04 02:41:19 +00:00
8ab5fd9b40
Measure time at the computation end but before sleep. This allows to adjust sleep interval for the next frame in case sleep is not precise due to syscall overhead or too low timer resolution. Remove old frame limiting mechanism.
57 lines
1.9 KiB
C++
57 lines
1.9 KiB
C++
#ifndef OPENMW_COMPONENTS_MISC_FRAMERATELIMITER_H
|
|
#define OPENMW_COMPONENTS_MISC_FRAMERATELIMITER_H
|
|
|
|
#include <chrono>
|
|
#include <thread>
|
|
|
|
namespace Misc
|
|
{
|
|
class FrameRateLimiter
|
|
{
|
|
public:
|
|
template <class Rep, class Ratio>
|
|
explicit FrameRateLimiter(std::chrono::duration<Rep, Ratio> maxFrameDuration,
|
|
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now())
|
|
: mMaxFrameDuration(std::chrono::duration_cast<std::chrono::steady_clock::duration>(maxFrameDuration))
|
|
, mLastMeasurement(now)
|
|
{}
|
|
|
|
std::chrono::steady_clock::duration getLastFrameDuration() const
|
|
{
|
|
return mLastFrameDuration;
|
|
}
|
|
|
|
void limit(std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now())
|
|
{
|
|
const auto passed = now - mLastMeasurement;
|
|
const auto left = mMaxFrameDuration - passed;
|
|
if (left > left.zero())
|
|
{
|
|
std::this_thread::sleep_for(left);
|
|
mLastMeasurement = now + left;
|
|
mLastFrameDuration = mMaxFrameDuration;
|
|
}
|
|
else
|
|
{
|
|
mLastMeasurement = now;
|
|
mLastFrameDuration = passed;
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::chrono::steady_clock::duration mMaxFrameDuration;
|
|
std::chrono::steady_clock::time_point mLastMeasurement;
|
|
std::chrono::steady_clock::duration mLastFrameDuration;
|
|
};
|
|
|
|
inline Misc::FrameRateLimiter makeFrameRateLimiter(float frameRateLimit)
|
|
{
|
|
if (frameRateLimit > 0.0f)
|
|
return Misc::FrameRateLimiter(std::chrono::duration<float>(1.0f / frameRateLimit));
|
|
else
|
|
return Misc::FrameRateLimiter(std::chrono::steady_clock::duration::zero());
|
|
}
|
|
}
|
|
|
|
#endif
|