117 lines
3.7 KiB
C++
117 lines
3.7 KiB
C++
#include "RenderCadenceClock.h"
|
|
|
|
#include <chrono>
|
|
#include <iostream>
|
|
|
|
namespace
|
|
{
|
|
int gFailures = 0;
|
|
|
|
void Expect(bool condition, const char* message)
|
|
{
|
|
if (condition)
|
|
return;
|
|
|
|
std::cerr << "FAIL: " << message << "\n";
|
|
++gFailures;
|
|
}
|
|
|
|
void TestEarlyPollWaitsWithoutAdvancing()
|
|
{
|
|
using Clock = RenderCadenceClock::Clock;
|
|
RenderCadenceClock cadence(16.0);
|
|
const auto start = Clock::now();
|
|
cadence.Reset(start);
|
|
|
|
const auto tick = cadence.Poll(start - std::chrono::milliseconds(1));
|
|
Expect(!tick.due, "early poll is not due");
|
|
Expect(tick.sleepFor > RenderCadenceClock::Duration::zero(), "early poll returns a sleep duration");
|
|
Expect(cadence.OverrunCount() == 0, "early poll does not count overrun");
|
|
Expect(cadence.SkippedFrameCount() == 0, "early poll does not skip frames");
|
|
}
|
|
|
|
void TestDuePollRendersWithoutSkipping()
|
|
{
|
|
using Clock = RenderCadenceClock::Clock;
|
|
RenderCadenceClock cadence(16.0);
|
|
const auto start = Clock::now();
|
|
cadence.Reset(start);
|
|
|
|
const auto tick = cadence.Poll(start);
|
|
Expect(tick.due, "exact cadence time is due");
|
|
Expect(tick.skippedFrames == 0, "exact cadence time skips no frames");
|
|
Expect(cadence.OverrunCount() == 0, "exact cadence time is not an overrun");
|
|
|
|
cadence.MarkRendered(start);
|
|
Expect(cadence.NextRenderTime() > start, "mark rendered advances next render time");
|
|
}
|
|
|
|
void TestLatePollRecordsSkippedFrames()
|
|
{
|
|
using Clock = RenderCadenceClock::Clock;
|
|
RenderCadenceClock cadence(10.0);
|
|
const auto start = Clock::now();
|
|
cadence.Reset(start);
|
|
|
|
const auto tick = cadence.Poll(start + std::chrono::milliseconds(35));
|
|
Expect(tick.due, "late poll is due");
|
|
Expect(tick.skippedFrames == 3, "late poll records skipped frame intervals");
|
|
Expect(cadence.OverrunCount() == 1, "late poll records overrun");
|
|
Expect(cadence.SkippedFrameCount() == 3, "late poll accumulates skipped frames");
|
|
}
|
|
|
|
void TestLatePollSkipsMissedIntervalsInsteadOfCatchingUp()
|
|
{
|
|
using Clock = RenderCadenceClock::Clock;
|
|
RenderCadenceClock cadence(10.0);
|
|
const auto start = Clock::now();
|
|
cadence.Reset(start);
|
|
|
|
const auto late = start + std::chrono::milliseconds(35);
|
|
const auto tick = cadence.Poll(late);
|
|
Expect(tick.due, "late skipped-interval poll is due");
|
|
Expect(tick.skippedFrames == 3, "late skipped-interval poll counts missed frames");
|
|
|
|
cadence.MarkRendered(late);
|
|
Expect(cadence.NextRenderTime() > late, "late render schedules the next tick in the future");
|
|
Expect(cadence.NextRenderTime() - late <= std::chrono::milliseconds(6), "late render does not leave catch-up frames due immediately");
|
|
|
|
const auto immediateFollowup = cadence.Poll(late);
|
|
Expect(!immediateFollowup.due, "cadence does not allow an immediate catch-up render after a late frame");
|
|
Expect(immediateFollowup.sleepFor > RenderCadenceClock::Duration::zero(), "cadence reports wait time after skipping missed intervals");
|
|
}
|
|
|
|
void TestMarkRenderedRebasesAfterLargeStall()
|
|
{
|
|
using Clock = RenderCadenceClock::Clock;
|
|
RenderCadenceClock cadence(10.0);
|
|
const auto start = Clock::now();
|
|
cadence.Reset(start);
|
|
|
|
const auto stalled = start + std::chrono::milliseconds(100);
|
|
cadence.MarkRendered(stalled);
|
|
|
|
const auto next = cadence.NextRenderTime();
|
|
Expect(next > stalled, "large stall rebases next render time after now");
|
|
Expect(next - stalled <= std::chrono::milliseconds(11), "large stall rebases to roughly one frame ahead");
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
TestEarlyPollWaitsWithoutAdvancing();
|
|
TestDuePollRendersWithoutSkipping();
|
|
TestLatePollRecordsSkippedFrames();
|
|
TestLatePollSkipsMissedIntervalsInsteadOfCatchingUp();
|
|
TestMarkRenderedRebasesAfterLargeStall();
|
|
|
|
if (gFailures != 0)
|
|
{
|
|
std::cerr << gFailures << " cadence clock test failure(s).\n";
|
|
return 1;
|
|
}
|
|
|
|
std::cout << "RenderCadenceCompositor cadence clock tests passed.\n";
|
|
return 0;
|
|
}
|