diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-03-20 17:26:37 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-21 11:59:43 +0000 |
| commit | af29924b20c7f4f5ad04f3444d4fd5f75794fef1 (patch) | |
| tree | ea015206393ecc657e50cbe76710760ff422986d | |
| parent | wrap Texture in Source (diff) | |
| download | glsl-view-af29924b20c7f4f5ad04f3444d4fd5f75794fef1.tar.gz glsl-view-af29924b20c7f4f5ad04f3444d4fd5f75794fef1.zip | |
add texture-share-vk Source
| -rw-r--r-- | src/c.zig | 1 | ||||
| -rw-r--r-- | src/control.zig | 37 | ||||
| -rw-r--r-- | src/gl.zig | 1 | ||||
| -rw-r--r-- | src/tsv.zig | 103 |
4 files changed, 123 insertions, 19 deletions
@@ -17,6 +17,5 @@ pub usingnamespace @cImport({ if (build_config.have_tsv) { @cInclude("texture_share_gl/texture_share_gl_client.h"); - @cInclude("texture_share_vk/config.hpp"); } }); diff --git a/src/control.zig b/src/control.zig index d36ce01..ed2531e 100644 --- a/src/control.zig +++ b/src/control.zig @@ -165,7 +165,12 @@ pub const ControlServer = struct { // _ = c.lo_server_add_method(self.server, "/reload", "", handle_reload, @as(*anyopaque, @ptrCast(self))); _ = c.lo_server_add_method(self.server, "/uniform/*", null, wrapCallback(handle_uniform), @as(*anyopaque, @ptrCast(self))); - _ = c.lo_server_add_method(self.server, "/texture/*", "ss", wrapCallback(handle_load_texture), @as(*anyopaque, @ptrCast(self))); + if (build_config.have_ffmpeg) { + _ = c.lo_server_add_method(self.server, "/texture/*/video", "ss", wrapCallback(handle_texture_video), @as(*anyopaque, @ptrCast(self))); + } + if (build_config.have_tsv) { + _ = c.lo_server_add_method(self.server, "/texture/*/tsv", "ss", wrapCallback(handle_texture_tsv), @as(*anyopaque, @ptrCast(self))); + } _ = c.lo_server_add_method(self.server, "/texture/*/destroy", "", wrapCallback(handle_destroy_texture), @as(*anyopaque, @ptrCast(self))); return self; @@ -300,10 +305,29 @@ pub const ControlServer = struct { return true; } - fn handle_load_texture(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { - if (!build_config.have_ffmpeg) return error.supportDisabled; + fn handle_texture_video(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { + _ = types; + + var parts = std.mem.tokenizeScalar(u8, path, '/'); + _ = parts.next(); + const name = parts.next() orelse unreachable; + if (self.cache.textures.contains(name)) return error.textureNameTaken; + + const texture_typeZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); + const texture_type = std.meta.stringToEnum(gl.Texture.Type, std.mem.span(texture_typeZ)) orelse return error.invalidType; + const filenameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); + const ffmpeg = @import("ffmpeg.zig"); + const source = try ffmpeg.VideoSource.init(self.cache.allocator, self.progress, filenameZ, texture_type); + + const key = try self.cache.allocator.dupe(u8, name); + errdefer self.cache.allocator.free(key); + try self.cache.textures.put(key, source); + + return true; + } + fn handle_texture_tsv(self: *ControlServer, path: []const u8, types: []const u8, argv: []const [*c]c.lo_arg) !bool { _ = types; var parts = std.mem.tokenizeScalar(u8, path, '/'); @@ -313,12 +337,13 @@ pub const ControlServer = struct { const texture_typeZ: [*:0]const u8 = @ptrCast(&argv[0].*.s); const texture_type = std.meta.stringToEnum(gl.Texture.Type, std.mem.span(texture_typeZ)) orelse return error.invalidType; + const tsv_nameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); + + const tsv = @import("tsv.zig"); + const source = try tsv.TSVSource.init(self.cache.allocator, tsv_nameZ, texture_type); - const filenameZ: [*:0]const u8 = @ptrCast(&argv[1].*.s); const key = try self.cache.allocator.dupe(u8, name); errdefer self.cache.allocator.free(key); - - const source = try ffmpeg.VideoSource.init(self.cache.allocator, self.progress, filenameZ, texture_type); try self.cache.textures.put(key, source); return true; @@ -1097,6 +1097,7 @@ pub const Constants = struct { \\ \\void main() { \\ uv = position / 2.0 + 0.5; + \\ uv.y *= -1.0; \\ gl_Position = vec4(position, 0, 1); \\} , 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; } |
