Smooth rendering!
This commit is contained in:
+107
-96
@@ -51,10 +51,14 @@ const WaylandState = struct {
|
||||
surface: ?*c.wl_surface,
|
||||
buffer: ?*c.wl_buffer,
|
||||
|
||||
shared_memory_pool_data: []u8,
|
||||
|
||||
xkb_context: ?*c.xkb_context,
|
||||
xkb_keymap: ?*c.xkb_keymap,
|
||||
xkb_state: ?*c.xkb_state,
|
||||
|
||||
io: std.Io,
|
||||
clock: std.Io.Clock,
|
||||
allocator: std.mem.Allocator,
|
||||
|
||||
resize: bool,
|
||||
@@ -66,6 +70,7 @@ const WaylandState = struct {
|
||||
|
||||
pointer_event: WlPointerEvent,
|
||||
|
||||
app_memory: puzzle.platform.AppMemory,
|
||||
app_input: puzzle.platform.AppInput,
|
||||
};
|
||||
|
||||
@@ -124,6 +129,42 @@ fn wlFrameHandleDone(data: ?*anyopaque, callback: ?*c.wl_callback, callback_data
|
||||
|
||||
std.debug.print("[Wayland] Frame ready\n", .{});
|
||||
|
||||
const render_start_time = wl_state.clock.now(wl_state.io);
|
||||
|
||||
wl_state.app_input.delta_time = 1.0 / 30.0;
|
||||
|
||||
const app_offscreen_buffer: puzzle.platform.OffscreenBuffer = .{
|
||||
.width = wl_state.window_width,
|
||||
.height = wl_state.window_height,
|
||||
.stride = wl_state.window_width * 4,
|
||||
.data = wl_state.shared_memory_pool_data,
|
||||
};
|
||||
// wl_state.app_input.controls = puzzle.platform.Controls{ .key = old_key };
|
||||
puzzle.updateAndRender(wl_state.io, &wl_state.app_memory, app_offscreen_buffer, &wl_state.app_input);
|
||||
|
||||
const render_end_time = wl_state.clock.now(wl_state.io);
|
||||
const render_time = render_start_time.durationTo(render_end_time);
|
||||
|
||||
std.debug.print("[Wayland] Render: {f}.\n", .{render_time});
|
||||
|
||||
// if (render_time.toNanoseconds() < frame_target_time_ns.toNanoseconds()) {
|
||||
// const sleep_duration: std.Io.Clock.Duration = .{
|
||||
// .raw = .{ .nanoseconds = frame_target_time.nanoseconds - render_time.nanoseconds },
|
||||
// .clock = clock,
|
||||
// };
|
||||
// std.debug.print("[Wayland] Sleeping: {f}.\n", .{sleep_duration.raw});
|
||||
// sleep_duration.sleep(io) catch {
|
||||
// std.debug.print("[Wayland] Error sleeping\n", .{});
|
||||
// return 1;
|
||||
// };
|
||||
// } else {
|
||||
// std.debug.print("[Wayland] MISSED FRAME\n", .{});
|
||||
// }
|
||||
|
||||
c.wl_surface_attach(wl_state.surface, wl_state.buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_state.surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_state.surface);
|
||||
|
||||
wl_state.frame_commited = true;
|
||||
}
|
||||
|
||||
@@ -146,12 +187,14 @@ fn xdg_surface_handle_configure(data: ?*anyopaque, xdg_surface: ?*c.xdg_surface,
|
||||
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||
|
||||
c.xdg_surface_ack_configure(xdg_surface, serial);
|
||||
c.wl_surface_commit(wl_state.surface);
|
||||
|
||||
// TODO: Ready to resize?
|
||||
if (wl_state.window_resized) {
|
||||
wl_state.resize = true;
|
||||
}
|
||||
|
||||
std.debug.print("[Wayland] Configured.\n", .{});
|
||||
wl_state.configured = true;
|
||||
}
|
||||
|
||||
@@ -856,13 +899,19 @@ fn pollEvents(wl_state: *WaylandState, fds: *[1]linux.pollfd) void {
|
||||
pub fn main(init: std.process.Init) u8 {
|
||||
const io = init.io;
|
||||
|
||||
const clock = std.Io.Clock.awake;
|
||||
const clock_resolution = clock.resolution(io) catch {
|
||||
std.debug.print("[Wayland] ERROR: awake clock resoultion not supported.\n", .{});
|
||||
return 1;
|
||||
};
|
||||
|
||||
const display = c.wl_display_connect(null);
|
||||
if (display == null) {
|
||||
std.debug.print("Error connecting to wayland display.\n", .{});
|
||||
return 1;
|
||||
}
|
||||
|
||||
const wl_fd = c.wl_display_get_fd(display);
|
||||
// const wl_fd = c.wl_display_get_fd(display);
|
||||
|
||||
std.debug.print("[Wayland] Connection established.\n", .{});
|
||||
|
||||
@@ -871,6 +920,8 @@ pub fn main(init: std.process.Init) u8 {
|
||||
wl_state.xkb_context = null;
|
||||
wl_state.xkb_state = null;
|
||||
wl_state.xkb_keymap = null;
|
||||
wl_state.io = io;
|
||||
wl_state.clock = clock;
|
||||
|
||||
const registry = c.wl_display_get_registry(display);
|
||||
if (registry == null) {
|
||||
@@ -927,11 +978,6 @@ pub fn main(init: std.process.Init) u8 {
|
||||
wl_state.window_width = 1280;
|
||||
wl_state.window_height = 960;
|
||||
|
||||
const clock = std.Io.Clock.awake;
|
||||
const clock_resolution = clock.resolution(io) catch {
|
||||
std.debug.print("[Wayland] ERROR: awake clock resoultion not supported.\n", .{});
|
||||
return 1;
|
||||
};
|
||||
{
|
||||
var buf: [34]u8 = undefined;
|
||||
var w: std.Io.Writer = .fixed(&buf);
|
||||
@@ -943,11 +989,10 @@ pub fn main(init: std.process.Init) u8 {
|
||||
}
|
||||
|
||||
var shared_memory_pool: ?*c.wl_shm_pool = undefined;
|
||||
var shared_memory_pool_data: []u8 = undefined;
|
||||
|
||||
const monitor_update_hz: f64 = 30;
|
||||
const game_update_hz: f64 = monitor_update_hz;
|
||||
const frame_target_time_s: f64 = 1.0 / game_update_hz;
|
||||
// const monitor_update_hz: f64 = 30;
|
||||
// const game_update_hz: f64 = monitor_update_hz;
|
||||
// const frame_target_time_s: f64 = 1.0 / game_update_hz;
|
||||
// const frame_target_time_ms: f64 = std.time.ms_per_s * frame_target_time_s;
|
||||
// const frame_target_time_ns = std.Io.Duration.fromNanoseconds(std.time.ns_per_ms * @as(u64, @intFromFloat(frame_target_time_ms)));
|
||||
// const frame_target_time = std.Io.Duration.fromNanoseconds(@intFromFloat(std.time.ns_per_s * frame_target_time_s));
|
||||
@@ -963,7 +1008,7 @@ pub fn main(init: std.process.Init) u8 {
|
||||
return 1;
|
||||
};
|
||||
|
||||
var app_memory: puzzle.platform.AppMemory = .{
|
||||
wl_state.app_memory = .{
|
||||
.initialized = false,
|
||||
.permanent_storage = app_permanent_storage,
|
||||
};
|
||||
@@ -974,98 +1019,64 @@ pub fn main(init: std.process.Init) u8 {
|
||||
std.debug.print("[Wayland] Added frame callback with ret {d}.\n", .{ret});
|
||||
}
|
||||
|
||||
if (wl_state.resize) {
|
||||
const new_pool = createSharedMemoryPool(wl_state) catch {
|
||||
std.debug.print("[Wayland] Error creating memory pool!\n", .{});
|
||||
wl_state.running = false;
|
||||
return 1;
|
||||
};
|
||||
|
||||
std.debug.print(
|
||||
"[Wayland] Reizing window to {d}x{d} = {d}B.\n",
|
||||
.{ wl_state.window_width, wl_state.window_height, new_pool.data.len },
|
||||
);
|
||||
|
||||
shared_memory_pool = new_pool.pool;
|
||||
wl_state.shared_memory_pool_data = new_pool.data;
|
||||
|
||||
const stride = wl_state.window_width * 4;
|
||||
const buffer = c.wl_shm_pool_create_buffer(
|
||||
shared_memory_pool,
|
||||
0,
|
||||
wl_state.window_width,
|
||||
wl_state.window_height,
|
||||
stride,
|
||||
c.WL_SHM_FORMAT_ARGB8888,
|
||||
);
|
||||
if (buffer) |buf| {
|
||||
wl_state.buffer = buf;
|
||||
} else {
|
||||
std.debug.print("[Wayland] Error creating buffer!\n", .{});
|
||||
wl_state.running = false;
|
||||
return 1;
|
||||
}
|
||||
|
||||
wl_state.resize = false;
|
||||
wl_state.window_resized = false;
|
||||
wl_state.frame_commited = true;
|
||||
c.wl_surface_attach(wl_state.surface, wl_state.buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_state.surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_state.surface);
|
||||
}
|
||||
|
||||
var start = clock.now(io);
|
||||
|
||||
var frame_count: u32 = 0;
|
||||
|
||||
var fds: [1]linux.pollfd = .{
|
||||
.{
|
||||
.fd = wl_fd,
|
||||
.events = std.posix.POLL.IN,
|
||||
.revents = 0,
|
||||
},
|
||||
};
|
||||
// var fds: [1]linux.pollfd = .{
|
||||
// .{
|
||||
// .fd = wl_fd,
|
||||
// .events = std.posix.POLL.IN,
|
||||
// .revents = 0,
|
||||
// },
|
||||
// };
|
||||
while (wl_state.running) {
|
||||
pollEvents(&wl_state, &fds);
|
||||
|
||||
if (wl_state.resize) {
|
||||
const new_pool = createSharedMemoryPool(wl_state) catch {
|
||||
std.debug.print("[Wayland] Error creating memory pool!\n", .{});
|
||||
wl_state.running = false;
|
||||
break;
|
||||
};
|
||||
|
||||
std.debug.print(
|
||||
"[Wayland] Reizing window to {d}x{d} = {d}B.\n",
|
||||
.{ wl_state.window_width, wl_state.window_height, new_pool.data.len },
|
||||
);
|
||||
|
||||
shared_memory_pool = new_pool.pool;
|
||||
shared_memory_pool_data = new_pool.data;
|
||||
|
||||
const stride = wl_state.window_width * 4;
|
||||
const buffer = c.wl_shm_pool_create_buffer(
|
||||
shared_memory_pool,
|
||||
0,
|
||||
wl_state.window_width,
|
||||
wl_state.window_height,
|
||||
stride,
|
||||
c.WL_SHM_FORMAT_ARGB8888,
|
||||
);
|
||||
if (buffer) |buf| {
|
||||
wl_state.buffer = buf;
|
||||
} else {
|
||||
std.debug.print("[Wayland] Error creating buffer!\n", .{});
|
||||
wl_state.running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
wl_state.resize = false;
|
||||
wl_state.window_resized = false;
|
||||
wl_state.frame_commited = true;
|
||||
c.wl_surface_attach(wl_state.surface, wl_state.buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_state.surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_state.surface);
|
||||
const ret = c.wl_display_dispatch(wl_state.display);
|
||||
if (ret == -1) {
|
||||
std.debug.print("[Wayland] Dispatch failed: exiting.\n", .{});
|
||||
wl_state.running = false;
|
||||
}
|
||||
|
||||
const render_start_time = clock.now(io);
|
||||
|
||||
wl_state.app_input.delta_time = frame_target_time_s;
|
||||
|
||||
const app_offscreen_buffer: puzzle.platform.OffscreenBuffer = .{
|
||||
.width = wl_state.window_width,
|
||||
.height = wl_state.window_height,
|
||||
.stride = wl_state.window_width * 4,
|
||||
.data = shared_memory_pool_data,
|
||||
};
|
||||
// wl_state.app_input.controls = puzzle.platform.Controls{ .key = old_key };
|
||||
puzzle.updateAndRender(io, &app_memory, app_offscreen_buffer, &wl_state.app_input);
|
||||
|
||||
const render_end_time = clock.now(io);
|
||||
const render_time = render_start_time.durationTo(render_end_time);
|
||||
|
||||
std.debug.print("[Wayland] Render: {f}.\n", .{render_time});
|
||||
|
||||
// if (render_time.toNanoseconds() < frame_target_time_ns.toNanoseconds()) {
|
||||
// const sleep_duration: std.Io.Clock.Duration = .{
|
||||
// .raw = .{ .nanoseconds = frame_target_time.nanoseconds - render_time.nanoseconds },
|
||||
// .clock = clock,
|
||||
// };
|
||||
// std.debug.print("[Wayland] Sleeping: {f}.\n", .{sleep_duration.raw});
|
||||
// sleep_duration.sleep(io) catch {
|
||||
// std.debug.print("[Wayland] Error sleeping\n", .{});
|
||||
// return 1;
|
||||
// };
|
||||
// } else {
|
||||
// std.debug.print("[Wayland] MISSED FRAME\n", .{});
|
||||
// }
|
||||
|
||||
c.wl_surface_attach(wl_state.surface, wl_state.buffer, 0, 0);
|
||||
c.wl_surface_damage_buffer(wl_state.surface, 0, 0, wl_state.window_width, wl_state.window_height);
|
||||
c.wl_surface_commit(wl_state.surface);
|
||||
|
||||
_ = c.wl_display_roundtrip(wl_state.display);
|
||||
|
||||
wl_state.frame_commited = false;
|
||||
|
||||
const last = clock.now(io);
|
||||
|
||||
Reference in New Issue
Block a user