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"); } };