[gtk+/wip/ebassi/gles: 2/10] gl: Use a uniform to flip R and B colors on GLES



commit f848450a70931133ab9368fd35b629c6c6e50fcb
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Apr 25 13:38:22 2016 +0100

    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.

 gdk/gdkgl.c                              |   15 +++++++++++----
 gdk/gdkglcontextprivate.h                |    1 +
 gdk/gdkinternals.h                       |    3 ++-
 gdk/resources/glsl/gles2-texture.fs.glsl |    8 ++++++--
 gdk/x11/gdkglcontext-x11.c               |    8 ++++----
 5 files changed, 24 insertions(+), 11 deletions(-)
---
diff --git a/gdk/gdkgl.c b/gdk/gdkgl.c
index bd6383b..51d2b02 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 c15524b..cb0b767 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 f128699..67c43a8 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 56c6c82..02193a3 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 596d37a..0819f89 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);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]