mirror of
https://repo.dec05eba.com/gpu-screen-recorder
synced 2026-03-31 09:07:13 +09:00
Fix screen and portal capture not working on some intel gpus
This commit is contained in:
@@ -50,6 +50,7 @@ typedef struct {
|
|||||||
|
|
||||||
gsr_color_range color_range;
|
gsr_color_range color_range;
|
||||||
bool load_external_image_shader;
|
bool load_external_image_shader;
|
||||||
|
bool force_graphics_shader;
|
||||||
} gsr_color_conversion_params;
|
} gsr_color_conversion_params;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -77,6 +78,7 @@ 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_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_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);
|
gsr_rotation gsr_monitor_rotation_to_rotation(gsr_monitor_rotation monitor_rotation);
|
||||||
|
|
||||||
|
|||||||
@@ -141,8 +141,6 @@ typedef void(*__GLXextFuncPtr)(void);
|
|||||||
#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS 0x90EB
|
#define GL_MAX_COMPUTE_FIXED_GROUP_INVOCATIONS 0x90EB
|
||||||
#define GL_TEXTURE0 0x84C0
|
#define GL_TEXTURE0 0x84C0
|
||||||
#define GL_TEXTURE1 0x84C1
|
#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_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
|
||||||
#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
|
#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ typedef struct {
|
|||||||
struct spa_video_info format;
|
struct spa_video_info format;
|
||||||
int server_version_sync;
|
int server_version_sync;
|
||||||
bool negotiated;
|
bool negotiated;
|
||||||
|
bool renegotiated;
|
||||||
bool damaged;
|
bool damaged;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -108,22 +108,14 @@ static int max_int(int a, int b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void gsr_capture_kms_create_input_texture_ids(gsr_capture_kms *self) {
|
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->glGenTextures(1, &self->input_texture_id);
|
||||||
self->params.egl->glBindTexture(GL_TEXTURE_2D, 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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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->glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
self->params.egl->glGenTextures(1, &self->external_input_texture_id);
|
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->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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_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->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
|
||||||
@@ -133,9 +125,6 @@ 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->glGenTextures(1, &self->cursor_texture_id);
|
||||||
self->params.egl->glBindTexture(cursor_texture_id_target, 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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(cursor_texture_id_target, GL_TEXTURE_MAG_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);
|
self->params.egl->glBindTexture(cursor_texture_id_target, 0);
|
||||||
|
|||||||
@@ -57,31 +57,20 @@ static void gsr_capture_portal_stop(gsr_capture_portal *self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void gsr_capture_portal_create_input_textures(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->glGenTextures(1, &self->texture_map.texture_id);
|
||||||
self->params.egl->glBindTexture(GL_TEXTURE_2D, 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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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->glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
self->params.egl->glGenTextures(1, &self->texture_map.external_texture_id);
|
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->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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_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->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
|
||||||
|
|
||||||
self->params.egl->glGenTextures(1, &self->texture_map.cursor_texture_id);
|
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->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_MIN_FILTER, GL_LINEAR);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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->glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
@@ -324,7 +313,7 @@ static int gsr_capture_portal_capture(gsr_capture *cap, gsr_capture_metadata *ca
|
|||||||
gsr_color_conversion_clear(color_conversion);
|
gsr_color_conversion_clear(color_conversion);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool is_scaled = self->params.output_resolution.x > 0 && self->params.output_resolution.y > 0;
|
const bool is_scaled = self->params.output_resolution.x > 0 && self->params.output_resolution.y > 0;
|
||||||
|
|||||||
@@ -89,15 +89,13 @@ static void get_compute_shader_header(char *header, size_t header_size, bool ext
|
|||||||
if(external_texture) {
|
if(external_texture) {
|
||||||
snprintf(header, header_size,
|
snprintf(header, header_size,
|
||||||
"#version 310 es\n"
|
"#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 : enable\n"
|
||||||
"#extension GL_OES_EGL_image_external_essl3 : require\n"
|
"#extension GL_OES_EGL_image_external_essl3 : require\n"
|
||||||
"layout(binding = 0) uniform highp samplerExternalOES img_input;\n"
|
"layout(binding = 0) uniform highp samplerExternalOES img_input;\n"
|
||||||
"layout(binding = 1) uniform highp sampler2D img_background;\n");
|
"layout(binding = 1) uniform highp sampler2D img_background;\n");
|
||||||
} else {
|
} else {
|
||||||
snprintf(header, header_size,
|
snprintf(header, header_size,
|
||||||
"#version 420\n"
|
"#version 310 es\n"
|
||||||
"#extension GL_ARB_compute_shader: enable\n"
|
|
||||||
"layout(binding = 0) uniform highp sampler2D img_input;\n"
|
"layout(binding = 0) uniform highp sampler2D img_input;\n"
|
||||||
"layout(binding = 1) uniform highp sampler2D img_background;\n");
|
"layout(binding = 1) uniform highp sampler2D img_background;\n");
|
||||||
}
|
}
|
||||||
@@ -109,7 +107,7 @@ static int load_compute_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_com
|
|||||||
char header[512];
|
char header[512];
|
||||||
get_compute_shader_header(header, sizeof(header), external_texture);
|
get_compute_shader_header(header, sizeof(header), external_texture);
|
||||||
|
|
||||||
char compute_shader[2048];
|
char compute_shader[4096];
|
||||||
snprintf(compute_shader, sizeof(compute_shader),
|
snprintf(compute_shader, sizeof(compute_shader),
|
||||||
"%s"
|
"%s"
|
||||||
"layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n"
|
"layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n"
|
||||||
@@ -127,12 +125,16 @@ static int load_compute_shader_y(gsr_shader *shader, gsr_egl *egl, gsr_color_com
|
|||||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
" 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 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 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n"
|
||||||
" vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size));\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_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
" vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
||||||
" vec4 output_color_yuv = %s;\n"
|
" vec4 output_color_yuv = %s;\n"
|
||||||
" float y_color = mix(output_color_yuv.r, source_color_yuv.r, source_color.a);\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"
|
" 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,
|
"}\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");
|
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)
|
if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0)
|
||||||
@@ -151,7 +153,7 @@ static int load_compute_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_co
|
|||||||
char header[512];
|
char header[512];
|
||||||
get_compute_shader_header(header, sizeof(header), external_texture);
|
get_compute_shader_header(header, sizeof(header), external_texture);
|
||||||
|
|
||||||
char compute_shader[2048];
|
char compute_shader[4096];
|
||||||
snprintf(compute_shader, sizeof(compute_shader),
|
snprintf(compute_shader, sizeof(compute_shader),
|
||||||
"%s"
|
"%s"
|
||||||
"layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n"
|
"layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n"
|
||||||
@@ -169,12 +171,16 @@ static int load_compute_shader_uv(gsr_shader *shader, gsr_egl *egl, gsr_color_co
|
|||||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
" 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 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 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n"
|
||||||
" vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size>>1));\n" // size/2
|
" 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_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
" vec4 source_color_yuv = RGBtoYUV * vec4(source_color.rgb, 1.0);\n"
|
||||||
" vec4 output_color_yuv = %s;\n"
|
" vec4 output_color_yuv = %s;\n"
|
||||||
" vec2 uv_color = mix(output_color_yuv.rg, source_color_yuv.gb, source_color.a);\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"
|
" 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,
|
"}\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");
|
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)
|
if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0)
|
||||||
@@ -191,10 +197,11 @@ static int load_compute_shader_rgb(gsr_shader *shader, gsr_egl *egl, gsr_color_c
|
|||||||
char header[512];
|
char header[512];
|
||||||
get_compute_shader_header(header, sizeof(header), external_texture);
|
get_compute_shader_header(header, sizeof(header), external_texture);
|
||||||
|
|
||||||
char compute_shader[2048];
|
char compute_shader[4096];
|
||||||
snprintf(compute_shader, sizeof(compute_shader),
|
snprintf(compute_shader, sizeof(compute_shader),
|
||||||
"%s"
|
"%s"
|
||||||
"layout (local_size_x = %d, local_size_y = %d, local_size_z = 1) in;\n"
|
"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 source_position;\n"
|
||||||
"uniform ivec2 target_position;\n"
|
"uniform ivec2 target_position;\n"
|
||||||
"uniform vec2 scale;\n"
|
"uniform vec2 scale;\n"
|
||||||
@@ -207,11 +214,15 @@ static int load_compute_shader_rgb(gsr_shader *shader, gsr_egl *egl, gsr_color_c
|
|||||||
" ivec2 output_size = textureSize(img_background, 0);\n"
|
" 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 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 output_texel_coord = vec2(texel_coord - source_position + target_position) + 0.5;\n"
|
||||||
" vec4 source_color = texture(img_input, rotated_texel_coord/vec2(size));\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 output_color = %s;\n"
|
" vec4 output_color = %s;\n"
|
||||||
" vec3 color = mix(output_color.rgb, source_color.rgb, source_color.a);\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"
|
" imageStore(img_output, texel_coord + target_position, vec4(color, 1.0));\n"
|
||||||
"}\n", header, max_local_size_dim, max_local_size_dim,
|
"}\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");
|
alpha_blending ? "texture(img_background, output_texel_coord/vec2(output_size))" : "source_color");
|
||||||
|
|
||||||
if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0)
|
if(gsr_shader_init(shader, egl, NULL, NULL, compute_shader) != 0)
|
||||||
@@ -620,20 +631,33 @@ int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!gsr_color_conversion_load_compute_shaders(self)) {
|
if(self->params.force_graphics_shader) {
|
||||||
self->compute_shaders_failed_to_load = true;
|
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");
|
self->external_compute_shaders_failed_to_load = true;
|
||||||
|
|
||||||
if(!gsr_color_conversion_load_graphics_shaders(self))
|
if(!gsr_color_conversion_load_graphics_shaders(self))
|
||||||
goto err;
|
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))
|
if(!gsr_color_conversion_load_external_graphics_shaders(self))
|
||||||
goto err;
|
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)
|
if(load_framebuffers(self) != 0)
|
||||||
@@ -998,6 +1022,13 @@ void gsr_color_conversion_clear(gsr_color_conversion *self) {
|
|||||||
self->params.egl->glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
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) {
|
gsr_rotation gsr_monitor_rotation_to_rotation(gsr_monitor_rotation monitor_rotation) {
|
||||||
return (gsr_rotation)monitor_rotation;
|
return (gsr_rotation)monitor_rotation;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,10 +56,6 @@ 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);
|
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);
|
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_MAG_FILTER, GL_LINEAR);
|
||||||
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
|||||||
@@ -33,10 +33,9 @@ static bool gsr_egl_create_window(gsr_egl *self) {
|
|||||||
EGLConfig ecfg;
|
EGLConfig ecfg;
|
||||||
int32_t num_config = 0;
|
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[] = {
|
const int32_t attr[] = {
|
||||||
EGL_BUFFER_SIZE, 24,
|
EGL_BUFFER_SIZE, 24,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
|
||||||
EGL_NONE, EGL_NONE
|
EGL_NONE, EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,8 +44,7 @@ static bool gsr_egl_create_window(gsr_egl *self) {
|
|||||||
EGL_NONE, EGL_NONE
|
EGL_NONE, EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Use EGL_OPENGL_ES_API as amd requires that for external texture, but that breaks software encoding
|
self->eglBindAPI(EGL_OPENGL_ES_API);
|
||||||
self->eglBindAPI(EGL_OPENGL_API);
|
|
||||||
|
|
||||||
self->egl_display = self->eglGetDisplay((EGLNativeDisplayType)gsr_window_get_display(self->window));
|
self->egl_display = self->eglGetDisplay((EGLNativeDisplayType)gsr_window_get_display(self->window));
|
||||||
if(!self->egl_display) {
|
if(!self->egl_display) {
|
||||||
|
|||||||
@@ -71,16 +71,15 @@ 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) {
|
static void gsr_video_encoder_software_copy_textures_to_frame(gsr_video_encoder *encoder, AVFrame *frame, gsr_color_conversion *color_conversion) {
|
||||||
gsr_video_encoder_software *self = encoder->priv;
|
(void)encoder;
|
||||||
|
//gsr_video_encoder_software *self = encoder->priv;
|
||||||
// TODO: hdr support
|
// TODO: hdr support
|
||||||
const unsigned int formats[2] = { GL_RED, GL_RG };
|
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) {
|
for(int i = 0; i < 2; ++i) {
|
||||||
self->params.egl->glBindTexture(GL_TEXTURE_2D, self->target_textures[i]);
|
// TODO: Use glPixelStore?
|
||||||
// We could use glGetTexSubImage and then we wouldn't have to use a specific linesize (LINESIZE_ALIGNMENT) that adds padding,
|
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]);
|
||||||
// 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);
|
// cap_kms->kms.base.egl->eglSwapBuffers(cap_kms->kms.base.egl->egl_display, cap_kms->kms.base.egl->egl_surface);
|
||||||
|
|
||||||
//self->params.egl->glFlush();
|
//self->params.egl->glFlush();
|
||||||
|
|||||||
@@ -92,10 +92,6 @@ 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) {
|
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 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 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);
|
self->params.egl->glGenTextures(2, self->target_textures);
|
||||||
for(int i = 0; i < 2; ++i) {
|
for(int i = 0; i < 2; ++i) {
|
||||||
@@ -125,9 +121,6 @@ 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->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_MIN_FILTER, GL_NEAREST);
|
||||||
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
self->params.egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
|||||||
@@ -71,11 +71,15 @@ static bool gsr_image_writer_write_opengl_texture_to_file(gsr_image_writer *self
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: hdr support
|
unsigned int fbo = 0;
|
||||||
self->egl->glBindTexture(GL_TEXTURE_2D, self->texture);
|
self->egl->glGenFramebuffers(1, &fbo);
|
||||||
// We could use glGetTexSubImage, but it's only available starting from opengl 4.5
|
self->egl->glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
self->egl->glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame_data);
|
self->egl->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self->texture, 0);
|
||||||
self->egl->glBindTexture(GL_TEXTURE_2D, 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);
|
||||||
|
|
||||||
self->egl->glFlush();
|
self->egl->glFlush();
|
||||||
self->egl->glFinish();
|
self->egl->glFinish();
|
||||||
|
|||||||
@@ -2311,6 +2311,7 @@ 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.destination_textures[0] = image_writer.texture;
|
||||||
color_conversion_params.num_destination_textures = 1;
|
color_conversion_params.num_destination_textures = 1;
|
||||||
color_conversion_params.destination_color = GSR_DESTINATION_COLOR_RGB8;
|
color_conversion_params.destination_color = GSR_DESTINATION_COLOR_RGB8;
|
||||||
|
color_conversion_params.force_graphics_shader = true;
|
||||||
|
|
||||||
gsr_color_conversion color_conversion;
|
gsr_color_conversion color_conversion;
|
||||||
if(gsr_color_conversion_init(&color_conversion, &color_conversion_params) != 0) {
|
if(gsr_color_conversion_init(&color_conversion, &color_conversion_params) != 0) {
|
||||||
@@ -3208,6 +3209,7 @@ int main(int argc, char **argv) {
|
|||||||
color_conversion_params.color_range = arg_parser.color_range;
|
color_conversion_params.color_range = arg_parser.color_range;
|
||||||
color_conversion_params.egl = &egl;
|
color_conversion_params.egl = &egl;
|
||||||
color_conversion_params.load_external_image_shader = gsr_capture_uses_external_image(capture);
|
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_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;
|
gsr_color_conversion color_conversion;
|
||||||
|
|||||||
@@ -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_ARGB_210LE: return DRM_FORMAT_ARGB2101010;
|
||||||
case SPA_VIDEO_FORMAT_ABGR_210LE: return DRM_FORMAT_ABGR2101010;
|
case SPA_VIDEO_FORMAT_ABGR_210LE: return DRM_FORMAT_ABGR2101010;
|
||||||
#endif
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return DRM_FORMAT_INVALID;
|
return DRM_FORMAT_INVALID;
|
||||||
}
|
}
|
||||||
@@ -471,6 +471,27 @@ 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);
|
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_index = self->num_modifiers;
|
||||||
self->supported_video_formats[i].modifiers_size = 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,6 +672,7 @@ void gsr_pipewire_video_deinit(gsr_pipewire_video *self) {
|
|||||||
self->dmabuf_num_planes = 0;
|
self->dmabuf_num_planes = 0;
|
||||||
|
|
||||||
self->negotiated = false;
|
self->negotiated = false;
|
||||||
|
self->renegotiated = false;
|
||||||
|
|
||||||
if(self->mutex_initialized) {
|
if(self->mutex_initialized) {
|
||||||
pthread_mutex_destroy(&self->mutex);
|
pthread_mutex_destroy(&self->mutex);
|
||||||
@@ -702,9 +724,19 @@ static EGLImage gsr_pipewire_video_create_egl_image_with_fallback(gsr_pipewire_v
|
|||||||
} else {
|
} else {
|
||||||
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true);
|
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, true);
|
||||||
if(!image) {
|
if(!image) {
|
||||||
fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
|
if(self->renegotiated) {
|
||||||
self->no_modifiers_fallback = true;
|
fprintf(stderr, "gsr error: gsr_pipewire_video_create_egl_image_with_fallback: failed to create egl image with modifiers, trying without modifiers\n");
|
||||||
image = gsr_pipewire_video_create_egl_image(self, fds, offsets, pitches, modifiers, false);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return image;
|
return image;
|
||||||
@@ -736,13 +768,9 @@ static void gsr_pipewire_video_update_cursor_texture(gsr_pipewire_video *self, g
|
|||||||
if(!self->cursor.data)
|
if(!self->cursor.data)
|
||||||
return;
|
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);
|
self->egl->glBindTexture(GL_TEXTURE_2D, texture_map.cursor_texture_id);
|
||||||
// TODO: glTextureSubImage2D if same size
|
// 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->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_MAG_FILTER, GL_LINEAR);
|
||||||
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
self->egl->glBindTexture(GL_TEXTURE_2D, 0);
|
self->egl->glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
@@ -767,12 +795,15 @@ 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);
|
EGLImage image = gsr_pipewire_video_create_egl_image_with_fallback(self);
|
||||||
if(image) {
|
if(!image) {
|
||||||
gsr_pipewire_video_bind_image_to_texture_with_fallback(self, texture_map, image);
|
pthread_mutex_unlock(&self->mutex);
|
||||||
*using_external_image = self->external_texture_fallback;
|
return false;
|
||||||
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);
|
gsr_pipewire_video_update_cursor_texture(self, texture_map);
|
||||||
|
|
||||||
region->x = 0;
|
region->x = 0;
|
||||||
|
|||||||
11
src/utils.c
11
src/utils.c
@@ -598,22 +598,11 @@ 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) {
|
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;
|
unsigned int texture_id = 0;
|
||||||
egl->glGenTextures(1, &texture_id);
|
egl->glGenTextures(1, &texture_id);
|
||||||
egl->glBindTexture(GL_TEXTURE_2D, 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->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_MAG_FILTER, filter);
|
||||||
egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||||
|
|
||||||
|
|||||||
@@ -85,10 +85,6 @@ int window_texture_on_resize(WindowTexture *self) {
|
|||||||
texture_id = self->texture_id;
|
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_MAG_FILTER, GL_LINEAR);
|
||||||
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
self->egl->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user