forked from AuroraMiddleware/gtk
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.
This commit is contained in:
parent
1379b4b175
commit
f848450a70
15
gdk/gdkgl.c
15
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ typedef struct {
|
||||
guint position_location;
|
||||
guint uv_location;
|
||||
guint map_location;
|
||||
guint flip_location;
|
||||
} GdkGLContextProgram;
|
||||
|
||||
typedef struct {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user