feat(gui): introduce deadline rendering
This commit is contained in:
parent
7b8a037627
commit
2adad0b05b
4 changed files with 47 additions and 16 deletions
|
|
@ -137,8 +137,8 @@ fn fmtmsg(self: *Self, value: anytype) std.Io.Writer.Error![]const u8 {
|
|||
return self.event_buffer.written();
|
||||
}
|
||||
|
||||
pub fn render(self: *Self) error{}!bool {
|
||||
if (!self.window_ready) return false;
|
||||
pub fn render(self: *Self) error{}!?i64 {
|
||||
if (!self.window_ready) return null;
|
||||
|
||||
var cursor = self.cursor_info;
|
||||
|
||||
|
|
@ -175,9 +175,12 @@ pub fn render(self: *Self) error{}!bool {
|
|||
|
||||
app.updateScreen(&self.vx.screen, cursor, self.secondary_cursors.items);
|
||||
|
||||
if (!self.cursor_info.vis or !self.cursor_blink) return false;
|
||||
const idle = std.time.microTimestamp() - self.blink_last_change;
|
||||
return idle < self.blink_idle_us;
|
||||
if (!self.cursor_info.vis or !self.cursor_blink) return null;
|
||||
const now_check = std.time.microTimestamp();
|
||||
if (now_check - self.blink_last_change >= self.blink_idle_us) return null;
|
||||
const elapsed = @mod(now_check - self.blink_epoch, self.blink_period_us * 2);
|
||||
const deadline = now_check + (self.blink_period_us - @mod(elapsed, self.blink_period_us));
|
||||
return deadline;
|
||||
}
|
||||
|
||||
pub fn sigwinch(self: *Self) !void {
|
||||
|
|
|
|||
|
|
@ -219,11 +219,11 @@ pub fn run(self: *Self) Error!void {
|
|||
try self.loop.start();
|
||||
}
|
||||
|
||||
pub fn render(self: *Self) !bool {
|
||||
if (in_panic.load(.acquire)) return false;
|
||||
pub fn render(self: *Self) !?i64 {
|
||||
if (in_panic.load(.acquire)) return null;
|
||||
try self.vx.render(self.tty.writer());
|
||||
try self.tty.writer().flush();
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn sigwinch(self: *Self) !void {
|
||||
|
|
|
|||
|
|
@ -165,10 +165,10 @@ fn fmtmsg(self: *Self, value: anytype) std.Io.Writer.Error![]const u8 {
|
|||
return self.event_buffer.written();
|
||||
}
|
||||
|
||||
pub fn render(self: *Self) error{}!bool {
|
||||
const hwnd = self.hwnd orelse return false;
|
||||
pub fn render(self: *Self) error{}!?i64 {
|
||||
const hwnd = self.hwnd orelse return null;
|
||||
_ = gui.updateScreen(hwnd, &self.vx.screen);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
pub fn stop(self: *Self) void {
|
||||
// this is guaranteed because stop won't be called until after
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ render_pending: bool = false,
|
|||
keepalive_timer: ?tp.Cancellable = null,
|
||||
input_idle_timer: ?tp.Cancellable = null,
|
||||
mouse_idle_timer: ?tp.Cancellable = null,
|
||||
render_deadline_timer: ?tp.Cancellable = null,
|
||||
fontface_: []const u8 = "",
|
||||
fontfaces_: std.ArrayListUnmanaged([]const u8) = .{},
|
||||
input_is_idle: bool = false,
|
||||
|
|
@ -293,6 +294,11 @@ fn deinit(self: *Self) void {
|
|||
t.deinit();
|
||||
self.keepalive_timer = null;
|
||||
}
|
||||
if (self.render_deadline_timer) |*t| {
|
||||
t.cancel() catch {};
|
||||
t.deinit();
|
||||
self.render_deadline_timer = null;
|
||||
}
|
||||
if (self.input_mode_) |*m| {
|
||||
m.deinit();
|
||||
self.input_mode_ = null;
|
||||
|
|
@ -681,17 +687,24 @@ fn render(self: *Self) void {
|
|||
top_layer_.draw(self.rdr_.stdplane());
|
||||
}
|
||||
|
||||
const renderer_more = ret: {
|
||||
if (self.render_deadline_timer) |*t| {
|
||||
t.cancel() catch {};
|
||||
t.deinit();
|
||||
self.render_deadline_timer = null;
|
||||
}
|
||||
|
||||
const render_deadline: ?i64 = ret: {
|
||||
const frame = tracy.initZone(@src(), .{ .name = renderer.log_name ++ " render" });
|
||||
defer frame.deinit();
|
||||
const m = self.rdr_.render() catch |e| blk: {
|
||||
const dl = self.rdr_.render() catch |e| blk: {
|
||||
self.logger.err("render", e);
|
||||
break :blk false;
|
||||
break :blk @as(?i64, null);
|
||||
};
|
||||
tracy.frameMark();
|
||||
self.unrendered_input_events_count = 0;
|
||||
break :ret m;
|
||||
break :ret dl;
|
||||
};
|
||||
|
||||
self.top_layer_reset();
|
||||
|
||||
self.idle_frame_count = if (self.unrendered_input_events_count > 0)
|
||||
|
|
@ -699,13 +712,28 @@ fn render(self: *Self) void {
|
|||
else
|
||||
self.idle_frame_count + 1;
|
||||
|
||||
if (more or renderer_more or self.idle_frame_count < idle_frames or self.no_sleep) {
|
||||
const deadline_within_frame = if (render_deadline) |dl|
|
||||
dl - std.time.microTimestamp() < @as(i64, @intCast(self.frame_time))
|
||||
else
|
||||
false;
|
||||
|
||||
if (more or deadline_within_frame or self.idle_frame_count < idle_frames or self.no_sleep) {
|
||||
if (!self.frame_clock_running) {
|
||||
self.frame_clock.start() catch {};
|
||||
self.frame_clock_running = true;
|
||||
tp.trace(tp.channel.widget, .{ "frame_clock_running", "started", more });
|
||||
}
|
||||
} else {
|
||||
if (render_deadline) |deadline| {
|
||||
const delay_us: u64 = @intCast(@max(0, deadline - std.time.microTimestamp()));
|
||||
self.render_deadline_timer = tp.self_pid().delay_send_cancellable(
|
||||
self.allocator,
|
||||
"tui.render_deadline",
|
||||
delay_us,
|
||||
.{"render"},
|
||||
) catch null;
|
||||
}
|
||||
|
||||
if (self.frame_clock_running) {
|
||||
self.frame_clock.stop() catch {};
|
||||
self.frame_clock_running = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue