From eb39426b08a77563fbbe8e74320a3799663b8c47 Mon Sep 17 00:00:00 2001 From: Maxim Solovyov Date: Fri, 2 Feb 2024 23:55:29 +0300 Subject: [PATCH 1/3] backend: gl: inherit image's inner properties in the gl_image_decouple function Image decouple should keep all the image properies from the source image, so shader must be copied. And there are also some internal properties what should be inherited but wasn't. In particular this prevents images from losing their shaders when alpha is applied. Fixes #1174 --- src/backend/gl/gl_common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index 73bfea94..de1ff73a 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -1013,9 +1013,11 @@ static inline void gl_image_decouple(backend_t *base, struct backend_image *img) auto new_tex = ccalloc(1, struct gl_texture); new_tex->texture = gl_new_texture(GL_TEXTURE_2D); - new_tex->y_inverted = true; + new_tex->y_inverted = inner->y_inverted; + new_tex->has_alpha = inner->has_alpha; new_tex->height = inner->height; new_tex->width = inner->width; + new_tex->shader = inner->shader; new_tex->refcount = 1; new_tex->user_data = gd->decouple_texture_user_data(base, inner->user_data); From c73840005811ff6d2dbe3bab20d43ebbcad73a1a Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 6 Feb 2024 12:46:29 +0000 Subject: [PATCH 2/3] backend: clarify what clone_image does Signed-off-by: Yuxuan Shui --- src/backend/backend.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/backend/backend.h b/src/backend/backend.h index 5896e19d..fba17bbd 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -335,9 +335,10 @@ struct backend_operations { bool (*image_op)(backend_t *backend_data, enum image_operations op, void *image_data, const region_t *reg_op, const region_t *reg_visible, void *args); - /// Create another instance of the `image_data`. All `image_op` and - /// `set_image_property` calls on the returned image should not affect the - /// original image + /// Create another instance of the `image_data`. The newly created image + /// inherits its content and all image properties from the image being + /// cloned. All `image_op` and `set_image_property` calls on the + /// returned image should not affect the original image. void *(*clone_image)(backend_t *base, const void *image_data, const region_t *reg_visible); From 9204426caf6a80e858487772c4d24e98582173d5 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Tue, 6 Feb 2024 13:04:10 +0000 Subject: [PATCH 3/3] backend: gl: don't use present shader for decoupling Present shader optionally does dithering, but that's not needed for decoupling. Signed-off-by: Yuxuan Shui --- src/backend/gl/gl_common.c | 30 ++++++++++++++++++++---------- src/backend/gl/gl_common.h | 1 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/backend/gl/gl_common.c b/src/backend/gl/gl_common.c index de1ff73a..22c74ba5 100644 --- a/src/backend/gl/gl_common.c +++ b/src/backend/gl/gl_common.c @@ -885,24 +885,35 @@ bool gl_init(struct gl_data *gd, session_t *ps) { glUseProgram(0); gd->dithered_present = ps->o.dithered_present; + gd->dummy_prog = + gl_create_program_from_strv((const char *[]){present_vertex_shader, NULL}, + (const char *[]){dummy_frag, NULL}); + if (!gd->dummy_prog) { + log_error("Failed to create the dummy shader"); + return false; + } if (gd->dithered_present) { gd->present_prog = gl_create_program_from_strv( (const char *[]){present_vertex_shader, NULL}, (const char *[]){present_frag, dither_glsl, NULL}); } else { - gd->present_prog = gl_create_program_from_strv( - (const char *[]){present_vertex_shader, NULL}, - (const char *[]){dummy_frag, NULL}); + gd->present_prog = gd->dummy_prog; } if (!gd->present_prog) { log_error("Failed to create the present shader"); return false; } - pml = glGetUniformLocationChecked(gd->present_prog, "projection"); - glUseProgram(gd->present_prog); - glUniform1i(glGetUniformLocationChecked(gd->present_prog, "tex"), 0); + + pml = glGetUniformLocationChecked(gd->dummy_prog, "projection"); + glUseProgram(gd->dummy_prog); + glUniform1i(glGetUniformLocationChecked(gd->dummy_prog, "tex"), 0); glUniformMatrix4fv(pml, 1, false, projection_matrix[0]); - glUseProgram(0); + if (gd->present_prog != gd->dummy_prog) { + pml = glGetUniformLocationChecked(gd->present_prog, "projection"); + glUseProgram(gd->present_prog); + glUniform1i(glGetUniformLocationChecked(gd->present_prog, "tex"), 0); + glUniformMatrix4fv(pml, 1, false, projection_matrix[0]); + } gd->shadow_shader.prog = gl_create_program_from_str(present_vertex_shader, shadow_colorization_frag); @@ -912,7 +923,6 @@ bool gl_init(struct gl_data *gd, session_t *ps) { glUseProgram(gd->shadow_shader.prog); glUniform1i(glGetUniformLocationChecked(gd->shadow_shader.prog, "tex"), 0); glUniformMatrix4fv(pml, 1, false, projection_matrix[0]); - glUseProgram(0); glBindFragDataLocation(gd->shadow_shader.prog, 0, "out_color"); gd->brightness_shader.prog = @@ -925,6 +935,7 @@ bool gl_init(struct gl_data *gd, session_t *ps) { glUseProgram(gd->brightness_shader.prog); glUniform1i(glGetUniformLocationChecked(gd->brightness_shader.prog, "tex"), 0); glUniformMatrix4fv(pml, 1, false, projection_matrix[0]); + glUseProgram(0); // Set up the size and format of the back texture @@ -1026,8 +1037,7 @@ static inline void gl_image_decouple(backend_t *base, struct backend_image *img) GL_BGRA, GL_UNSIGNED_BYTE, NULL); glBindTexture(GL_TEXTURE_2D, 0); - assert(gd->present_prog); - glUseProgram(gd->present_prog); + glUseProgram(gd->dummy_prog); glBindTexture(GL_TEXTURE_2D, inner->texture); GLuint fbo; diff --git a/src/backend/gl/gl_common.h b/src/backend/gl/gl_common.h index a1f396b8..cacee38a 100644 --- a/src/backend/gl/gl_common.h +++ b/src/backend/gl/gl_common.h @@ -112,6 +112,7 @@ struct gl_data { GLuint frame_timing[2]; int current_frame_timing; GLuint present_prog; + GLuint dummy_prog; bool dithered_present;