Smooth rendering!
This commit is contained in:
+107
-96
@@ -51,10 +51,14 @@ const WaylandState = struct {
|
|||||||
surface: ?*c.wl_surface,
|
surface: ?*c.wl_surface,
|
||||||
buffer: ?*c.wl_buffer,
|
buffer: ?*c.wl_buffer,
|
||||||
|
|
||||||
|
shared_memory_pool_data: []u8,
|
||||||
|
|
||||||
xkb_context: ?*c.xkb_context,
|
xkb_context: ?*c.xkb_context,
|
||||||
xkb_keymap: ?*c.xkb_keymap,
|
xkb_keymap: ?*c.xkb_keymap,
|
||||||
xkb_state: ?*c.xkb_state,
|
xkb_state: ?*c.xkb_state,
|
||||||
|
|
||||||
|
io: std.Io,
|
||||||
|
clock: std.Io.Clock,
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
resize: bool,
|
resize: bool,
|
||||||
@@ -66,6 +70,7 @@ const WaylandState = struct {
|
|||||||
|
|
||||||
pointer_event: WlPointerEvent,
|
pointer_event: WlPointerEvent,
|
||||||
|
|
||||||
|
app_memory: puzzle.platform.AppMemory,
|
||||||
app_input: puzzle.platform.AppInput,
|
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", .{});
|
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;
|
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));
|
var wl_state: *WaylandState = @ptrCast(@alignCast(data));
|
||||||
|
|
||||||
c.xdg_surface_ack_configure(xdg_surface, serial);
|
c.xdg_surface_ack_configure(xdg_surface, serial);
|
||||||
|
c.wl_surface_commit(wl_state.surface);
|
||||||
|
|
||||||
// TODO: Ready to resize?
|
// TODO: Ready to resize?
|
||||||
if (wl_state.window_resized) {
|
if (wl_state.window_resized) {
|
||||||
wl_state.resize = true;
|
wl_state.resize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std.debug.print("[Wayland] Configured.\n", .{});
|
||||||
wl_state.configured = true;
|
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 {
|
pub fn main(init: std.process.Init) u8 {
|
||||||
const io = init.io;
|
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);
|
const display = c.wl_display_connect(null);
|
||||||
if (display == null) {
|
if (display == null) {
|
||||||
std.debug.print("Error connecting to wayland display.\n", .{});
|
std.debug.print("Error connecting to wayland display.\n", .{});
|
||||||
return 1;
|
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", .{});
|
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_context = null;
|
||||||
wl_state.xkb_state = null;
|
wl_state.xkb_state = null;
|
||||||
wl_state.xkb_keymap = null;
|
wl_state.xkb_keymap = null;
|
||||||
|
wl_state.io = io;
|
||||||
|
wl_state.clock = clock;
|
||||||
|
|
||||||
const registry = c.wl_display_get_registry(display);
|
const registry = c.wl_display_get_registry(display);
|
||||||
if (registry == null) {
|
if (registry == null) {
|
||||||
@@ -927,11 +978,6 @@ pub fn main(init: std.process.Init) u8 {
|
|||||||
wl_state.window_width = 1280;
|
wl_state.window_width = 1280;
|
||||||
wl_state.window_height = 960;
|
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 buf: [34]u8 = undefined;
|
||||||
var w: std.Io.Writer = .fixed(&buf);
|
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: ?*c.wl_shm_pool = undefined;
|
||||||
var shared_memory_pool_data: []u8 = undefined;
|
|
||||||
|
|
||||||
const monitor_update_hz: f64 = 30;
|
// const monitor_update_hz: f64 = 30;
|
||||||
const game_update_hz: f64 = monitor_update_hz;
|
// const game_update_hz: f64 = monitor_update_hz;
|
||||||
const frame_target_time_s: f64 = 1.0 / game_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_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_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));
|
// 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;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
var app_memory: puzzle.platform.AppMemory = .{
|
wl_state.app_memory = .{
|
||||||
.initialized = false,
|
.initialized = false,
|
||||||
.permanent_storage = app_permanent_storage,
|
.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});
|
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 start = clock.now(io);
|
||||||
|
|
||||||
var frame_count: u32 = 0;
|
var frame_count: u32 = 0;
|
||||||
|
|
||||||
var fds: [1]linux.pollfd = .{
|
// var fds: [1]linux.pollfd = .{
|
||||||
.{
|
// .{
|
||||||
.fd = wl_fd,
|
// .fd = wl_fd,
|
||||||
.events = std.posix.POLL.IN,
|
// .events = std.posix.POLL.IN,
|
||||||
.revents = 0,
|
// .revents = 0,
|
||||||
},
|
// },
|
||||||
};
|
// };
|
||||||
while (wl_state.running) {
|
while (wl_state.running) {
|
||||||
pollEvents(&wl_state, &fds);
|
const ret = c.wl_display_dispatch(wl_state.display);
|
||||||
|
if (ret == -1) {
|
||||||
if (wl_state.resize) {
|
std.debug.print("[Wayland] Dispatch failed: exiting.\n", .{});
|
||||||
const new_pool = createSharedMemoryPool(wl_state) catch {
|
wl_state.running = false;
|
||||||
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 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;
|
wl_state.frame_commited = false;
|
||||||
|
|
||||||
const last = clock.now(io);
|
const last = clock.now(io);
|
||||||
|
|||||||
Reference in New Issue
Block a user