From 8d062a90b1ffbe9e00334fa3e9e939406bd32141 Mon Sep 17 00:00:00 2001 From: Nathan Reiner Date: Sun, 2 Feb 2025 16:00:15 +0100 Subject: screen: add vsync and double buffering --- src/screen/main.zig | 86 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 19 deletions(-) (limited to 'src/screen/main.zig') diff --git a/src/screen/main.zig b/src/screen/main.zig index 1a33fd0..f11f628 100644 --- a/src/screen/main.zig +++ b/src/screen/main.zig @@ -1,5 +1,6 @@ const std = @import("std"); const drm = @import("drm/card.zig"); +const Event = @import("drm/event.zig").Event; pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; @@ -38,35 +39,82 @@ pub fn main() !void { std.debug.print("crtc = {}\n", .{ crtc.id }); - var framebuffer = try card.create_frame_buffer(mode.horizontal.size, mode.vertical.size, 32); - defer framebuffer.deinit(); + var double_buffer = try card.create_double_buffer(mode.horizontal.size, mode.vertical.size, 32); + defer double_buffer.deinit(); - std.debug.print("framebuffer = {}, {}\n", .{ framebuffer.id, framebuffer.canvas_size }); + std.debug.print("buffer = {}, {}x{}, stride = {}\n", .{ + double_buffer.buffer().id, + double_buffer.buffer().width, + double_buffer.buffer().height, + double_buffer.buffer().stride, + }); - try crtc.attach(&framebuffer, &connector, mode); + try crtc.attach(double_buffer.crtc_buffer(), &connector, mode); - var frame: u24 = 0; + const Pos = struct { x: f32, y: f32 }; + + var vec = Pos { .x = 10, .y = 10 }; + var pos = Pos { .x = 0, .y = 0 }; + var delta: f32 = 0; + const size = 100; + + const width: f32 = @floatFromInt(double_buffer.buffer().width); + const height: f32 = @floatFromInt(double_buffer.buffer().height); while (true) { - for (0..framebuffer.width) |x| { - for (0..framebuffer.height) |y| { - const raster_x = (frame + x) / 100 * 100; - const raster_y = y / 100 * 100; - const color = ((raster_x + raster_y) + 0x129453) * 0x329120; - framebuffer.set(@intCast(x), @intCast(y), .{ - .red = @intCast(color & 0xff), - .green = @intCast((color >> 8) & 0xff), - .blue = @intCast((color >> 16) & 0xff), + const start = try std.time.Instant.now(); + + double_buffer.buffer().fill(.{ .red = 0, .green = 0, .blue = 0 }); + + pos.x += vec.x * delta; + pos.y += vec.y * delta; + + if (pos.x < 0) { + pos.x = -pos.x; + vec.x = -vec.x; + } else if (pos.x + size >= width) { + pos.x = width - size; + vec.x = -vec.x; + } + + if (pos.y < 0) { + pos.y = -pos.y; + vec.y = -vec.y; + } else if (pos.y + size >= height) { + pos.y = height - size; + vec.y = -vec.y; + } + + for (0..size) |w| { + for (0..size) |h| { + double_buffer.buffer().set( + @as(u32, @intFromFloat(pos.x)) + @as(u32, @intCast(w)), + @as(u32, @intFromFloat(pos.y)) + @as(u32, @intCast(h)), + .{ + .red = 0xff, + .green = 0, + .blue = 0, }); } } - frame, _ = @addWithOverflow(frame, 1); + const end = try std.time.Instant.now(); + const elapsed = (@as(f32, @floatFromInt(end.since(start))) / std.time.ns_per_s); + std.debug.print("FPS: {d:.2}\r", .{ 1 / elapsed }); + delta = elapsed * 60; - try crtc.attach(&framebuffer, &connector, mode); + try crtc.page_flip(&double_buffer); - std.time.sleep(@intFromFloat(1000000000 / mode.frame_rate())); - } + while (true) { + var event: ?Event = null; + while (event == null) { + event = try card.poll_event(5000); + } - while (true) { std.time.sleep(5000000000); } + switch ((event orelse unreachable).type) { + .page_flip_complete => break, + else => {}, + } + } + } } -- cgit v1.2.3-70-g09d2