diff options
Diffstat (limited to 'src/gui/gui.zig')
| -rw-r--r-- | src/gui/gui.zig | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/src/gui/gui.zig b/src/gui/gui.zig index ab1875b7..aa39cf32 100644 --- a/src/gui/gui.zig +++ b/src/gui/gui.zig @@ -4086,7 +4086,12 @@ fn waitInput(ctx: ?*anyopaque, timeout_ms: u32) void { const minimized = !s.test_mode and c.SDL_GetWindowFlags(g.window) & (c.SDL_WINDOW_MINIMIZED | c.SDL_WINDOW_OCCLUDED) != 0; // A latency trace is fed on stdin, whose poll below paces the loop: // waiting here too would make every tick cost two frames. - const ms: c_int = if (latency_fd >= 0) 0 else if (minimized) -1 else if (timeout_ms != 0) @intCast(timeout_ms) else if (polls) 16 else -1; + // A chain that moves on its own wakes once a display refresh. + const poll_ms: c_int = if (g.post.animating(core.settings.shader_animation)) + @intCast(@max(1, refreshNs(g) / std.time.ns_per_ms)) + else + 16; + const ms: c_int = if (latency_fd >= 0) 0 else if (minimized) -1 else if (timeout_ms != 0) @min(@as(c_int, @intCast(@min(timeout_ms, std.math.maxInt(c_int)))), if (polls) poll_ms else std.math.maxInt(c_int)) else if (polls) poll_ms else -1; // The wait is the 9P connections' turn with the core. pardes.turn.rest(); const got = c.SDL_WaitEventTimeout(&sev, ms); @@ -4168,9 +4173,19 @@ fn pollFrame(ctx: ?*anyopaque) void { if (updateCoreResize(core, geom.cols, geom.rows, g.cell_w, g.cell_h, g.tagline_width, g.tagline_height)) resetScroll(g); stepScroll(g, core, s.gpa); g.post.sync(s.gpa, s.io, g.device, g.swapchain_format, core); - // Between the core's frames, a chain that moves on its own redraws alone. + // Between the core's frames, a chain that moves on its own redraws + // alone, once a refresh of the display the window is on (a millisecond + // early is on time: the wait that paces it is in whole milliseconds). if (g.post.animating(core.settings.shader_animation) and !core.needs_frame and s.presented and - c.SDL_GetTicksNS() -| g.post.last_ns >= pardes.animation.frame_ns) redrawPost(g, s.gpa); + c.SDL_GetTicksNS() -| g.post.last_ns + std.time.ns_per_ms >= refreshNs(g)) redrawPost(g, s.gpa); +} + +/// One refresh of the display the window is on, in ns; a frame of the +/// core's where the display does not say. +fn refreshNs(g: *const Gui) u64 { + const mode = c.SDL_GetCurrentDisplayMode(c.SDL_GetDisplayForWindow(g.window)) orelse return pardes.animation.frame_ns; + if (!(mode.*.refresh_rate > 1)) return pardes.animation.frame_ns; + return @intFromFloat(@as(f64, std.time.ns_per_s) / mode.*.refresh_rate); } fn finishWindowOpacity(core: *pardes.Pardes, applied: *u8, failure: ?[]const u8) void { |
