[gtk+/wip/baedert/gl: 86/95] gl renderer: Implement cross fade nodes



commit 58bbbf7cd5c3bddf8abac22f84669fae2c1dd81b
Author: Timm Bäder <mail baedert org>
Date:   Mon Dec 11 08:22:28 2017 +0100

    gl renderer: Implement cross fade nodes

 gsk/gl/gskglrenderer.c                |   66 ++++++++++++++++++++++++++++++++-
 gsk/gl/gskglrenderopsprivate.h        |   15 ++++++-
 gsk/meson.build                       |    1 +
 gsk/resources/glsl/cross_fade.fs.glsl |   12 ++++++
 4 files changed, 90 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index f0f5508..c9acda7 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -199,6 +199,7 @@ struct _GskGLRenderer
       Program outset_shadow_program;
       Program shadow_program;
       Program border_program;
+      Program cross_fade_program;
     };
   };
 
@@ -992,6 +993,51 @@ render_shadow_node (GskGLRenderer       *self,
   gsk_gl_renderer_add_render_ops (self, original_child, builder);
 }
 
+static inline void
+render_cross_fade_node (GskGLRenderer       *self,
+                        GskRenderNode       *node,
+                        RenderOpBuilder     *builder)
+{
+  const float min_x = node->bounds.origin.x;
+  const float min_y = node->bounds.origin.y;
+  const float max_x = min_x + node->bounds.size.width;
+  const float max_y = min_y + node->bounds.size.height;
+  GskRenderNode *start_node = gsk_cross_fade_node_get_start_child (node);
+  GskRenderNode *end_node = gsk_cross_fade_node_get_end_child (node);
+  float progress = gsk_cross_fade_node_get_progress (node);
+  int start_texture_id;
+  int end_texture_id;
+  gboolean is_offscreen;
+  RenderOp op;
+  const GskQuadVertex vertex_data[GL_N_VERTICES] = {
+    { { min_x, min_y }, { 0, 1 }, },
+    { { min_x, max_y }, { 0, 0 }, },
+    { { max_x, min_y }, { 1, 1 }, },
+
+    { { max_x, max_y }, { 1, 0 }, },
+    { { min_x, max_y }, { 0, 0 }, },
+    { { max_x, min_y }, { 1, 1 }, },
+  };
+
+  /* TODO: We create 2 textures here as big as the cross-fade node, but both the
+   * start and the end node might be a lot smaller than that. */
+
+  add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y, start_node,
+                         &start_texture_id, &is_offscreen);
+
+  add_offscreen_ops (self, builder, min_x, max_x, min_y, max_y, end_node,
+                     &end_texture_id, &is_offscreen);
+
+  ops_set_program (builder, &self->cross_fade_program);
+  op.op = OP_CHANGE_CROSS_FADE;
+  op.cross_fade.progress = progress;
+  op.cross_fade.source2 = end_texture_id;
+  ops_add (builder, &op);
+  ops_set_texture (builder, start_texture_id);
+
+  ops_draw (builder, vertex_data);
+}
+
 static void
 gsk_gl_renderer_dispose (GObject *gobject)
 {
@@ -1073,6 +1119,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
     { "outset shadow",   "blit.vs.glsl",  "outset_shadow.fs.glsl" },
     { "shadow",          "blit.vs.glsl",  "shadow.fs.glsl" },
     { "border",          "blit.vs.glsl",  "border.fs.glsl" },
+    { "cross fade",      "blit.vs.glsl",  "cross_fade.fs.glsl" },
   };
 
   builder = gsk_shader_builder_new ();
@@ -1190,6 +1237,10 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   INIT_PROGRAM_UNIFORM_LOCATION (border, color);
   INIT_PROGRAM_UNIFORM_LOCATION (border, widths);
 
+  /* cross fade */
+  INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, progress);
+  INIT_PROGRAM_UNIFORM_LOCATION (cross_fade, source2);
+
   g_object_unref (builder);
   return TRUE;
 }
@@ -1510,8 +1561,11 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer   *self,
       render_border_node (self, node, builder);
     break;
 
-    case GSK_REPEATING_LINEAR_GRADIENT_NODE:
     case GSK_CROSS_FADE_NODE:
+      render_cross_fade_node (self, node, builder);
+    break;
+
+    case GSK_REPEATING_LINEAR_GRADIENT_NODE:
     case GSK_BLEND_NODE:
     case GSK_REPEAT_NODE:
     default:
@@ -1770,6 +1824,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
 
           break;
 
+        case OP_CHANGE_CROSS_FADE:
+          g_assert (program == &self->cross_fade_program);
+          /* End texture id */
+          glUniform1i (program->cross_fade.source2_location, 1);
+          glActiveTexture (GL_TEXTURE0 + 1);
+          glBindTexture (GL_TEXTURE_2D, op->cross_fade.source2);
+          /* progress */
+          glUniform1f (program->cross_fade.progress_location, op->cross_fade.progress);
+          break;
+
         case OP_CHANGE_LINEAR_GRADIENT:
             OP_PRINT (" -> Linear gradient");
             glUniform1i (program->linear_gradient.num_color_stops_location,
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 89dca55..5081a0c 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -10,7 +10,7 @@
 #include "gskglrendererprivate.h"
 
 #define GL_N_VERTICES 6
-#define GL_N_PROGRAMS 11
+#define GL_N_PROGRAMS 12
 
 enum {
   OP_NONE,
@@ -31,8 +31,9 @@ enum {
   OP_CHANGE_OUTSET_SHADOW   =  15,
   OP_CHANGE_BORDER          =  16,
   OP_CHANGE_BORDER_COLOR    =  17,
-  OP_CLEAR                  =  18,
-  OP_DRAW                   =  19,
+  OP_CHANGE_CROSS_FADE      =  18,
+  OP_CLEAR                  =  19,
+  OP_DRAW                   =  20,
 };
 
 typedef struct
@@ -99,6 +100,10 @@ typedef struct
       int color_location;
       int widths_location;
     } border;
+    struct {
+      int source2_location;
+      int progress_location;
+    } cross_fade;
   };
 
 } Program;
@@ -162,6 +167,10 @@ typedef struct
       float widths[4];
       float color[4];
     } border;
+    struct {
+      float progress;
+      int source2;
+    } cross_fade;
   };
 } RenderOp;
 
diff --git a/gsk/meson.build b/gsk/meson.build
index 7f0ff26..8ee5af9 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -13,6 +13,7 @@ gsk_private_source_shaders = [
   'resources/glsl/outset_shadow.fs.glsl',
   'resources/glsl/shadow.fs.glsl',
   'resources/glsl/border.fs.glsl',
+  'resources/glsl/cross_fade.fs.glsl',
   'resources/glsl/es2_common.fs.glsl',
   'resources/glsl/es2_common.vs.glsl',
   'resources/glsl/gl3_common.fs.glsl',
diff --git a/gsk/resources/glsl/cross_fade.fs.glsl b/gsk/resources/glsl/cross_fade.fs.glsl
new file mode 100644
index 0000000..a38b504
--- /dev/null
+++ b/gsk/resources/glsl/cross_fade.fs.glsl
@@ -0,0 +1,12 @@
+
+uniform float u_progress;
+uniform sampler2D u_source2;
+
+void main() {
+  vec4 source1 = Texture(u_source, vUv);  // start child
+  vec4 source2 = Texture(u_source2, vUv); // end child
+
+  float p = u_progress;
+  vec4 color = ((1 - p) * source1) + (p * source2);
+  setOutputColor(color);
+}


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