mirror of
https://mzte.de/git/LordMZTE/dotfiles.git
synced 2024-06-17 18:59:45 +02:00
wlbg: only do one frame per minute
F gpu
This commit is contained in:
parent
1e04919f26
commit
7c64072005
|
@ -16,6 +16,10 @@ pub fn build(b: *std.Build) void {
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
exe.addModule("xev", b.dependency("xev", .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
}).module("xev"));
|
||||||
exe.addModule("wayland", wayland_mod);
|
exe.addModule("wayland", wayland_mod);
|
||||||
|
|
||||||
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
|
scanner.addSystemProtocol("stable/xdg-shell/xdg-shell.xml");
|
||||||
|
|
|
@ -7,5 +7,9 @@
|
||||||
.url = "https://git.mzte.de/LordMZTE/zig-wayland/archive/85722422985f928087e56d90c3617ecb04232486.tar.gz",
|
.url = "https://git.mzte.de/LordMZTE/zig-wayland/archive/85722422985f928087e56d90c3617ecb04232486.tar.gz",
|
||||||
.hash = "1220d992b223e473988d203d66d262e54141b59559c09587eb00231c800d46f9b408",
|
.hash = "1220d992b223e473988d203d66d262e54141b59559c09587eb00231c800d46f9b408",
|
||||||
},
|
},
|
||||||
|
.xev = .{
|
||||||
|
.url = "https://github.com/mitchellh/libxev/archive/5ecbc871f3bfa80fb7bf0fa853866cb93b99bc18.tar.gz",
|
||||||
|
.hash = "1220416854e424601ecc9814afb461a5dc9cf95db5917d82f794594a58ffc723b82c",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ const OutputInfo = @import("OutputInfo.zig");
|
||||||
|
|
||||||
egl_dpy: c.EGLDisplay,
|
egl_dpy: c.EGLDisplay,
|
||||||
bg_shader_program: c_uint,
|
bg_shader_program: c_uint,
|
||||||
time: f64,
|
|
||||||
|
|
||||||
const Gfx = @This();
|
const Gfx = @This();
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ pub fn init(egl_dpy: c.EGLDisplay) !Gfx {
|
||||||
return .{
|
return .{
|
||||||
.egl_dpy = egl_dpy,
|
.egl_dpy = egl_dpy,
|
||||||
.bg_shader_program = program,
|
.bg_shader_program = program,
|
||||||
.time = 0.0,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,15 +38,15 @@ pub fn deinit(self: *Gfx) void {
|
||||||
self.* = undefined;
|
self.* = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub fn drawBackground(
|
||||||
self: *Gfx,
|
self: *Gfx,
|
||||||
dt: f32,
|
dt: i64,
|
||||||
egl_surface: c.EGLSurface,
|
egl_surface: c.EGLSurface,
|
||||||
info: OutputInfo,
|
info: OutputInfo,
|
||||||
base_xoff: i32,
|
base_xoff: i32,
|
||||||
base_yoff: i32,
|
base_yoff: i32,
|
||||||
) !void {
|
) !void {
|
||||||
self.time += dt;
|
_ = dt;
|
||||||
|
|
||||||
// There's just about a 0% chance this works properly when monitors have different resolutions,
|
// There's just about a 0% chance this works properly when monitors have different resolutions,
|
||||||
// but I can't even begin thinking about that.
|
// but I can't even begin thinking about that.
|
||||||
|
@ -76,9 +74,11 @@ pub fn draw(
|
||||||
c.glVertexAttribPointer(1, 2, c.GL_FLOAT, c.GL_FALSE, @sizeOf(f32) * 5, @ptrFromInt(@intFromPtr(&vertices) + @sizeOf(f32) * 3));
|
c.glVertexAttribPointer(1, 2, c.GL_FLOAT, c.GL_FALSE, @sizeOf(f32) * 5, @ptrFromInt(@intFromPtr(&vertices) + @sizeOf(f32) * 3));
|
||||||
c.glEnableVertexAttribArray(1);
|
c.glEnableVertexAttribArray(1);
|
||||||
|
|
||||||
c.glUniform1f(c.glGetUniformLocation(self.bg_shader_program, "time"), @as(f32, @floatCast(self.time / 10000.0)));
|
const rand = std.crypto.random.float(f32);
|
||||||
|
c.glUniform1f(c.glGetUniformLocation(self.bg_shader_program, "time"), rand * 2000.0 - 1000.0);
|
||||||
|
|
||||||
c.glDrawArrays(c.GL_TRIANGLES, 0, vertices.len / 3);
|
c.glDrawArrays(c.GL_TRIANGLES, 0, vertices.len / 3);
|
||||||
|
|
||||||
if (c.eglSwapBuffers(self.egl_dpy, egl_surface) != c.EGL_TRUE) return error.EGLError;
|
if (c.eglSwapInterval(self.egl_dpy, 0) != c.EGL_TRUE or
|
||||||
|
c.eglSwapBuffers(self.egl_dpy, egl_surface) != c.EGL_TRUE) return error.EGLError;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,11 @@ const wl = wayland.client.wl;
|
||||||
const zwlr = wayland.client.zwlr;
|
const zwlr = wayland.client.zwlr;
|
||||||
const zxdg = wayland.client.zxdg;
|
const zxdg = wayland.client.zxdg;
|
||||||
|
|
||||||
const fps = 10;
|
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
|
std.log.info("initializing event loop", .{});
|
||||||
|
var loop = try xev.Loop.init(.{});
|
||||||
|
defer loop.deinit();
|
||||||
|
|
||||||
std.log.info("connecting to wayland display", .{});
|
std.log.info("connecting to wayland display", .{});
|
||||||
const dpy = try wl.Display.connect(null);
|
const dpy = try wl.Display.connect(null);
|
||||||
defer dpy.disconnect();
|
defer dpy.disconnect();
|
||||||
|
@ -146,32 +148,116 @@ pub fn main() !void {
|
||||||
var gfx = try Gfx.init(egl_dpy);
|
var gfx = try Gfx.init(egl_dpy);
|
||||||
defer gfx.deinit();
|
defer gfx.deinit();
|
||||||
|
|
||||||
var timer = try std.time.Timer.start();
|
var rbgdata = RenderBackgroundData{
|
||||||
var prev_time = std.time.milliTimestamp();
|
.gfx = &gfx,
|
||||||
while (true) {
|
.egl_dpy = egl_dpy,
|
||||||
const now_time = std.time.milliTimestamp();
|
.egl_ctx = egl_ctx,
|
||||||
const delta_time: f32 = @floatFromInt(now_time - prev_time);
|
.outputs = output_windows,
|
||||||
prev_time = now_time;
|
.output_info = output_info,
|
||||||
|
.last_time = loop.now(),
|
||||||
|
.base_offset = .{ base_xoff, base_yoff },
|
||||||
|
};
|
||||||
|
|
||||||
for (output_windows, output_info) |output, info| {
|
var rbg_timer_completion: xev.Completion = undefined;
|
||||||
if (c.eglMakeCurrent(
|
var rbg_timer = try xev.Timer.init();
|
||||||
egl_dpy,
|
defer rbg_timer.deinit();
|
||||||
output.egl_surface,
|
|
||||||
output.egl_surface,
|
rbg_timer.run(
|
||||||
egl_ctx,
|
&loop,
|
||||||
) != c.EGL_TRUE) return error.EGLError;
|
&rbg_timer_completion,
|
||||||
try gfx.draw(delta_time, output.egl_surface, info, base_xoff, base_yoff);
|
0,
|
||||||
|
RenderBackgroundData,
|
||||||
|
&rbgdata,
|
||||||
|
renderBackgroundCb,
|
||||||
|
);
|
||||||
|
|
||||||
|
var wl_poll_completion = xev.Completion{
|
||||||
|
.op = .{ .poll = .{ .fd = dpy.getFd() } },
|
||||||
|
.userdata = dpy,
|
||||||
|
.callback = wlPollCb,
|
||||||
|
};
|
||||||
|
loop.add(&wl_poll_completion);
|
||||||
|
|
||||||
|
std.log.info("running event loop", .{});
|
||||||
|
try loop.run(.until_done);
|
||||||
|
}
|
||||||
|
|
||||||
|
const RenderBackgroundData = struct {
|
||||||
|
gfx: *Gfx,
|
||||||
|
egl_dpy: c.EGLDisplay,
|
||||||
|
egl_ctx: c.EGLContext,
|
||||||
|
outputs: []const OutputWindow,
|
||||||
|
output_info: []const OutputInfo,
|
||||||
|
last_time: isize,
|
||||||
|
base_offset: [2]c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn renderBackgroundCb(
|
||||||
|
data: ?*RenderBackgroundData,
|
||||||
|
loop: *xev.Loop,
|
||||||
|
completion: *xev.Completion,
|
||||||
|
result: xev.Timer.RunError!void,
|
||||||
|
) xev.CallbackAction {
|
||||||
|
result catch unreachable;
|
||||||
|
|
||||||
|
const now = loop.now();
|
||||||
|
|
||||||
|
const delta_time = now - data.?.last_time;
|
||||||
|
data.?.last_time = now;
|
||||||
|
const next_time = now + std.time.ms_per_min;
|
||||||
|
completion.op.timer.reset = .{
|
||||||
|
.tv_sec = @divTrunc(next_time, std.time.ms_per_s),
|
||||||
|
.tv_nsec = @mod(next_time, std.time.ms_per_s) * std.time.ns_per_ms,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (data.?.outputs, data.?.output_info) |output, info| {
|
||||||
|
if (c.eglMakeCurrent(
|
||||||
|
data.?.egl_dpy,
|
||||||
|
output.egl_surface,
|
||||||
|
output.egl_surface,
|
||||||
|
data.?.egl_ctx,
|
||||||
|
) != c.EGL_TRUE) {
|
||||||
|
std.log.err("failed to set EGL context", .{});
|
||||||
|
loop.stop();
|
||||||
|
return .disarm;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpy.dispatchPending() != .SUCCESS or dpy.flush() != .SUCCESS) {
|
data.?.gfx.drawBackground(
|
||||||
std.log.err("error processing wayland events", .{});
|
delta_time,
|
||||||
return error.DispatchFail;
|
output.egl_surface,
|
||||||
}
|
info,
|
||||||
|
data.?.base_offset[0],
|
||||||
const elapsed = timer.lap();
|
data.?.base_offset[1],
|
||||||
if (elapsed < 1000 * std.time.ns_per_ms / fps)
|
) catch |e| {
|
||||||
std.os.nanosleep(0, (1000 * std.time.ns_per_ms) / fps - elapsed);
|
std.log.err("drawing: {}", .{e});
|
||||||
|
loop.stop();
|
||||||
|
return .disarm;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return .rearm;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wlPollCb(
|
||||||
|
userdata: ?*anyopaque,
|
||||||
|
loop: *xev.Loop,
|
||||||
|
_: *xev.Completion,
|
||||||
|
result: xev.Result,
|
||||||
|
) xev.CallbackAction {
|
||||||
|
result.poll catch |e| {
|
||||||
|
std.log.err("unable to poll wayland FD: {}", .{e});
|
||||||
|
loop.stop();
|
||||||
|
return .disarm;
|
||||||
|
};
|
||||||
|
|
||||||
|
const dpy: *wl.Display = @ptrCast(@alignCast(userdata));
|
||||||
|
if (dpy.dispatchPending() != .SUCCESS or dpy.flush() != .SUCCESS) {
|
||||||
|
std.log.err("error processing wayland events", .{});
|
||||||
|
loop.stop();
|
||||||
|
return .disarm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .rearm;
|
||||||
}
|
}
|
||||||
|
|
||||||
const OutputWindow = struct {
|
const OutputWindow = struct {
|
||||||
|
|
Loading…
Reference in a new issue