swap RGB -> BGR when necessary

This commit is contained in:
Jason Francis 2019-08-01 11:07:00 -04:00
parent 2ec122ef32
commit 1fba2b78a8
4 changed files with 31 additions and 2 deletions

View File

@ -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;
} }
} }
} }

View File

@ -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:

View File

@ -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);
} }
} }

View File

@ -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;