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->position_location = glGetAttribLocation (program->program, "position");
|
||||||
program->uv_location = glGetAttribLocation (program->program, "uv");
|
program->uv_location = glGetAttribLocation (program->program, "uv");
|
||||||
program->map_location = glGetUniformLocation (program->program, "map");
|
program->map_location = glGetUniformLocation (program->program, "map");
|
||||||
|
program->flip_location = glGetUniformLocation (program->program, "flipColors");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -212,7 +213,8 @@ void
|
|||||||
gdk_gl_texture_quads (GdkGLContext *paint_context,
|
gdk_gl_texture_quads (GdkGLContext *paint_context,
|
||||||
guint texture_target,
|
guint texture_target,
|
||||||
int n_quads,
|
int n_quads,
|
||||||
GdkTexturedQuad *quads)
|
GdkTexturedQuad *quads,
|
||||||
|
gboolean flip_colors)
|
||||||
{
|
{
|
||||||
GdkGLContextPaintData *paint_data = gdk_gl_context_get_paint_data (paint_context);
|
GdkGLContextPaintData *paint_data = gdk_gl_context_get_paint_data (paint_context);
|
||||||
GdkGLContextProgram *program;
|
GdkGLContextProgram *program;
|
||||||
@ -240,8 +242,13 @@ gdk_gl_texture_quads (GdkGLContext *paint_context,
|
|||||||
|
|
||||||
program = paint_data->current_program;
|
program = paint_data->current_program;
|
||||||
|
|
||||||
|
/* Use texture unit 0 */
|
||||||
glActiveTexture (GL_TEXTURE0);
|
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->position_location);
|
||||||
glEnableVertexAttribArray (program->uv_location);
|
glEnableVertexAttribArray (program->uv_location);
|
||||||
@ -619,7 +626,7 @@ gdk_cairo_draw_from_gl (cairo_t *cr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n_quads > 0)
|
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);
|
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.
|
/* 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. */
|
* 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 position_location;
|
||||||
guint uv_location;
|
guint uv_location;
|
||||||
guint map_location;
|
guint map_location;
|
||||||
|
guint flip_location;
|
||||||
} GdkGLContextProgram;
|
} GdkGLContextProgram;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -443,7 +443,8 @@ typedef struct {
|
|||||||
void gdk_gl_texture_quads (GdkGLContext *paint_context,
|
void gdk_gl_texture_quads (GdkGLContext *paint_context,
|
||||||
guint texture_target,
|
guint texture_target,
|
||||||
int n_quads,
|
int n_quads,
|
||||||
GdkTexturedQuad *quads);
|
GdkTexturedQuad *quads,
|
||||||
|
gboolean flip_colors);
|
||||||
|
|
||||||
void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
|
void gdk_cairo_surface_mark_as_direct (cairo_surface_t *surface,
|
||||||
GdkWindow *window);
|
GdkWindow *window);
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
uniform sampler2D map;
|
uniform sampler2D map;
|
||||||
|
uniform int flipColors;
|
||||||
|
|
||||||
varying highp vec2 vUv;
|
varying highp vec2 vUv;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(map, vUv);
|
vec4 color = texture2D(map, vUv);
|
||||||
|
|
||||||
/* Flip R and B around to match the Cairo convention */
|
/* Flip R and B around to match the Cairo convention, if required */
|
||||||
gl_FragColor = vec4(color.z, color.y, color.x, color.w);
|
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)
|
if (glx_pixmap == NULL)
|
||||||
return FALSE;
|
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 = gdk_gl_context_get_window (paint_context)->impl_window;
|
||||||
window_scale = gdk_window_get_scale_factor (window);
|
window_scale = gdk_window_get_scale_factor (window);
|
||||||
gdk_window_get_unscaled_size (window, NULL, &unscaled_window_height);
|
gdk_window_get_unscaled_size (window, NULL, &unscaled_window_height);
|
||||||
|
|
||||||
sx = sy = 1;
|
sx = sy = 1;
|
||||||
cairo_surface_get_device_scale (window->current_paint.surface, &sx, &sy);
|
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 */
|
/* Ensure all the X stuff are synced before we read it back via texture-from-pixmap */
|
||||||
glXWaitX();
|
glXWaitX();
|
||||||
@ -526,7 +526,7 @@ gdk_x11_gl_context_texture_from_surface (GdkGLContext *paint_context,
|
|||||||
|
|
||||||
#undef FLIP_Y
|
#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);
|
g_free (quads);
|
||||||
|
|
||||||
glDisable (GL_SCISSOR_TEST);
|
glDisable (GL_SCISSOR_TEST);
|
||||||
|
Loading…
Reference in New Issue
Block a user