diff options
| author | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-02-02 21:54:14 +0100 |
|---|---|---|
| committer | Nathan Reiner <nathan@nathanreiner.xyz> | 2025-02-02 21:54:14 +0100 |
| commit | 811a6bd572f4c6b26e99b4e746f5d710947ee934 (patch) | |
| tree | 3ff6375ce2d7ea13e0d49f7800757a1b42604884 /src/screen/drm/buffer | |
| parent | 3f4375a14218796cbd7bfff1c8cfff0f7bb1f6df (diff) | |
screen: drm change struct layout
Diffstat (limited to 'src/screen/drm/buffer')
| -rw-r--r-- | src/screen/drm/buffer/raw.zig | 109 | ||||
| -rw-r--r-- | src/screen/drm/buffer/root.zig | 32 |
2 files changed, 141 insertions, 0 deletions
diff --git a/src/screen/drm/buffer/raw.zig b/src/screen/drm/buffer/raw.zig new file mode 100644 index 0000000..e4674eb --- /dev/null +++ b/src/screen/drm/buffer/raw.zig @@ -0,0 +1,109 @@ +const std = @import("std"); +const os = std.os.linux; +const drm = @import("../root.zig"); +const cerror = @import("../../cerror.zig"); + +pub const Raw = struct { + const Self = @This(); + + card: *drm.Card, + id: u32, + width: u32, + height: u32, + bpp: u32, + stride: u32, + data_size: u64, + canvas_size: u64, + handle: u32, + data: [*]volatile drm.Pixel, + + pub fn init(card: *drm.Card, width: u32, height: u32, bpp: u32) !Self { + var create_dumb = std.mem.zeroInit(drm.request.CreateDumb, .{ + .width = width, + .height = height, + .bpp = bpp, + }); + try card.request( + .create_dumb, + &create_dumb + ); + + var fb = Self { + .id = 0, + .width = create_dumb.width, + .height = create_dumb.height, + .bpp = create_dumb.bpp, + .stride = create_dumb.pitch, + .data_size = create_dumb.size, + .canvas_size = create_dumb.size / (bpp / 8), + .handle = create_dumb.handle, + .data = undefined, + .card = card, + }; + + var buffer_cmd = drm.request.FrameBufferCmd2 { + .id = 0, + .width = fb.width, + .height = fb.height, + .pixel_format = drm.Pixel.Format.xrgb8888, + .flags = 0, + .handles = [_] u32 { fb.handle, 0, 0, 0 }, + .pitches = [_] u32 { fb.stride, 0, 0, 0 }, + .offsets = [_] u32 { 0, 0, 0, 0 }, + .modifier = [_] u32 { 0, 0, 0, 0 }, + }; + + try card.request( + .add_frame_buffer2, + &buffer_cmd + ); + + fb.id = buffer_cmd.id; + + var map_dumb = std.mem.zeroInit(drm.request.MapDumb, .{ .handle = fb.handle }); + + try card.request( + .map_dumb, + &map_dumb + ); + + const address = os.mmap( + null, + fb.data_size, + os.PROT.READ | os.PROT.WRITE, + .{ .TYPE = os.MAP_TYPE.SHARED }, + card.file.handle, + map_dumb.offset + ); + + try cerror.from_usize(address); + + fb.data = @ptrFromInt(address); + + return fb; + } + + pub fn set(self: *Self, x: u32, y: u32, p: drm.Pixel) void { + self.data[x + self.width * y] = p; + } + + pub fn fill(self: *Self, p: drm.Pixel) void { + @memset(self.data[0..self.canvas_size], p); + } + + pub fn deinit(self: *Self) void { + cerror.from_usize( + os.munmap(@ptrCast(@volatileCast(self.data)), self.data_size) + ) catch |err| std.debug.panic("munmap failed in frame-buffer: {}", .{err}); + + self.card.request( + .remove_frame_buffer, + &self.id + ) catch @panic("failed to remove frame-buffer"); + + self.card.request( + .destroy_dumb, + &self.handle + ) catch @panic("failed to destroy dumb-buffer"); + } +}; diff --git a/src/screen/drm/buffer/root.zig b/src/screen/drm/buffer/root.zig new file mode 100644 index 0000000..e967d51 --- /dev/null +++ b/src/screen/drm/buffer/root.zig @@ -0,0 +1,32 @@ +const drm = @import("../root.zig"); + +pub const Buffer = struct { + const Self = @This(); + pub const Raw = @import("raw.zig").Raw; + + current: Raw, + crtc: Raw, + + pub fn init(card: *drm.Card, width: u32, height: u32, bpp: u32) !Self { + return .{ + .current = try Raw.init(card, width, height, bpp), + .crtc = try Raw.init(card, width, height, bpp), + }; + } + + pub fn swap(self: *Self) void { + const data = self.current.data; + self.current.data = self.crtc.data; + self.crtc.data = data; + + const id = self.current.id; + self.current.id = self.crtc.id; + self.crtc.id = id; + } + + pub fn deinit(self: *Self) void { + self.current.deinit(); + self.crtc.deinit(); + } +}; + |