aboutsummaryrefslogtreecommitdiffstats
path: root/texture_share_vk.lua
diff options
context:
space:
mode:
Diffstat (limited to 'texture_share_vk.lua')
-rw-r--r--texture_share_vk.lua172
1 files changed, 172 insertions, 0 deletions
diff --git a/texture_share_vk.lua b/texture_share_vk.lua
new file mode 100644
index 0000000..b8e2523
--- /dev/null
+++ b/texture_share_vk.lua
@@ -0,0 +1,172 @@
+local ffi = require 'ffi'
+
+ffi.cdef [[
+// GL/gl.h
+typedef int GLint;
+typedef unsigned int GLuint;
+typedef unsigned int GLenum;
+
+void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params);
+
+// texture_share_ipc/texture_share_ipc.h
+typedef enum ImgFormat {
+ R8G8B8A8,
+ R8G8B8,
+ B8G8R8A8,
+ B8G8R8,
+ Undefined,
+} ImgFormat;
+
+// texture_share_gl_client/texture_share_gl_client.h
+typedef enum ImageLookupResult {
+ Error = -1,
+ NotFound = 0,
+ Found = 1,
+ RequiresUpdate = 2,
+} ImageLookupResult;
+
+typedef struct ClientImageDataGuard ClientImageDataGuard;
+
+typedef struct GlClient GlClient;
+
+typedef struct GlImageExtent {
+ GLint top_left[2];
+ GLint bottom_right[2];
+} GlImageExtent;
+
+bool gl_client_initialize_external_gl(void);
+
+struct GlClient *gl_client_new(const char *socket_path, uint64_t timeout_in_millis);
+struct GlClient *gl_client_new_with_server_launch(const char *socket_path,
+ uint64_t client_timeout_in_millis,
+ const char *server_program,
+ const char *server_lock_path,
+ const char *server_socket_path,
+ const char *shmem_prefix,
+ uint64_t server_socket_timeout_in_millis,
+ uint64_t server_connection_wait_timeout_in_millis,
+ uint64_t server_ipc_timeout_in_millis,
+ uint64_t server_lockfile_timeout_in_millis,
+ uint64_t server_spawn_timeout_in_millis);
+
+void gl_client_destroy(struct GlClient *gl_client);
+
+enum ImageLookupResult gl_client_init_image(struct GlClient *gl_client,
+ const char *image_name,
+ uint32_t width,
+ uint32_t height,
+ ImgFormat format,
+ bool overwrite_existing);
+
+int gl_client_send_image(struct GlClient *gl_client,
+ const char *image_name,
+ GLuint src_texture_id,
+ GLenum src_texture_target,
+ bool invert,
+ GLuint prev_fbo,
+ const struct GlImageExtent *extents);
+]]
+
+-- from texture_share_vk/config.h
+local VK_SERVER_EXECUTABLE = "/usr/bin/texture-share-vk-server"
+local VK_SERVER_DEFAULT_LOCKFILE_PATH = "/tmp/vk_server/vk_server.lock"
+local VK_SERVER_DEFAULT_SOCKET_PATH = "/tmp/vk_server/vk_server.sock"
+local VK_SERVER_DEFAULT_SHMEM_PREFIX = "shmem_img_"
+
+-- from GL/gl.h
+local GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1
+local GL_COLOR_ATTACHMENT0 = 0x8CE0
+local GL_FRAMEBUFFER = 0x8D40
+local GL_TEXTURE_2D = 0x0DE1
+
+local IMAGE_FORMATS = {
+ rgba8 = ffi.C.R8G8B8A8,
+ rgb8 = ffi.C.R8G8B8,
+}
+
+local tvs = ffi.load("texture_share_gl_client")
+local gl = ffi.load("GL")
+
+local Client, Canvas = {}, {}
+Client.__index = Client
+
+function Client.new()
+ assert(tvs.gl_client_initialize_external_gl(), "failed to init tsv OpenGL")
+ local client = assert(tvs.gl_client_new_with_server_launch(
+ VK_SERVER_DEFAULT_SOCKET_PATH,
+ 1000,
+ VK_SERVER_EXECUTABLE,
+ VK_SERVER_DEFAULT_LOCKFILE_PATH,
+ VK_SERVER_DEFAULT_SOCKET_PATH,
+ VK_SERVER_DEFAULT_SHMEM_PREFIX,
+ 2000,
+ 2000,
+ 2000,
+ 2000,
+ 2000
+ ), "failed to connect or launch tsv server")
+
+ return setmetatable({ client = client }, Client)
+end
+
+function Client:newSharedCanvas(name, ...)
+ local canvas = love.graphics.newCanvas(...)
+ local width, height = canvas:getDimensions()
+ local format = assert(IMAGE_FORMATS[canvas:getFormat()], "unsupported Texture format")
+ assert(
+ tvs.gl_client_init_image(self.client, name, width, height, format, true) > 0,
+ "failed to init image"
+ )
+
+ local last_canvas = love.graphics.getCanvas()
+ love.graphics.setCanvas(canvas)
+
+ local name_ptr = ffi.typeof('GLint[1]')()
+ gl.glGetFramebufferAttachmentParameteriv(
+ GL_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ name_ptr
+ )
+ love.graphics.setCanvas(last_canvas)
+
+ return setmetatable({
+ name = name,
+ canvas = canvas,
+ client = self,
+ texture_id = name_ptr[0]
+ }, Canvas)
+end
+
+function Client:__gc()
+ tvs.gl_client_destroy(self)
+end
+
+function Canvas:send()
+ tvs.gl_client_send_image(
+ self.client.client,
+ self.name,
+ self.texture_id,
+ GL_TEXTURE_2D,
+ false,
+ 0,
+ nil
+ )
+end
+
+function Canvas:__index(key)
+ local val = Canvas[key]
+ if val then return val end
+
+ val = self.canvas[key]
+ if val then
+ Canvas[key] = function (shared, ...)
+ return val(shared.canvas, ...)
+ end
+
+ return Canvas[key]
+ end
+end
+
+return Client