swap RGB -> BGR when necessary
This commit is contained in:
parent
2ec122ef32
commit
1fba2b78a8
@ -824,6 +824,7 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
|||||||
render->preview = true;
|
render->preview = true;
|
||||||
render->updated_at = tick;
|
render->updated_at = tick;
|
||||||
render->y_invert = frame->y_invert;
|
render->y_invert = frame->y_invert;
|
||||||
|
render->swap_rgb = frame->swap_rgb;
|
||||||
}
|
}
|
||||||
} else if (render->preview
|
} else if (render->preview
|
||||||
|| render->pixels == NULL || size_changed(render)) {
|
|| render->pixels == NULL || size_changed(render)) {
|
||||||
@ -839,6 +840,7 @@ static void canvas_render(GtkGLArea *area, GdkGLContext *context, gpointer data)
|
|||||||
render->tex_stride = cairo_image_surface_get_stride(head->surface);
|
render->tex_stride = cairo_image_surface_get_stride(head->surface);
|
||||||
render->updated_at = tick;
|
render->updated_at = tick;
|
||||||
render->y_invert = false;
|
render->y_invert = false;
|
||||||
|
render->swap_rgb = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,13 @@ static void capture_buffer(void *data,
|
|||||||
struct zwlr_screencopy_frame_v1 *copy_frame,
|
struct zwlr_screencopy_frame_v1 *copy_frame,
|
||||||
uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
uint32_t format, uint32_t width, uint32_t height, uint32_t stride) {
|
||||||
struct wd_frame *frame = data;
|
struct wd_frame *frame = data;
|
||||||
|
|
||||||
char *shm_name = NULL;
|
char *shm_name = NULL;
|
||||||
|
|
||||||
|
if (format != WL_SHM_FORMAT_ARGB8888 && format != WL_SHM_FORMAT_XRGB8888 &&
|
||||||
|
format != WL_SHM_FORMAT_ABGR8888 && format != WL_SHM_FORMAT_XBGR8888) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (asprintf(&shm_name, "/wd-%s", frame->output->name) == -1) {
|
if (asprintf(&shm_name, "/wd-%s", frame->output->name) == -1) {
|
||||||
fprintf(stderr, "asprintf: %s\n", strerror(errno));
|
fprintf(stderr, "asprintf: %s\n", strerror(errno));
|
||||||
shm_name = NULL;
|
shm_name = NULL;
|
||||||
@ -199,6 +204,8 @@ static void capture_buffer(void *data,
|
|||||||
frame->stride = stride;
|
frame->stride = stride;
|
||||||
frame->width = width;
|
frame->width = width;
|
||||||
frame->height = height;
|
frame->height = height;
|
||||||
|
frame->swap_rgb = format == WL_SHM_FORMAT_ABGR8888
|
||||||
|
|| format == WL_SHM_FORMAT_XBGR8888;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
err:
|
err:
|
||||||
|
20
src/render.c
20
src/render.c
@ -53,6 +53,7 @@ struct wd_gl_data {
|
|||||||
GLuint texture_uv_attribute;
|
GLuint texture_uv_attribute;
|
||||||
GLuint texture_screen_size_uniform;
|
GLuint texture_screen_size_uniform;
|
||||||
GLuint texture_texture_uniform;
|
GLuint texture_texture_uniform;
|
||||||
|
GLuint texture_color_transform_uniform;
|
||||||
|
|
||||||
GLuint buffers[2];
|
GLuint buffers[2];
|
||||||
|
|
||||||
@ -93,8 +94,9 @@ void main(void) {\n\
|
|||||||
static const char *texture_fragment_shader_src = "\
|
static const char *texture_fragment_shader_src = "\
|
||||||
varying vec2 uv_out;\n\
|
varying vec2 uv_out;\n\
|
||||||
uniform sampler2D texture;\n\
|
uniform sampler2D texture;\n\
|
||||||
|
uniform mat4 color_transform;\n\
|
||||||
void main(void) {\n\
|
void main(void) {\n\
|
||||||
gl_FragColor = texture2D(texture, uv_out);\n\
|
gl_FragColor = texture2D(texture, uv_out) * color_transform;\n\
|
||||||
}";
|
}";
|
||||||
|
|
||||||
static GLuint gl_make_shader(GLenum type, const char *src) {
|
static GLuint gl_make_shader(GLenum type, const char *src) {
|
||||||
@ -182,6 +184,8 @@ struct wd_gl_data *wd_gl_setup(void) {
|
|||||||
"screen_size");
|
"screen_size");
|
||||||
res->texture_texture_uniform = glGetUniformLocation(res->texture_program,
|
res->texture_texture_uniform = glGetUniformLocation(res->texture_program,
|
||||||
"texture");
|
"texture");
|
||||||
|
res->texture_color_transform_uniform = glGetUniformLocation(
|
||||||
|
res->texture_program, "color_transform");
|
||||||
|
|
||||||
glGenBuffers(2, res->buffers);
|
glGenBuffers(2, res->buffers);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, res->buffers[0]);
|
glBindBuffer(GL_ARRAY_BUFFER, res->buffers[0]);
|
||||||
@ -195,6 +199,18 @@ struct wd_gl_data *wd_gl_setup(void) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const GLfloat TRANSFORM_RGB[16] = {
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 0, 0, 1};
|
||||||
|
|
||||||
|
static const GLfloat TRANSFORM_BGR[16] = {
|
||||||
|
0, 0, 1, 0,
|
||||||
|
0, 1, 0, 0,
|
||||||
|
1, 0, 0, 0,
|
||||||
|
0, 0, 0, 1};
|
||||||
|
|
||||||
#define PUSH_POINT(_start, _a, _b) \
|
#define PUSH_POINT(_start, _a, _b) \
|
||||||
*((_start)++) = (_a);\
|
*((_start)++) = (_a);\
|
||||||
*((_start)++) = (_b);
|
*((_start)++) = (_b);
|
||||||
@ -278,6 +294,8 @@ void wd_gl_render(struct wd_gl_data *res, struct wd_render_data *info,
|
|||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, head->pixels);
|
0, GL_RGBA, GL_UNSIGNED_BYTE, head->pixels);
|
||||||
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0);
|
glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, 0);
|
||||||
}
|
}
|
||||||
|
glUniformMatrix4fv(res->texture_color_transform_uniform, 1, GL_FALSE,
|
||||||
|
head->swap_rgb ? TRANSFORM_RGB : TRANSFORM_BGR);
|
||||||
glDrawArrays(GL_TRIANGLES, i * 6, 6);
|
glDrawArrays(GL_TRIANGLES, i * 6, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,7 @@ struct wd_frame {
|
|||||||
uint8_t *pixels;
|
uint8_t *pixels;
|
||||||
uint64_t tick;
|
uint64_t tick;
|
||||||
bool y_invert;
|
bool y_invert;
|
||||||
|
bool swap_rgb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wd_head_config {
|
struct wd_head_config {
|
||||||
@ -154,6 +155,7 @@ struct wd_render_head_data {
|
|||||||
unsigned tex_height;
|
unsigned tex_height;
|
||||||
bool preview;
|
bool preview;
|
||||||
bool y_invert;
|
bool y_invert;
|
||||||
|
bool swap_rgb;
|
||||||
uint64_t updated_at;
|
uint64_t updated_at;
|
||||||
|
|
||||||
bool hovered;
|
bool hovered;
|
||||||
|
Loading…
Reference in New Issue
Block a user