The pacer counted only its own frames, so the client's 30 came on top (60 gave about 80), and it added no frames at all when the rate was out of reach. It now asks for a window's next frame once the interval since its last frame began has passed, and the client has had a third of a frame's time idle: all frames within the rate, and as many as the client can draw when it can't reach it. The engine's stats also break a frame's time down: sending to the renderer process, bytes sent, buffer updates. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
05a7be5d41
commit
399d934a08
6 files changed
+45
-18
No files matched your search
@@ -14,10 +14,8 @@ namespace {
|
||||
|
||||
// The client's own rate: its ticks already draw these frames.
|
||||
constexpr DWORD clientRate = 30;
|
||||
// Extra frames only if a frame takes less than this share of the interval.
|
||||
constexpr double affordable = 0.75;
|
||||
// Uncapped, the client is left idle this share of a frame's time between frames.
|
||||
constexpr double uncappedIdle = 1.0 / 3.0;
|
||||
// The client is left idle at least this share of a frame's time between frames.
|
||||
constexpr double idleShare = 1.0 / 3.0;
|
||||
|
||||
// The user's frame rate, from the registry (unset or unreadable: the client's own).
|
||||
DWORD read_rate()
|
||||
@@ -88,8 +86,8 @@ private:
|
||||
double askedAt = 0; // when a repaint was last asked for
|
||||
};
|
||||
|
||||
// Re-reads the setting now and then; above the client's rate, asks each window for a repaint at the rate, when
|
||||
// affordable.
|
||||
// Re-reads the setting now and then; above the client's rate, asks each window for repaints at the rate, or as often
|
||||
// as leaves the client its idle time.
|
||||
void run()
|
||||
{
|
||||
HANDLE timer = CreateWaitableTimerExW(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
|
||||
@@ -116,9 +114,8 @@ private:
|
||||
if (w.pending && now - w.askedAt < 0.25) {
|
||||
continue; // not drawn yet (asked again after a while: the client may have skipped it)
|
||||
}
|
||||
const bool due = rate == 0 ? now - w.drawnAt >= w.frameTime * uncappedIdle
|
||||
: now - w.askedAt >= interval && w.frameTime < interval * affordable;
|
||||
if (due) {
|
||||
// Since the last frame ended: the rest of the interval since it began, and the idle time.
|
||||
if (now - w.drawnAt >= std::max(interval - w.frameTime, w.frameTime * idleShare)) {
|
||||
w.pending = true;
|
||||
w.askedAt = now;
|
||||
InvalidateRect(w.window, nullptr, FALSE);
|
||||
|
||||
Reference in new issue
Block a user