aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2025-03-24 21:31:31 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-24 21:31:31 +0000
commit3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7 (patch)
treefa7695ea8a22de5717895c7509c26569538869fb
parentrelease 0.1.0 (diff)
downloadlua-texture-share-vk-3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7.tar.gz
lua-texture-share-vk-3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7.zip
support receiving canvas
-rw-r--r--README.md4
l---------example/texture-share-vk.lua1
-rw-r--r--examples/recv/main.lua17
l---------examples/recv/texture-share-vk.lua1
-rw-r--r--examples/send/main.lua (renamed from example/main.lua)0
l---------examples/send/texture-share-vk.lua1
-rw-r--r--texture-share-vk.lua82
7 files changed, 102 insertions, 4 deletions
diff --git a/README.md b/README.md
index c234d19..9ab89ea 100644
--- a/README.md
+++ b/README.md
@@ -2,13 +2,15 @@
A LÖVE library for sharing GPU textures between processes.
-This wraps the OpenGL C API of [texture-share-vk](https://github.com/DigitOtter/texture-share-vk) and allows publishing a LÖVE Canvas object.
+This wraps the OpenGL C API of [texture-share-vk](https://github.com/DigitOtter/texture-share-vk) and allows sending and receiving LÖVE Canvas contents.
## API
- `tvs.new()`: creates a new `Client` object (`texture-share-gl` client).
- `Client:newSharedCanvas(name, ...)`: creates a new `SharedCanvas` object by delegating to [`love.graphics.newCanvas(...)`](https://love2d.org/wiki/love.graphics.newCanvas) and publishes it.
+- `Client:loadSharedCanvas(name)`: loads a `SharedCanvas` object from another publisher.
- `Canvas.name`: the name passed in the SharedCanvas constructor
- `Canvas.canvas`: the love2d `Canvas` object
- `Canvas:send()`: Sends the current contents of the Canvas to subscribers, call this after drawing to the Canvas.
+- `Canvas:load()`: Loads updated contents from the publisher, call this before drawing the Canvas.
- `Canvas:any_other_method()`: delegated to the love2d `Canvas` object
diff --git a/example/texture-share-vk.lua b/example/texture-share-vk.lua
deleted file mode 120000
index f828f1e..0000000
--- a/example/texture-share-vk.lua
+++ /dev/null
@@ -1 +0,0 @@
-../texture-share-vk.lua \ No newline at end of file
diff --git a/examples/recv/main.lua b/examples/recv/main.lua
new file mode 100644
index 0000000..c9ebd30
--- /dev/null
+++ b/examples/recv/main.lua
@@ -0,0 +1,17 @@
+local tvs = require 'texture-share-vk'
+local client, shared
+
+function love.load()
+ client = tvs.new()
+ shared = client:loadSharedCanvas("love2d")
+
+ print(shared:getDimensions()) -- NOTE: delegated to LÖVE Canvas
+end
+
+function love.draw()
+ shared:recv()
+
+ love.graphics.reset()
+ love.graphics.setBlendMode("alpha", "premultiplied")
+ love.graphics.draw(shared.canvas) -- NOTE: different from normal canvas
+end
diff --git a/examples/recv/texture-share-vk.lua b/examples/recv/texture-share-vk.lua
new file mode 120000
index 0000000..78b332b
--- /dev/null
+++ b/examples/recv/texture-share-vk.lua
@@ -0,0 +1 @@
+../../texture-share-vk.lua \ No newline at end of file
diff --git a/example/main.lua b/examples/send/main.lua
index 4788361..4788361 100644
--- a/example/main.lua
+++ b/examples/send/main.lua
diff --git a/examples/send/texture-share-vk.lua b/examples/send/texture-share-vk.lua
new file mode 120000
index 0000000..78b332b
--- /dev/null
+++ b/examples/send/texture-share-vk.lua
@@ -0,0 +1 @@
+../../texture-share-vk.lua \ No newline at end of file
diff --git a/texture-share-vk.lua b/texture-share-vk.lua
index b8e2523..f8f9c4c 100644
--- a/texture-share-vk.lua
+++ b/texture-share-vk.lua
@@ -18,6 +18,19 @@ typedef enum ImgFormat {
Undefined,
} ImgFormat;
+typedef uint8_t ImgName[1024];
+
+typedef struct ShmemDataInternal {
+ ImgName name;
+ uint32_t handle_id;
+ uint32_t width;
+ uint32_t height;
+ enum ImgFormat format;
+ uint64_t allocation_size;
+ uint64_t gpu_device_uuid_0;
+ uint64_t gpu_device_uuid_1;
+} ShmemDataInternal;
+
// texture_share_gl_client/texture_share_gl_client.h
typedef enum ImageLookupResult {
Error = -1,
@@ -59,6 +72,18 @@ enum ImageLookupResult gl_client_init_image(struct GlClient *gl_client,
ImgFormat format,
bool overwrite_existing);
+enum ImageLookupResult gl_client_find_image(struct GlClient *gl_client,
+ const char *image_name,
+ bool force_update);
+
+struct ClientImageDataGuard *gl_client_find_image_data(struct GlClient *gl_client,
+ const char *image_name,
+ bool force_update);
+
+const ShmemDataInternal *gl_client_image_data_guard_read(const struct ClientImageDataGuard *image_data_guard);
+
+void gl_client_image_data_guard_destroy(struct ClientImageDataGuard *image_data_guard);
+
int gl_client_send_image(struct GlClient *gl_client,
const char *image_name,
GLuint src_texture_id,
@@ -66,6 +91,14 @@ int gl_client_send_image(struct GlClient *gl_client,
bool invert,
GLuint prev_fbo,
const struct GlImageExtent *extents);
+
+int gl_client_recv_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
@@ -83,6 +116,8 @@ local GL_TEXTURE_2D = 0x0DE1
local IMAGE_FORMATS = {
rgba8 = ffi.C.R8G8B8A8,
rgb8 = ffi.C.R8G8B8,
+ [ffi.C.R8G8B8A8] = "rgba8",
+ [ffi.C.R8G8B8] = "rgb8",
}
local tvs = ffi.load("texture_share_gl_client")
@@ -135,7 +170,38 @@ function Client:newSharedCanvas(name, ...)
name = name,
canvas = canvas,
client = self,
- texture_id = name_ptr[0]
+ texture_id = name_ptr[0],
+ }, Canvas)
+end
+
+function Client:loadSharedCanvas(name)
+ local guard = assert(
+ tvs.gl_client_find_image_data(self.client, name, false),
+ "failed to load image"
+ )
+
+ local data = tvs.gl_client_image_data_guard_read(guard)
+ local format = assert(IMAGE_FORMATS[tonumber(data.format)], "unsupported Texture format")
+ local canvas = love.graphics.newCanvas(data.width, data.height, { format = format })
+ tvs.gl_client_image_data_guard_destroy(guard)
+
+ 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
@@ -144,7 +210,19 @@ function Client:__gc()
end
function Canvas:send()
- tvs.gl_client_send_image(
+ return tvs.gl_client_send_image(
+ self.client.client,
+ self.name,
+ self.texture_id,
+ GL_TEXTURE_2D,
+ false,
+ 0,
+ nil
+ )
+end
+
+function Canvas:recv()
+ return tvs.gl_client_recv_image(
self.client.client,
self.name,
self.texture_id,