aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-09-06 13:17:17 +0200
committerdec05eba <dec05eba@protonmail.com>2024-09-06 13:17:17 +0200
commit0f289b58bbd4a81f1d0288e89b5fef70719141a2 (patch)
tree59f5515c1f67f71f2cd269ea2c969c82ae2f037a
parentf756d5a0a72602a8f3d220a800fdfac20303d66a (diff)
Portal: fix external texture glitches
-rw-r--r--include/egl.h1
-rw-r--r--src/capture/portal.c33
-rw-r--r--src/egl.c1
3 files changed, 34 insertions, 1 deletions
diff --git a/include/egl.h b/include/egl.h
index e54f23d..f7f7209 100644
--- a/include/egl.h
+++ b/include/egl.h
@@ -266,6 +266,7 @@ struct gsr_egl {
void (*glTexParameteriv)(unsigned int target, unsigned int pname, const int *params);
void (*glGetTexLevelParameteriv)(unsigned int target, int level, unsigned int pname, int *params);
void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels);
+ void (*glCopyImageSubData)(unsigned int srcName, unsigned int srcTarget, int srcLevel, int srcX, int srcY, int srcZ, unsigned int dstName, unsigned int dstTarget, int dstLevel, int dstX, int dstY, int dstZ, int srcWidth, int srcHeight, int srcDepth);
void (*glGetTexImage)(unsigned int target, int level, unsigned int format, unsigned int type, void *pixels);
void (*glGenFramebuffers)(int n, unsigned int *framebuffers);
void (*glBindFramebuffer)(unsigned int target, unsigned int framebuffer);
diff --git a/src/capture/portal.c b/src/capture/portal.c
index 7d50c0a..9b4ded7 100644
--- a/src/capture/portal.c
+++ b/src/capture/portal.c
@@ -16,6 +16,7 @@ typedef struct {
gsr_capture_portal_params params;
gsr_texture_map texture_map;
+ unsigned int external_intermediate_texture;
gsr_dbus dbus;
char *session_handle;
@@ -47,6 +48,11 @@ static void gsr_capture_portal_stop(gsr_capture_portal *self) {
self->texture_map.external_texture_id = 0;
}
+ if(self->external_intermediate_texture) {
+ self->params.egl->glDeleteTextures(1, &self->external_intermediate_texture);
+ self->external_intermediate_texture = 0;
+ }
+
if(self->texture_map.cursor_texture_id) {
self->params.egl->glDeleteTextures(1, &self->texture_map.cursor_texture_id);
self->texture_map.cursor_texture_id = 0;
@@ -326,21 +332,46 @@ static int gsr_capture_portal_capture(gsr_capture *cap, AVFrame *frame, gsr_colo
gsr_pipewire_region region = {0, 0, 0, 0};
gsr_pipewire_region cursor_region = {0, 0, 0, 0};
bool using_external_image = false;
+ bool resized = false;
if(gsr_pipewire_map_texture(&self->pipewire, self->texture_map, &region, &cursor_region, self->plane_fds, &self->num_plane_fds, &using_external_image)) {
if(region.width != self->capture_size.x || region.height != self->capture_size.y) {
gsr_color_conversion_clear(color_conversion);
self->capture_size.x = region.width;
self->capture_size.y = region.height;
+ resized = true;
}
}
self->params.egl->glFlush();
self->params.egl->glFinish();
+
+ if(using_external_image && (self->external_intermediate_texture == 0 || resized)) {
+ int internal_image_format = gl_texture_get_internal_image_format(self->params.egl, self->texture_map.external_texture_id);
+ if(internal_image_format == 0)
+ internal_image_format = GL_RGBA8;
+
+ if(self->external_intermediate_texture == 0)
+ self->params.egl->glGenTextures(1, &self->external_intermediate_texture);
+ self->params.egl->glBindTexture(GL_TEXTURE_2D, self->external_intermediate_texture);
+ self->params.egl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, self->capture_size.x, self->capture_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ self->params.egl->glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ /* The image glitches a lot unless this is done. TODO: Find a proper solution */
+ if(using_external_image) {
+ self->params.egl->glCopyImageSubData(self->texture_map.external_texture_id, GL_TEXTURE_EXTERNAL_OES, 0, 0, 0, 0,
+ self->external_intermediate_texture, GL_TEXTURE_2D, 0, 0, 0, 0,
+ self->capture_size.x, self->capture_size.y, 1);
+ }
const int target_x = max_int(0, frame->width / 2 - self->capture_size.x / 2);
const int target_y = max_int(0, frame->height / 2 - self->capture_size.y / 2);
- gsr_color_conversion_draw(color_conversion, using_external_image ? self->texture_map.external_texture_id : self->texture_map.texture_id,
+ gsr_color_conversion_draw(color_conversion, using_external_image ? self->external_intermediate_texture : self->texture_map.texture_id,
(vec2i){target_x, target_y}, self->capture_size,
(vec2i){region.x, region.y}, self->capture_size,
0.0f, false);
diff --git a/src/egl.c b/src/egl.c
index d97ff0f..a1f23eb 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -445,6 +445,7 @@ static bool gsr_egl_load_gl(gsr_egl *self, void *library) {
{ (void**)&self->glTexParameteriv, "glTexParameteriv" },
{ (void**)&self->glGetTexLevelParameteriv, "glGetTexLevelParameteriv" },
{ (void**)&self->glTexImage2D, "glTexImage2D" },
+ { (void**)&self->glCopyImageSubData, "glCopyImageSubData" },
{ (void**)&self->glGetTexImage, "glGetTexImage" },
{ (void**)&self->glGenFramebuffers, "glGenFramebuffers" },
{ (void**)&self->glBindFramebuffer, "glBindFramebuffer" },