Skip to content

Commit

Permalink
add AutoMemPool
Browse files Browse the repository at this point in the history
  • Loading branch information
psnszsn committed Aug 19, 2024
1 parent fd8968f commit 951c2d6
Show file tree
Hide file tree
Showing 11 changed files with 406 additions and 184 deletions.
15 changes: 14 additions & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub fn build(b: *std.Build) void {
});
_ = toolkit; // autofix

inline for (.{ "globals", "seats", "hello", "kb_grab" }) |example| {
inline for (.{ "globals", "seats", "hello", "kb_grab", "animation" }) |example| {
const exe = b.addExecutable(.{
.name = example,
.root_source_file = b.path("wayland/examples/" ++ example ++ ".zig"),
Expand All @@ -46,4 +46,17 @@ pub fn build(b: *std.Build) void {
const run_step = b.step("run-" ++ example, "Run the app");
run_step.dependOn(&run_cmd.step);
}
{
const unit_tests = b.addTest(.{
.root_source_file = b.path("wayland/lib.zig"),
.target = target,
.optimize = optimize,
});
unit_tests.root_module.addImport("wayland", wayland);
unit_tests.root_module.addImport("xev", libxev);

const run_unit_tests = b.addRunArtifact(unit_tests);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&run_unit_tests.step);
}
}
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.dependencies = .{
.libxev = .{
.url = "https://github.com/mitchellh/libxev/archive/main.tar.gz",
.hash = "1220b644b45718a869b37bc37bbc476e69922b21090003b38c1b68a7218fc365771a",
.hash = "1220aec83b6367c6bc64ca781828e0ad817fb38e7fca7331bd6d736b6896910f6637",
},
},
}
2 changes: 1 addition & 1 deletion toolkit/App.zig
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub fn new_common(app: *App, root_widget: WidgetIdx) !*Surface {
.size = size,
.last_frame = 0,
.root = root_widget,
.pool = try wlnd.shm.Pool.init(client, app.shm.?, size.width, size.height),
.pool = try wlnd.shm.AutoMemPool.init(client, app.shm.?),
};

return surf;
Expand Down
10 changes: 5 additions & 5 deletions toolkit/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ min_size: Size,
last_frame: u32,
frame_done: bool = true,
initial_draw: bool = false,
pool: shm.Pool = undefined,
pool: shm.AutoMemPool = undefined,

pub const SurfaceRole = enum {
xdg_toplevel,
Expand Down Expand Up @@ -176,20 +176,20 @@ pub fn draw(self: *Surface) void {
// std.log.info("draw {}", .{std.meta.activeTag(self.role)});
const client = self.app.client;
const size = self.app.layout.get(self.root, .rect).get_size();
const buf = self.pool.get_buffer(client, size.width, size.height);
const buf = self.pool.buffer(client, size.width, size.height);
if (size.contains(self.min_size)) {
const ctx = PaintCtx{
.buffer = @ptrCast(std.mem.bytesAsSlice(u32, self.pool.mmap)),
.buffer = @ptrCast(std.mem.bytesAsSlice(u32, buf.mem())),
//TODO: use ptrCast directly when implemented in zig
// .buffer = @ptrCast(buf.pool.mmap),
.width = buf.width,
.height = buf.height,
.clip = size.to_rect(),
};
@memset(self.pool.mmap, 155);
@memset(buf.mem(), 155);
self.draw_root_widget(ctx);
} else {
@memset(self.pool.mmap, 200);
@memset(buf.mem(), 200);
}
client.request(self.wl_surface, .attach, .{ .buffer = buf.wl_buffer, .x = 0, .y = 0 });
// client.request(self.wl_surface, .offset, .{ .x = 220, .y = 220 });
Expand Down
1 change: 0 additions & 1 deletion toolkit/widgets/Scrollable.zig
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ pub fn handle_event(layout: *Layout, idx: WidgetIdx, event: tk.Event) void {
c.button.pos = wpos;
break :b c;
} else ev;
std.log.info("asdf", .{});
_ = layout.call(
idxx,
.handle_event,
Expand Down
14 changes: 7 additions & 7 deletions wayland/cmsghdr.zig
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ pub fn Cmsghdr(comptime T: type) type {
};
}

test {
std.testing.refAllDecls(Cmsghdr([3]std.os.fd_t));
}
// test {
// std.testing.refAllDecls(Cmsghdr([3]std.os.fd_t));
// }

test "sendmsg" {
const os = std.os;
const os = std.posix;
var address_server = try std.net.Address.parseIp4("127.0.0.1", 0);

// const fd = try std.os.socket(os.linux.AF.UNIX, os.linux.SOCK.STREAM, 0);
Expand All @@ -75,7 +75,7 @@ test "sendmsg" {
defer os.close(client);
const buffer_send = [_]u8{42} ** 128;
const iovecs_send = [_]os.iovec_const{
os.iovec_const{ .iov_base = &buffer_send, .iov_len = buffer_send.len },
os.iovec_const{ .base = &buffer_send, .len = buffer_send.len },
};
const msg_send = os.msghdr_const{
.name = &address_server.any,
Expand All @@ -90,7 +90,7 @@ test "sendmsg" {

var buffer_recv = [_]u8{0} ** 128;
var iovecs_recv = [_]os.iovec{
os.iovec{ .iov_base = &buffer_recv, .iov_len = buffer_recv.len },
os.iovec{ .base = &buffer_recv, .len = buffer_recv.len },
};
const addr = [_]u8{0} ** 4;
var address_recv = std.net.Address.initIp4(addr, 0);
Expand All @@ -103,7 +103,7 @@ test "sendmsg" {
.controllen = 0,
.flags = 0,
};
const sqe_recvmsg = os.linux.recvmsg(server, &msg_recv, 0);
const sqe_recvmsg = std.os.linux.recvmsg(server, &msg_recv, 0);

try std.testing.expectEqual(buffer_send.len, sqe_sendmsg);
try std.testing.expectEqual(buffer_recv.len, sqe_recvmsg);
Expand Down
193 changes: 193 additions & 0 deletions wayland/examples/animation.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
pub const std_options = std.Options{
.log_level = .info,
};

const App = struct {
shm: ?wl.Shm,
compositor: ?wl.Compositor,
wm_base: ?xdg.WmBase,
running: bool = true,
};

const SurfaceCtx = struct {
ctx: *App,
wl_surface: wl.Surface,
xdg_surface: xdg.Surface,
xdg_toplevel: xdg.Toplevel,
width: u31,
height: u31,
offset: f32,
last_frame: u32,
};

pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const allocator = gpa.allocator();

const client = try wayland.Client.connect(allocator);
const registry = client.request(client.wl_display, .get_registry, .{});

var context = App{
.shm = null,
.compositor = null,
.wm_base = null,
};

client.set_listener(registry, *App, registryListener, &context);
try client.roundtrip();

const compositor = context.compositor orelse return error.NoWlCompositor;
const wm_base = context.wm_base orelse return error.NoXdgWmBase;

var surface: SurfaceCtx = b: {
const wl_surface = client.request(compositor, .create_surface, .{});
const xdg_surface = client.request(wm_base, .get_xdg_surface, .{ .surface = wl_surface });
const xdg_toplevel = client.request(xdg_surface, .get_toplevel, .{});

client.request(xdg_toplevel, .set_min_size, .{ .width = 500, .height = 200 });
client.request(xdg_toplevel, .set_title, .{ .title = "Demo" });

client.request(wl_surface, .commit, {});

break :b .{
.xdg_surface = xdg_surface,
.xdg_toplevel = xdg_toplevel,
.wl_surface = wl_surface,
.width = 100,
.height = 100,
.last_frame = 0,
.offset = 0,
.ctx = &context,
};
};
defer client.request(surface.wl_surface, .destroy, {});
defer client.request(surface.xdg_toplevel, .destroy, {});
defer client.request(surface.xdg_surface, .destroy, {});

client.set_listener(surface.xdg_surface, *SurfaceCtx, xdg_surface_listener, &surface);
client.set_listener(surface.xdg_toplevel, *SurfaceCtx, xdg_toplevel_listener, &surface);
try client.roundtrip();

const buf = try Buffer.get(client, surface.ctx.shm.?, surface.width, surface.height);
client.request(surface.wl_surface, .attach, .{ .buffer = buf.wl_buffer, .x = 0, .y = 0 });

client.request(surface.wl_surface, .commit, {});
try client.roundtrip();

const frame_cb = client.request(surface.wl_surface, .frame, .{});
client.set_listener(frame_cb, *SurfaceCtx, frame_listener, &surface);
client.request(surface.wl_surface, .commit, {});

try client.recvEvents();
}

fn registryListener(client: *wayland.Client, registry: wl.Registry, event: wl.Registry.Event, context: *App) void {
switch (event) {
.global => |global| {
if (mem.orderZ(u8, global.interface, wl.Compositor.interface.name) == .eq) {
context.compositor = client.bind(registry, global.name, wl.Compositor, 1);
} else if (mem.orderZ(u8, global.interface, wl.Shm.interface.name) == .eq) {
context.shm = client.bind(registry, global.name, wl.Shm, 1);
} else if (mem.orderZ(u8, global.interface, xdg.WmBase.interface.name) == .eq) {
context.wm_base = client.bind(registry, global.name, xdg.WmBase, 1);
}
},
.global_remove => {},
}
}

const palette = [_]u32{ 0xff1a1c2c, 0xff5d275d, 0xffb13e53, 0xffef7d57, 0xffffcd75, 0xffa7f070, 0xff38b764, 0xff257179, 0xff29366f, 0xff3b5dc9, 0xff41a6f6, 0xff73eff7, 0xfff4f4f4, 0xff94b0c2, 0xff566c86, 0xff333c57 };

fn draw(buf: []align(32) u8, width: u32, height: u32, _offset: f32) void {
const data_u32: []u32 = std.mem.bytesAsSlice(u32, buf);

const sin = std.math.sin;
for (0..height) |y| {
for (0..width) |x| {
const x_f: f32, const y_f: f32 = .{ @floatFromInt(x), @floatFromInt(y) };
const c = sin(x_f / 80) + sin(y_f / 80) + sin(_offset / 80);
const index: i64 = @intFromFloat(c * 4);
data_u32[y * width + x] = palette[@abs(index) % 16];
}
}
}

fn draw2(buf: []align(4096) u8, width: u32, height: u32, _offset: f32) void {
const offset_int: u32 = @intFromFloat(_offset);
const offset = offset_int % 8;
const data_u32: []u32 = std.mem.bytesAsSlice(u32, buf);
for (0..height) |y| {
for (0..width) |x| {
if (((x + offset) + (y + offset) / 8 * 8) % 16 < 8) {
// if ((x + y / 8 * 8) % 16 < 8) {
data_u32[y * width + x] = 0xFF666666;
} else {
data_u32[y * width + x] = 0xFFEEEEEE;
}
}
}
}

fn xdg_surface_listener(client: *wayland.Client, xdg_surface: xdg.Surface, event: xdg.Surface.Event, surf: *SurfaceCtx) void {
_ = surf;
switch (event) {
.configure => |configure| {
client.request(xdg_surface, .ack_configure, .{ .serial = configure.serial });
},
}
}

fn xdg_toplevel_listener(_: *wayland.Client, _: xdg.Toplevel, event: xdg.Toplevel.Event, surf: *SurfaceCtx) void {
switch (event) {
.configure => |configure| {
std.log.warn("new size {} {}", .{ configure.width, configure.height });
surf.width = @intCast(configure.width);
surf.height = @intCast(configure.height);
},
.close => {
surf.ctx.running = false;
},
else => {},
}
}

fn frame_listener(client: *wayland.Client, cb: wl.Callback, event: wl.Callback.Event, surf: *SurfaceCtx) void {
_ = cb;
switch (event) {
.done => |done| {
const time = done.callback_data;
defer surf.last_frame = time;

const frame_cb = client.request(surf.wl_surface, .frame, .{});

client.set_listener(frame_cb, *SurfaceCtx, frame_listener, surf);

if (surf.last_frame != 0) {
const elapsed: f32 = @floatFromInt(time - surf.last_frame);
surf.offset += elapsed / 1000.0 * 24;
}

defer client.request(surf.wl_surface, .commit, {});

const buf = Buffer.get(client, surf.ctx.shm.?, surf.width, surf.height) catch return;
draw(buf.mem(), surf.width, surf.height, surf.offset);
client.request(surf.wl_surface, .attach, .{ .buffer = buf.wl_buffer, .x = 0, .y = 0 });
client.request(surf.wl_surface, .damage, .{
.x = 0,
.y = 0,
.width = std.math.maxInt(i32),
.height = std.math.maxInt(i32),
});
},
}
}

const std = @import("std");
const mem = std.mem;

const wayland = @import("wayland");
const wl = wayland.wl;
const xdg = wayland.xdg;

const Buffer = wayland.shm.Buffer;
Loading

0 comments on commit 951c2d6

Please sign in to comment.