Smooth motion: budget dynres for the in-between frames, time them from the game frame's arrival, keep small views put, move HUD needles

- Dynamic resolution budgets the real frames with the share of the game
  frame Smooth motion leaves them (gl_renderer_frame_gen_real_share), so the
  scale drops until the in-between frames fit the display refresh.
- In-between frames are timed from the game frame's arrival, not from the end
  of its composition; the last one per game frame is no longer dropped by a
  quarter-interval margin.
- Views under 15 % of the largest (a rear-view mirror) stay as the real frame
  drew them: a wrong mirror camera fit threw its lane marks across the
  screen as a dashed line.
- HUD: 2D triangles both frames draw with the same key that moved a little
  (tachometer needle) are interpolated; changed digits stay as drawn.
- frame_gen JSON: end_ahead / end_bp / end_phase counters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-10-07 13:09:21 -07:00
parent 3c64a13347
commit 0bebface12
6 changed files with 124 additions and 9 deletions
+3 -1
View File
@@ -9421,7 +9421,9 @@ static void dynres_tick_rt(double now_s, double wall, double period, int held,
g_dynres.rt_acc_gpu_frames += co.gpu_frames - c0.gpu_frames;
g_dynres.last_costs = co;
g_dynres.last_bp_ns = bp_ns;
DynrtSample smp{ period, wall, frames, cost, bp, held };
/* Smooth motion's in-between frames share the game frame with it. */
const double share = gl_renderer_frame_gen_real_share();
DynrtSample smp{ period * share, wall, frames, cost, bp, held };
const int prev_level = c.level;
const int level = dynrt_sample(&c, now_s, &smp);
/* Frame generation only spends surplus: not while the real frames are