Prepare for deferred waits

This commit is contained in:
Henrik Rydgård 2023-12-18 13:44:32 +01:00
parent 7f075dc9fe
commit 97e0f6dc94
4 changed files with 40 additions and 11 deletions

View File

@ -32,6 +32,17 @@
FrameTiming g_frameTiming;
void WaitUntil(double now, double timestamp) {
#ifdef _WIN32
while (time_now_d() < timestamp) {
sleep_ms(1); // Sleep for 1ms on this thread
}
#else
const double left = timestamp - now;
usleep((long)(left * 1000000));
#endif
}
inline Draw::PresentMode GetBestImmediateMode(Draw::PresentMode supportedModes) {
if (supportedModes & Draw::PresentMode::MAILBOX) {
return Draw::PresentMode::MAILBOX;
@ -50,6 +61,22 @@ void FrameTiming::Reset(Draw::DrawContext *draw) {
}
}
void FrameTiming::DeferWaitUntil(double until, double *curTimePtr) {
_dbg_assert_(until > 0.0);
waitUntil_ = until;
curTimePtr_ = curTimePtr;
}
void FrameTiming::PostSubmit() {
if (waitUntil_ != 0.0) {
WaitUntil(time_now_d(), waitUntil_);
if (curTimePtr_) {
*curTimePtr_ = waitUntil_;
}
waitUntil_ = 0.0;
}
}
Draw::PresentMode ComputePresentMode(Draw::DrawContext *draw, int *interval) {
Draw::PresentMode mode = Draw::PresentMode::FIFO;

View File

@ -8,14 +8,23 @@ namespace Draw {
class DrawContext;
}
struct FrameTiming {
class FrameTiming {
public:
void DeferWaitUntil(double until, double *curTimePtr);
void PostSubmit();
void Reset(Draw::DrawContext *draw);
// Some backends won't allow changing this willy nilly.
Draw::PresentMode presentMode;
int presentInterval;
void Reset(Draw::DrawContext *draw);
private:
double waitUntil_;
double *curTimePtr_;
};
extern FrameTiming g_frameTiming;
Draw::PresentMode ComputePresentMode(Draw::DrawContext *draw, int *interval);
void WaitUntil(double now, double timestamp);

View File

@ -440,15 +440,7 @@ static void DoFrameTiming(bool throttle, bool *skipFrame, float scaledTimestep,
// Wait until we've caught up.
// TODO: This is the wait we actually move to after the frame.
// But watch out, curFrameTime below must be updated correctly - I think.
while (time_now_d() < nextFrameTime) {
#ifdef _WIN32
sleep_ms(1); // Sleep for 1ms on this thread
#else
const double left = nextFrameTime - curFrameTime;
usleep((long)(left * 1000000));
#endif
}
WaitUntil(curFrameTime, nextFrameTime);
}
curFrameTime = time_now_d();
}

View File

@ -1117,6 +1117,7 @@ void NativeFrame(GraphicsContext *graphicsContext) {
// This, between EndFrame and Present, is where we should actually wait to do present time management.
// There might not be a meaningful distinction here for all backends..
g_frameTiming.PostSubmit();
if (renderCounter < 10 && ++renderCounter == 10) {
// We're rendering fine, clear out failure info.