diff options
author | dec05eba <dec05eba@protonmail.com> | 2025-06-09 22:11:16 +0200 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2025-06-09 22:11:16 +0200 |
commit | 7f00ce22e7e86904e09f900422dfa591d045f447 (patch) | |
tree | 7ba28db730298c462b3a028348b4960977e751c2 | |
parent | 3ba1dbda98fcf221eb92d241b753ccdef9eb2a08 (diff) |
Revert "Fix screen and portal capture not working on some intel gpus"
This reverts commit 3ba1dbda98fcf221eb92d241b753ccdef9eb2a08.
-rw-r--r-- | include/color_conversion.h | 2 | ||||
-rw-r--r-- | include/egl.h | 2 | ||||
-rw-r--r-- | include/pipewire_video.h | 1 | ||||
-rw-r--r-- | src/capture/kms.c | 11 | ||||
-rw-r--r-- | src/capture/portal.c | 13 | ||||
-rw-r--r-- | src/color_conversion.c | 63 | ||||
-rw-r--r-- | src/cursor.c | 4 | ||||
-rw-r--r-- | src/egl.c | 6 | ||||
-rw-r--r-- | src/encoder/video/software.c | 11 | ||||
-rw-r--r-- | src/encoder/video/vaapi.c | 7 | ||||
-rw-r--r-- | src/image_writer.c | 14 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/pipewire_video.c | 55 | ||||
-rw-r--r-- | src/utils.c | 11 | ||||
-rw-r--r-- | src/window_texture.c | 4 |
15 files changed, 94 insertions, 112 deletions
diff --git a/include/color_conversion.h b/include/color_conversion.h index cb074a1..76d8be5 100644 --- a/include/color_conversion.h +++ b/include/color_conversion.h @@ -50,7 +50,6 @@ typedef struct { gsr_color_range color_range; bool load_external_image_shader; - bool force_graphics_shader; } gsr_color_conversion_params; typedef struct { @@ -78,7 +77,6 @@ void gsr_color_conversion_deinit(gsr_color_conversion *self); void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i destination_pos, vec2i destination_size, vec2i source_pos, vec2i source_size, vec2i texture_size, gsr_rotation rotation, gsr_source_color source_color, bool external_texture, bool alpha_blending); void gsr_color_conversion_clear(gsr_color_conversion *self); -void gsr_color_conversion_read_destination_texture(gsr_color_conversion *self, int destination_texture_index, int x, int y, int width, int height, unsigned int color_format, unsigned int data_format, void *pixels); gsr_rotation gsr_monitor_rotation_to_rotation(gsr_monitor_rotation monitor_rotation); diff --git a/include/egl.h b/include/egl.h index 0b6a034..8e7496c 100644 --- a/include/egl.h +++ b/include/egl.h @@ -141,6 +141,8 @@ typedef void(*__GLXextFuncPtr)(void); #define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS 0x90EB #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 +#define GL_CLAMP_TO_BORDER 0x812D +#define GL_TEXTURE_BORDER_COLOR 0x1004 #define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020 #define GL_ALL_BARRIER_BITS 0xFFFFFFFF diff --git a/include/pipewire_video.h b/include/pipewire_video.h index b593630..92622b8 100644 --- a/include/pipewire_video.h +++ b/include/pipewire_video.h @@ -65,7 +65,6 @@ typedef struct { struct spa_video_info format; int server_version_sync; bool negotiated; - bool renegotiated; bool damaged; struct { diff --git a/src/capture/kms.c b/src/capture/kms.c index daba6bc..18858f2 100644 --- a/src/capture/kms.c +++ b/src/capture/kms.c @@ -108,14 +108,22 @@ static int max_int(int a, int b) { } static void gsr_capture_kms_create_input_texture_ids(gsr_capture_kms *self) { + const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + self->params.egl->glGenTextures(1, &self->input_texture_id); self->params.egl->glBindTexture(GL_TEXTURE_2D, self->input_texture_id); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); 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); self->params.egl->glGenTextures(1, &self->external_input_texture_id); self->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, self->external_input_texture_id); + self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BORDER_COLOR, border_color); self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); @@ -125,6 +133,9 @@ static void gsr_capture_kms_create_input_texture_ids(gsr_capture_kms *self) { self->params.egl->glGenTextures(1, &self->cursor_texture_id); self->params.egl->glBindTexture(cursor_texture_id_target, self->cursor_texture_id); + self->params.egl->glTexParameteri(cursor_texture_id_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(cursor_texture_id_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(cursor_texture_id_target, GL_TEXTURE_BORDER_COLOR, border_color); self->params.egl->glTexParameteri(cursor_texture_id_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); self->params.egl->glTexParameteri(cursor_texture_id_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->params.egl->glBindTexture(cursor_texture_id_target, 0); diff --git a/src/capture/portal.c b/src/capture/portal.c index 5dbbd40..a5e62af 100644 --- a/src/capture/portal.c +++ b/src/capture/portal.c @@ -57,20 +57,31 @@ static void gsr_capture_portal_stop(gsr_capture_portal *self) { } static void gsr_capture_portal_create_input_textures(gsr_capture_portal *self) { + const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + self->params.egl->glGenTextures(1, &self->texture_map.texture_id); self->params.egl->glBindTexture(GL_TEXTURE_2D, self->texture_map.texture_id); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); 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); self->params.egl->glGenTextures(1, &self->texture_map.external_texture_id); self->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, self->texture_map.external_texture_id); + self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_BORDER_COLOR, border_color); self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->params.egl->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); self->params.egl->glGenTextures(1, &self->texture_map.cursor_texture_id); self->params.egl->glBindTexture(GL_TEXTURE_2D, self->texture_map.cursor_texture_id); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); 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); @@ -313,7 +324,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca gsr_color_conversion_clear(color_conversion); } } else { - return -1; + return 0; } const bool is_scaled = self->params.output_resolution.x > 0 && self->params.output_resolution.y > 0; diff --git a/src/color_conversion.c b/src/color_conversion.c index 23b166e..caae0b0 100644 --- a/src/color_conversion.c +++ b/src/color_conversion.c @@ -89,13 +89,15 @@ static void get_compute_shader_header(char *header, size_t header_size, bool ext if(external_texture) { snprintf(header, header_size, "#version 310 es\n" + "#extension GL_ARB_compute_shader: enable\n" "#extension GL_OES_EGL_image_external : enable\n" "#extension GL_OES_EGL_image_external_essl3 : require\n" "layout(binding = 0) uniform highp samplerExternalOES img_input;\n" "layout(binding = 1) uniform highp sampler2D img_background;\n"); } else { snprintf(header, header_size, - "#version 310 es\n" + "#version 420\n" + "#extension GL_ARB_compute_shader: enable\n" "layout(binding = 0) uniform highp sampler2D img_input;\n" "layout(binding = 1) uniform highp sampler2D img_background;\n"); } @@ -107,7 +109,7 @@ static int load_compute_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_com char header[512]; get_compute_shader_header(header, sizeof(header), external_texture); - char compute_shader[4096]; + char compute_shader[2048]; snprintf(compute_shader, sizeof(compute_shader), "%s" "layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n" @@ -125,16 +127,12 @@ static int load_compute_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_com " ivec2 output_size = textureSize(img_background, 0);\n" " vec2 rotated_texel_coord = vec2(texel_coord - source_position - size_shift) * rotation_matrix + vec2(size_shift) + 0.5;\n" " vec2 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n" - " vec2 source_color_coords = rotated_texel_coord/vec2(size);\n" - " vec4 source_color = texture(img_input, source_color_coords);\n" - " if(source_color_coords.x > 1.0 || source_color_coords.y > 1.0)\n" - " source_color.rgba = vec4(0.0, 0.0, 0.0, %s);\n" + " vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size));\n" " vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n" " vec4 output_color_yuv = %s;\n" " float y_color = mix(output_color_yuv.r, source_color_yuv.r, source_color.a);\n" " imageStore(img_output, texel_coord + target_position, vec4(y_color, 1.0, 1.0, 1.0));\n" "}\n", header, max_local_size_dim, max_local_size_dim, color_transform_matrix, - alpha_blending ? "0.0" : "1.0", alpha_blending ? "texture(img_background, output_texel_coord/vec2(output_size))" : "source_color_yuv"); if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0) @@ -153,7 +151,7 @@ static int load_compute_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_co char header[512]; get_compute_shader_header(header, sizeof(header), external_texture); - char compute_shader[4096]; + char compute_shader[2048]; snprintf(compute_shader, sizeof(compute_shader), "%s" "layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n" @@ -171,16 +169,12 @@ static int load_compute_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_co " ivec2 output_size = textureSize(img_background, 0);\n" " vec2 rotated_texel_coord = vec2(texel_coord - source_position - size_shift) * rotation_matrix + vec2(size_shift) + 0.5;\n" " vec2 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n" - " vec2 source_color_coords = rotated_texel_coord/vec2(size>>1);\n" - " vec4 source_color = texture(img_input, source_color_coords);\n" // size/2 - " if(source_color_coords.x > 1.0 || source_color_coords.y > 1.0)\n" - " source_color.rgba = vec4(0.0, 0.0, 0.0, %s);\n" + " vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size>>1));\n" // size/2 " vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n" " vec4 output_color_yuv = %s;\n" " vec2 uv_color = mix(output_color_yuv.rg, source_color_yuv.gb, source_color.a);\n" " imageStore(img_output, texel_coord + target_position, vec4(uv_color, 1.0, 1.0));\n" "}\n", header, max_local_size_dim, max_local_size_dim, color_transform_matrix, - alpha_blending ? "0.0" : "1.0", alpha_blending ? "texture(img_background, output_texel_coord/vec2(output_size))" : "source_color_yuv"); if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0) @@ -197,11 +191,10 @@ static int load_compute_shader_rgb(gsr_shader *shader, gsr_egl *egl, gsr_color_c char header[512]; get_compute_shader_header(header, sizeof(header), external_texture); - char compute_shader[4096]; + char compute_shader[2048]; snprintf(compute_shader, sizeof(compute_shader), "%s" "layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n" - "precision highp float;\n" "uniform ivec2 source_position;\n" "uniform ivec2 target_position;\n" "uniform vec2 scale;\n" @@ -214,15 +207,11 @@ static int load_compute_shader_rgb(gsr_shader *shader, gsr_egl *egl, gsr_color_c " ivec2 output_size = textureSize(img_background, 0);\n" " vec2 rotated_texel_coord = vec2(texel_coord - source_position - size_shift) * rotation_matrix + vec2(size_shift) + 0.5;\n" " vec2 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n" - " vec2 source_color_coords = rotated_texel_coord/vec2(size);\n" - " vec4 source_color = texture(img_input, source_color_coords);\n" - " if(source_color_coords.x > 1.0 || source_color_coords.y > 1.0)\n" - " source_color.rgba = vec4(0.0, 0.0, 0.0, %s);\n" + " vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size));\n" " vec4 output_color = %s;\n" " vec3 color = mix(output_color.rgb, source_color.rgb, source_color.a);\n" " imageStore(img_output, texel_coord + target_position, vec4(color, 1.0));\n" "}\n", header, max_local_size_dim, max_local_size_dim, - alpha_blending ? "0.0" : "1.0", alpha_blending ? "texture(img_background, output_texel_coord/vec2(output_size))" : "source_color"); if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0) @@ -631,33 +620,20 @@ int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conver } } - if(self->params.force_graphics_shader) { + if(!gsr_color_conversion_load_compute_shaders(self)) { self->compute_shaders_failed_to_load = true; - self->external_compute_shaders_failed_to_load = true; - + fprintf(stderr, "gsr info: failed to load one or more compute shaders, run gpu-screen-recorder with the '-gl-debug yes' option to see why. Falling back to slower graphics shader instead\n"); if(!gsr_color_conversion_load_graphics_shaders(self)) goto err; + } - if(self->params.load_external_image_shader) { + if(self->params.load_external_image_shader) { + if(!gsr_color_conversion_load_external_compute_shaders(self)) { + self->external_compute_shaders_failed_to_load = true; + fprintf(stderr, "gsr info: failed to load one or more external compute shaders, run gpu-screen-recorder with the '-gl-debug yes' option to see why. Falling back to slower graphics shader instead\n"); if(!gsr_color_conversion_load_external_graphics_shaders(self)) goto err; } - } else { - if(!gsr_color_conversion_load_compute_shaders(self)) { - self->compute_shaders_failed_to_load = true; - fprintf(stderr, "gsr info: failed to load one or more compute shaders, run gpu-screen-recorder with the '-gl-debug yes' option to see why. Falling back to slower graphics shader instead\n"); - if(!gsr_color_conversion_load_graphics_shaders(self)) - goto err; - } - - if(self->params.load_external_image_shader) { - if(!gsr_color_conversion_load_external_compute_shaders(self)) { - self->external_compute_shaders_failed_to_load = true; - fprintf(stderr, "gsr info: failed to load one or more external compute shaders, run gpu-screen-recorder with the '-gl-debug yes' option to see why. Falling back to slower graphics shader instead\n"); - if(!gsr_color_conversion_load_external_graphics_shaders(self)) - goto err; - } - } } if(load_framebuffers(self) != 0) @@ -1022,13 +998,6 @@ void gsr_color_conversion_clear(gsr_color_conversion *self) { self->params.egl->glBindFramebuffer(GL_FRAMEBUFFER, 0); } -void gsr_color_conversion_read_destination_texture(gsr_color_conversion *self, int destination_texture_index, int x, int y, int width, int height, unsigned int color_format, unsigned int data_format, void *pixels) { - assert(destination_texture_index >= 0 && destination_texture_index < self->params.num_destination_textures); - self->params.egl->glBindFramebuffer(GL_FRAMEBUFFER, self->framebuffers[destination_texture_index]); - self->params.egl->glReadPixels(x, y, width, height, color_format, data_format, pixels); - self->params.egl->glBindFramebuffer(GL_FRAMEBUFFER, 0); -} - gsr_rotation gsr_monitor_rotation_to_rotation(gsr_monitor_rotation monitor_rotation) { return (gsr_rotation)monitor_rotation; } diff --git a/src/cursor.c b/src/cursor.c index e818d72..40532f8 100644 --- a/src/cursor.c +++ b/src/cursor.c @@ -56,6 +56,10 @@ static bool gsr_cursor_set_from_x11_cursor_image(gsr_cursor *self, XFixesCursorI self->egl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, self->size.x, self->size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, cursor_data); free(cursor_data); + const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -33,9 +33,10 @@ static bool gsr_egl_create_window(gsr_egl *self) { EGLConfig ecfg; int32_t num_config = 0; + // TODO: Use EGL_OPENGL_ES_BIT as amd requires that for external texture, but that breaks software encoding const int32_t attr[] = { EGL_BUFFER_SIZE, 24, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, EGL_NONE, EGL_NONE }; @@ -44,7 +45,8 @@ static bool gsr_egl_create_window(gsr_egl *self) { EGL_NONE, EGL_NONE }; - self->eglBindAPI(EGL_OPENGL_ES_API); + // TODO: Use EGL_OPENGL_ES_API as amd requires that for external texture, but that breaks software encoding + self->eglBindAPI(EGL_OPENGL_API); self->egl_display = self->eglGetDisplay((EGLNativeDisplayType)gsr_window_get_display(self->window)); if(!self->egl_display) { diff --git a/src/encoder/video/software.c b/src/encoder/video/software.c index d8d9828..627cdea 100644 --- a/src/encoder/video/software.c +++ b/src/encoder/video/software.c @@ -71,15 +71,16 @@ void gsr_video_encoder_software_stop(gsr_video_encoder_software *self, AVCodecCo } static void gsr_video_encoder_software_copy_textures_to_frame(gsr_video_encoder *encoder, AVFrame *frame, gsr_color_conversion *color_conversion) { - (void)encoder; - //gsr_video_encoder_software *self = encoder->priv; + gsr_video_encoder_software *self = encoder->priv; // TODO: hdr support const unsigned int formats[2] = { GL_RED, GL_RG }; - const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size for(int i = 0; i < 2; ++i) { - // TODO: Use glPixelStore? - gsr_color_conversion_read_destination_texture(color_conversion, i, 0, 0, frame->width / div[i], frame->height / div[i], formats[i], GL_UNSIGNED_BYTE, frame->data[i]); + self->params.egl->glBindTexture(GL_TEXTURE_2D, self->target_textures[i]); + // We could use glGetTexSubImage and then we wouldn't have to use a specific linesize (LINESIZE_ALIGNMENT) that adds padding, + // but glGetTexSubImage is only available starting from opengl 4.5. + self->params.egl->glGetTexImage(GL_TEXTURE_2D, 0, formats[i], GL_UNSIGNED_BYTE, frame->data[i]); } + self->params.egl->glBindTexture(GL_TEXTURE_2D, 0); // cap_kms->kms.base.egl->eglSwapBuffers(cap_kms->kms.base.egl->egl_display, cap_kms->kms.base.egl->egl_surface); //self->params.egl->glFlush(); diff --git a/src/encoder/video/vaapi.c b/src/encoder/video/vaapi.c index 0daf4d8..c7ccd26 100644 --- a/src/encoder/video/vaapi.c +++ b/src/encoder/video/vaapi.c @@ -92,6 +92,10 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self if(self->prime.fourcc == VA_FOURCC_NV12 || self->prime.fourcc == VA_FOURCC_P010) { const uint32_t *formats = self->prime.fourcc == VA_FOURCC_NV12 ? formats_nv12 : formats_p010; const int div[2] = {1, 2}; // divide UV texture size by 2 because chroma is half size + const float border_colors[2][4] = { + {0.0f, 0.0f, 0.0f, 1.0f}, + {0.5f, 0.5f, 0.0f, 1.0f} + }; self->params.egl->glGenTextures(2, self->target_textures); for(int i = 0; i < 2; ++i) { @@ -121,6 +125,9 @@ static bool gsr_video_encoder_vaapi_setup_textures(gsr_video_encoder_vaapi *self } self->params.egl->glBindTexture(GL_TEXTURE_2D, self->target_textures[i]); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->params.egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_colors[i]); self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); diff --git a/src/image_writer.c b/src/image_writer.c index 3d731a0..e153a34 100644 --- a/src/image_writer.c +++ b/src/image_writer.c @@ -71,15 +71,11 @@ static bool gsr_image_writer_write_opengl_texture_to_file(gsr_image_writer *self return false; } - unsigned int fbo = 0; - self->egl->glGenFramebuffers(1, &fbo); - self->egl->glBindFramebuffer(GL_FRAMEBUFFER, fbo); - self->egl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->texture, 0); - - self->egl->glReadPixels(0, 0, self->width, self->height, GL_RGBA, GL_UNSIGNED_BYTE, frame_data); - - self->egl->glBindFramebuffer(GL_FRAMEBUFFER, 0); - self->egl->glDeleteFramebuffers(1, &fbo); + // TODO: hdr support + self->egl->glBindTexture(GL_TEXTURE_2D, self->texture); + // We could use glGetTexSubImage, but it's only available starting from opengl 4.5 + self->egl->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame_data); + self->egl->glBindTexture(GL_TEXTURE_2D, 0); self->egl->glFlush(); self->egl->glFinish(); diff --git a/src/main.cpp b/src/main.cpp index 2703c60..0956d0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2311,7 +2311,6 @@ static void capture_image_to_file(args_parser &arg_parser, gsr_egl *egl, gsr_ima color_conversion_params.destination_textures[0] = image_writer.texture; color_conversion_params.num_destination_textures = 1; color_conversion_params.destination_color = GSR_DESTINATION_COLOR_RGB8; - color_conversion_params.force_graphics_shader = true; gsr_color_conversion color_conversion; if(gsr_color_conversion_init(&color_conversion, &color_conversion_params) != 0) { @@ -3209,7 +3208,6 @@ int main(int argc, char **argv) { color_conversion_params.color_range = arg_parser.color_range; color_conversion_params.egl = &egl; color_conversion_params.load_external_image_shader = gsr_capture_uses_external_image(capture); - color_conversion_params.force_graphics_shader = arg_parser.video_encoder == GSR_VIDEO_ENCODER_HW_CPU; gsr_video_encoder_get_textures(video_encoder, color_conversion_params.destination_textures, &color_conversion_params.num_destination_textures, &color_conversion_params.destination_color); gsr_color_conversion color_conversion; diff --git a/src/pipewire_video.c b/src/pipewire_video.c index 29d12fd..bbc3f5d 100644 --- a/src/pipewire_video.c +++ b/src/pipewire_video.c @@ -358,7 +358,7 @@ static int64_t spa_video_format_to_drm_format(const enum spa_video_format format case SPA_VIDEO_FORMAT_ARGB_210LE: return DRM_FORMAT_ARGB2101010; case SPA_VIDEO_FORMAT_ABGR_210LE: return DRM_FORMAT_ABGR2101010; #endif - default: break; + default: break; } return DRM_FORMAT_INVALID; } @@ -471,27 +471,6 @@ static void gsr_pipewire_video_init_modifiers(gsr_pipewire_video *self) { spa_video_format_get_modifiers(self, self->supported_video_formats[i].format, self->modifiers + self->num_modifiers, GSR_PIPEWIRE_VIDEO_MAX_MODIFIERS - self->num_modifiers, &num_modifiers); self->supported_video_formats[i].modifiers_index = self->num_modifiers; self->supported_video_formats[i].modifiers_size = num_modifiers; - self->num_modifiers += num_modifiers; - } -} - -static void gsr_pipewire_video_format_remove_modifier(gsr_pipewire_video *self, gsr_video_format *video_format, uint64_t modifier) { - for(size_t i = 0; i < video_format->modifiers_size; ++i) { - if(self->modifiers[video_format->modifiers_index + i] != modifier) - continue; - - for(size_t j = i + 1; j < video_format->modifiers_size; ++j) { - self->modifiers[j - 1] = self->modifiers[j]; - } - --video_format->modifiers_size; - return; - } -} - -static void gsr_pipewire_video_remove_modifier(gsr_pipewire_video *self, uint64_t modifier) { - for(size_t i = 0; i < GSR_PIPEWIRE_VIDEO_NUM_VIDEO_FORMATS; i++) { - gsr_video_format *video_format = &self->supported_video_formats[i]; - gsr_pipewire_video_format_remove_modifier(self, video_format, modifier); } } @@ -672,7 +651,6 @@ void gsr_pipewire_video_deinit(gsr_pipewire_video *self) { self->dmabuf_num_planes = 0; self->negotiated = false; - self->renegotiated = false; if(self->mutex_initialized) { pthread_mutex_destroy(&self->mutex); @@ -724,19 +702,9 @@ static EGLImage gsr_pipewire_video_create_egl_image_with_fallback(gsr_pipewire_v } else { image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true); if(!image) { - if(self->renegotiated) { - fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n"); - self->no_modifiers_fallback = true; - image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false); - } else { - fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, renegotiating with a different modifier\n"); - self->negotiated = false; - self->renegotiated = true; - gsr_pipewire_video_remove_modifier(self, self->format.info.raw.modifier); - pw_thread_loop_lock(self->thread_loop); - pw_loop_signal_event(pw_thread_loop_get_loop(self->thread_loop), self->reneg); - pw_thread_loop_unlock(self->thread_loop); - } + fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n"); + self->no_modifiers_fallback = true; + image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false); } } return image; @@ -768,9 +736,13 @@ static void gsr_pipewire_video_update_cursor_texture(gsr_pipewire_video *self, g if(!self->cursor.data) return; + const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; self->egl->glBindTexture(GL_TEXTURE_2D, texture_map.cursor_texture_id); // TODO: glTextureSubImage2D if same size self->egl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, self->cursor.width, self->cursor.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self->cursor.data); + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); self->egl->glBindTexture(GL_TEXTURE_2D, 0); @@ -795,15 +767,12 @@ bool gsr_pipewire_video_map_texture(gsr_pipewire_video *self, gsr_texture_map te } EGLImage image = gsr_pipewire_video_create_egl_image_with_fallback(self); - if(!image) { - pthread_mutex_unlock(&self->mutex); - return false; + if(image) { + gsr_pipewire_video_bind_image_to_texture_with_fallback(self, texture_map, image); + *using_external_image = self->external_texture_fallback; + self->egl->eglDestroyImage(self->egl->egl_display, image); } - gsr_pipewire_video_bind_image_to_texture_with_fallback(self, texture_map, image); - *using_external_image = self->external_texture_fallback; - self->egl->eglDestroyImage(self->egl->egl_display, image); - gsr_pipewire_video_update_cursor_texture(self, texture_map); region->x = 0; diff --git a/src/utils.c b/src/utils.c index 092f1a5..c625ecf 100644 --- a/src/utils.c +++ b/src/utils.c @@ -598,11 +598,22 @@ vec2i scale_keep_aspect_ratio(vec2i from, vec2i to) { } unsigned int gl_create_texture(gsr_egl *egl, int width, int height, int internal_format, unsigned int format, int filter) { + float border_color[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + if(format == GL_RG) { // UV + border_color[0] = 0.5f; + border_color[1] = 0.5f; + border_color[2] = 0.0f; + border_color[3] = 1.0f; + } + unsigned int texture_id = 0; egl->glGenTextures(1, &texture_id); egl->glBindTexture(GL_TEXTURE_2D, texture_id); egl->glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, format, GL_UNSIGNED_BYTE, NULL); + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); diff --git a/src/window_texture.c b/src/window_texture.c index ba7212a..4846bdc 100644 --- a/src/window_texture.c +++ b/src/window_texture.c @@ -85,6 +85,10 @@ int window_texture_on_resize(WindowTexture *self) { texture_id = self->texture_id; } + const float border_color[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + self->egl->glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |