diff options
author | Emmanuele Bassi <ebassi@gnome.org> | 2016-04-25 13:38:22 +0100 |
---|---|---|
committer | Emmanuele Bassi <ebassi@gnome.org> | 2016-04-25 14:33:36 +0100 |
commit | f848450a70931133ab9368fd35b629c6c6e50fcb (patch) | |
tree | 648dbd35a3e44a168fa92f6d548639cb8e160bb9 /gdk | |
parent | 1379b4b175910a253bb4aa8df3194eec2e160213 (diff) | |
download | gtk+-f848450a70931133ab9368fd35b629c6c6e50fcb.tar.gz |
gl: Use a uniform to flip R and B colors on GLES
This allows us to decide when the R and B color channels should be
flipped with a much better granularity.
For instance, when using GLX_EXT_texture_from_pixmap to create a GL
texture from a surface we don't need to swap the R and B channels, as
the internal representation of the texture data will already have the
appropriate colors.
We also don't need to flip color channels when blitting from a texture.
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/gdkgl.c | 15 | ||||
-rw-r--r-- | gdk/gdkglcontextprivate.h | 1 | ||||
-rw-r--r-- | gdk/gdkinternals.h | 3 | ||||
-rw-r--r-- | gdk/resources/glsl/gles2-texture.fs.glsl | 8 | ||||
-rw-r--r-- | gdk/x11/gdkglcontext-x11.c | 8 |
5 files changed, 24 insertions, 11 deletions
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c index bd6383b985..51d2b029c6 100644 --- a/gdk/gdkgl.c +++ b/gdk/gdkgl.c @@ -138,6 +138,7 @@ make_program (GdkGLContextProgram *program, program->position_location = glGetAttribLocation (program->program, "position"); program->uv_location = glGetAttribLocation (program->program, "uv"); program->map_location = glGetUniformLocation (program->program, "map"); + program->flip_location = glGetUniformLocation (program->program, "flipColors"); } static void @@ -212,7 +213,8 @@ void gdk_gl_texture_quads (GdkGLContext *paint_context, guint texture_target, int n_quads, - GdkTexturedQuad *quads) + GdkTexturedQuad *quads, + gboolean flip_colors) { GdkGLContextPaintData *paint_data = gdk_gl_context_get_paint_data (paint_context); GdkGLContextProgram *program; @@ -240,8 +242,13 @@ gdk_gl_texture_quads (GdkGLContext *paint_context, program = paint_data->current_program; + /* Use texture unit 0 */ glActiveTexture (GL_TEXTURE0); - glUniform1i(program->map_location, 0); /* Use texture unit 0 */ + glUniform1i(program->map_location, 0); + + /* Flip 'R' and 'B' colors on GLES, if necessary */ + if (gdk_gl_context_get_use_es (paint_context)) + glUniform1i (program->flip_location, flip_colors ? 1 : 0); glEnableVertexAttribArray (program->position_location); glEnableVertexAttribArray (program->uv_location); @@ -619,7 +626,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr, } if (n_quads > 0) - gdk_gl_texture_quads (paint_context, GL_TEXTURE_2D, n_quads, quads); + gdk_gl_texture_quads (paint_context, GL_TEXTURE_2D, n_quads, quads, FALSE); g_free (quads); @@ -798,7 +805,7 @@ gdk_gl_texture_from_surface (cairo_surface_t *surface, /* We don't want to combine the quads here, because they have different textures. * And we don't want to upload the unused source areas to make it one texture. */ - gdk_gl_texture_quads (paint_context, target, 1, &quad); + gdk_gl_texture_quads (paint_context, target, 1, &quad, TRUE); } } diff --git a/gdk/gdkglcontextprivate.h b/gdk/gdkglcontextprivate.h index c15524b558..cb0b76793f 100644 --- a/gdk/gdkglcontextprivate.h +++ b/gdk/gdkglcontextprivate.h @@ -56,6 +56,7 @@ typedef struct { guint position_location; guint uv_location; guint map_location; + guint flip_location; } GdkGLContextProgram; typedef struct { diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h index f1286998ea..67c43a8b10 100644 --- a/gdk/gdkinternals.h +++ b/gdk/gdkinternals.h @@ -443,7 +443,8 @@ typedef struct { void gdk_gl_texture_quads (GdkGLContext *paint_context, guint texture_target, int n_quads, - GdkTexturedQuad *quads); + GdkTexturedQuad *quads, + gboolean flip_colors); void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface, GdkWindow *window); diff --git a/gdk/resources/glsl/gles2-texture.fs.glsl b/gdk/resources/glsl/gles2-texture.fs.glsl index 56c6c82002..02193a3dca 100644 --- a/gdk/resources/glsl/gles2-texture.fs.glsl +++ b/gdk/resources/glsl/gles2-texture.fs.glsl @@ -1,12 +1,16 @@ precision mediump float; uniform sampler2D map; +uniform int flipColors; varying highp vec2 vUv; void main() { vec4 color = texture2D(map, vUv); - /* Flip R and B around to match the Cairo convention */ - gl_FragColor = vec4(color.z, color.y, color.x, color.w); + /* Flip R and B around to match the Cairo convention, if required */ + if (flipColors == 1) + gl_FragColor = vec4(color.z, color.y, color.x, color.w); + else + gl_FragColor = color; } diff --git a/gdk/x11/gdkglcontext-x11.c b/gdk/x11/gdkglcontext-x11.c index 596d37a35e..0819f89648 100644 --- a/gdk/x11/gdkglcontext-x11.c +++ b/gdk/x11/gdkglcontext-x11.c @@ -455,15 +455,15 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context, if (glx_pixmap == NULL) return FALSE; + GDK_NOTE (OPENGL, g_message ("Using GLX_EXT_texture_from_pixmap to draw surface")); + window = gdk_gl_context_get_window (paint_context)->impl_window; window_scale = gdk_window_get_scale_factor (window); gdk_window_get_unscaled_size (window, NULL, &unscaled_window_height); sx = sy = 1; cairo_surface_get_device_scale (window->current_paint.surface, &sx, &sy); - - cairo_surface_get_device_offset (surface, - &device_x_offset, &device_y_offset); + cairo_surface_get_device_offset (surface, &device_x_offset, &device_y_offset); /* Ensure all the X stuff are synced before we read it back via texture-from-pixmap */ glXWaitX(); @@ -526,7 +526,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context, #undef FLIP_Y - gdk_gl_texture_quads (paint_context, target, n_rects, quads); + gdk_gl_texture_quads (paint_context, target, n_rects, quads, FALSE); g_free (quads); glDisable (GL_SCISSOR_TEST); |