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, stride: u32, handle: u32, bytes: []volatile u8, pub fn init(card: drm.Card, width: u32, height: u32) !Self { var create_dumb = std.mem.zeroInit(drm.request.CreateDumb, .{ .width = width, .height = height, .bpp = 32, }); try card.request( .create_dumb, &create_dumb ); var fb = Self { .id = 0, .width = create_dumb.width, .height = create_dumb.height, .stride = create_dumb.pitch, .handle = create_dumb.handle, .bytes = undefined, .card = card, }; var buffer_cmd = drm.request.FrameBufferCmd2 { .id = 0, .width = fb.width, .height = fb.height, .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, create_dumb.size, os.PROT.READ | os.PROT.WRITE, .{ .TYPE = os.MAP_TYPE.SHARED }, card.file.handle, map_dumb.offset ); try cerror.from_usize(address); fb.bytes = @as([*]volatile u8, @ptrFromInt(address))[0..create_dumb.size]; return fb; } pub fn deinit(self: *Self) void { cerror.from_usize( os.munmap(@ptrCast(@volatileCast(self.bytes)), self.bytes.len) ) 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"); } };