diff options
Diffstat (limited to 'src/tsv.zig')
| -rw-r--r-- | src/tsv.zig | 103 |
1 files changed, 91 insertions, 12 deletions
diff --git a/src/tsv.zig b/src/tsv.zig index 9f15f2f..33c8c92 100644 --- a/src/tsv.zig +++ b/src/tsv.zig @@ -1,8 +1,96 @@ const std = @import("std"); const c = @import("c.zig"); const gl = @import("gl.zig"); +const Source = gl.Source; const Output = @import("output.zig").Output; +var global_client: ?*c.GlClient = null; + +fn get_or_init_client() *c.GlClient { + if (global_client == null) { + _ = c.gl_client_initialize_external_gl(); + global_client = c.gl_client_new_with_server_launch( + c.VK_SERVER_DEFAULT_SOCKET_PATH, + 1000, + c.VK_SERVER_EXECUTABLE, + c.VK_SERVER_DEFAULT_LOCKFILE_PATH, + c.VK_SERVER_DEFAULT_SOCKET_PATH, + c.VK_SERVER_DEFAULT_SHMEM_PREFIX, + 2000, + 2000, + 2000, + 2000, + 2000, + ) orelse unreachable; + } + + return global_client.?; +} + +pub const TSVSource = struct { + source: gl.Source, + name: [:0]const u8, + + pub fn init( + allocator: std.mem.Allocator, + name: [*:0]const u8, + texture_type: gl.Texture.Type, + ) !*gl.Source { + const self = try allocator.create(TSVSource); + errdefer allocator.destroy(self); + + self.* = .{ + .source = .{ + .texture = gl.Texture.create(texture_type), + + .update_fn = update, + .deinit_fn = deinit, + }, + .name = try allocator.dupeZ(u8, std.mem.span(name)), + }; + errdefer allocator.free(self.name); + + const guard = c.gl_client_find_image_data(get_or_init_client(), name, false) orelse return error.notFound; + defer c.gl_client_image_data_guard_destroy(guard); + + const metadata = c.gl_client_image_data_guard_read(guard) orelse return error.tsvError; + self.source.texture.allocate( + @intCast(metadata.*.width), + @intCast(metadata.*.height), + 0, + c.GL_RGBA8, + ); + + self.source.update(); + + return &self.source; + } + + fn deinit(source: *const gl.Source, allocator: std.mem.Allocator) void { + const self: *const TSVSource = @fieldParentPtr("source", source); + + allocator.free(self.name); + allocator.destroy(self); + } + + fn update(source: *const gl.Source) void { + const self: *const TSVSource = @fieldParentPtr("source", source); + + var fbo: c.GLint = undefined; + c.glGetIntegerv(c.GL_DRAW_FRAMEBUFFER_BINDING, &fbo); + + _ = c.gl_client_recv_image( + get_or_init_client(), + self.name.ptr, + self.source.texture.id, + @intFromEnum(self.source.texture.type), + false, + @intCast(fbo), + null, + ); + } +}; + pub const TSVOutput = struct { pub const Config = struct { name: [:0]const u8, @@ -18,23 +106,16 @@ pub const TSVOutput = struct { ) *Output { const self = allocator.create(TSVOutput) catch unreachable; - _ = c.gl_client_initialize_external_gl() or unreachable; - self.* = .{ .output = .{ .update_fn = update, .destroy_fn = destroy, }, .config = config, - .client = c.gl_client_new(c.VK_SERVER_DEFAULT_SOCKET_PATH, 1000) orelse unreachable, - .image_size = .{ - .top_left = .{ 0, 0 }, - .bottom_right = .{ constants.config.width, constants.config.height }, - }, }; _ = c.gl_client_init_image( - self.client, + get_or_init_client(), config.name, @intCast(constants.config.width), @intCast(constants.config.height), @@ -48,8 +129,6 @@ pub const TSVOutput = struct { output: Output, config: *const Config, - client: *c.GlClient, - image_size: c.GlImageExtent, fn update(output: *Output, texture_id: c.GLuint) bool { const self: *TSVOutput = @fieldParentPtr("output", output); @@ -58,13 +137,13 @@ pub const TSVOutput = struct { c.glGetIntegerv(c.GL_DRAW_FRAMEBUFFER_BINDING, &fbo); _ = c.gl_client_send_image( - self.client, + get_or_init_client(), self.config.name, texture_id, c.GL_TEXTURE_2D, false, @intCast(fbo), - &self.image_size, + null, ); return false; } |
