aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-03-20 17:26:37 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-21 11:59:43 +0000
commitaf29924b20c7f4f5ad04f3444d4fd5f75794fef1 (patch)
treeea015206393ecc657e50cbe76710760ff422986d
parentwrap Texture in Source (diff)
downloadglsl-view-af29924b20c7f4f5ad04f3444d4fd5f75794fef1.tar.gz
glsl-view-af29924b20c7f4f5ad04f3444d4fd5f75794fef1.zip
add texture-share-vk Source
-rw-r--r--src/c.zig1
-rw-r--r--src/control.zig37
-rw-r--r--src/gl.zig1
-rw-r--r--src/tsv.zig103
4 files changed, 123 insertions, 19 deletions
diff --git a/src/c.zig b/src/c.zig
index 944cfc8..ca8e029 100644
--- a/src/c.zig
+++ b/src/c.zig
@@ -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;
diff --git a/src/gl.zig b/src/gl.zig
index 64a4c20..baf5a8f 100644
--- a/src/gl.zig
+++ b/src/gl.zig
@@ -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;
}