diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-03-24 21:31:31 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-03-24 21:31:31 +0000 |
| commit | 3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7 (patch) | |
| tree | fa7695ea8a22de5717895c7509c26569538869fb | |
| parent | release 0.1.0 (diff) | |
| download | lua-texture-share-vk-3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7.tar.gz lua-texture-share-vk-3b1f59cc8328bd7c24ee5ae2d29a13fe1f6758d7.zip | |
support receiving canvas
| -rw-r--r-- | README.md | 4 | ||||
| l--------- | example/texture-share-vk.lua | 1 | ||||
| -rw-r--r-- | examples/recv/main.lua | 17 | ||||
| l--------- | examples/recv/texture-share-vk.lua | 1 | ||||
| -rw-r--r-- | examples/send/main.lua (renamed from example/main.lua) | 0 | ||||
| l--------- | examples/send/texture-share-vk.lua | 1 | ||||
| -rw-r--r-- | texture-share-vk.lua | 82 |
7 files changed, 102 insertions, 4 deletions
@@ -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, |
