[gtk+] glrenderer: Handle color nodes



commit fbada8e7583f0cc21a68d60c16f7af0468d24b33
Author: Timm Bäder <mail baedert org>
Date:   Fri Jan 6 20:53:12 2017 +0100

    glrenderer: Handle color nodes

 gsk/gskglrenderer.c              |   92 +++++++++++++++++++++++++++++++------
 gsk/resources/glsl/color.fs.glsl |    5 ++
 gsk/resources/glsl/color.vs.glsl |    6 +++
 3 files changed, 88 insertions(+), 15 deletions(-)
---
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 337aaba..4412084 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -34,6 +34,9 @@ typedef struct {
 
   /* Shader-specific locations */
   union {
+    struct {
+      int color_location;
+    };
   };
 } Program;
 
@@ -47,7 +50,14 @@ typedef struct {
   Program *program;
 } RenderData;
 
+enum {
+  MODE_COLOR = 1,
+  MODE_TEXTURE,
+  N_MODES
+};
+
 typedef struct {
+  int mode;
   /* Back pointer to the node, only meant for comparison */
   GskRenderNode *node;
 
@@ -61,8 +71,13 @@ typedef struct {
   float opacity;
   float z;
 
-  /* mode-specific data for shaders */
   union {
+    struct {
+      GdkRGBA color;
+    } color_data;
+    struct {
+      int a,b;
+    } texture_data;
   };
 
   const char *name;
@@ -109,7 +124,7 @@ typedef enum {
   RENDER_SCISSOR
 } RenderMode;
 
-#define NUM_PROGRAMS 2
+#define NUM_PROGRAMS 3
 
 struct _GskGLRenderer
 {
@@ -134,6 +149,7 @@ struct _GskGLRenderer
     struct {
       Program blend_program;
       Program blit_program;
+      Program color_program;
     };
     struct {
       Program programs[NUM_PROGRAMS];
@@ -320,7 +336,22 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
     }
   init_common_locations (self, &self->blit_program);
 
-
+  self->color_program.id =
+    gsk_shader_builder_create_program (builder, "color.vs.glsl", "color.fs.glsl", &shader_error);
+  if (shader_error != NULL)
+    {
+      g_propagate_prefixed_error (error,
+                                  shader_error,
+                                  "Unable to create 'color' program: ");
+      g_object_unref (builder);
+      goto out;
+    }
+  init_common_locations (self, &self->color_program);
+  self->color_program.color_location = gsk_shader_builder_get_uniform_location (self->shader_builder,
+                                                                                self->color_program.id,
+                                                                                
g_quark_from_string("uColor"));
+  self->color_program.color_location = glGetUniformLocation(self->color_program.id, "uColor");
+  g_assert(self->color_program.color_location >= 0);
 
   res = TRUE;
 
@@ -492,25 +523,43 @@ render_item (GskGLRenderer *self,
 
   gsk_gl_driver_bind_vao (self->gl_driver, item->render_data.vao_id);
 
-  glUseProgram (item->render_data.program_id);
+  glUseProgram (item->render_data.program->id);
 
-  if (item->render_data.texture_id != 0)
+  switch(item->mode)
     {
-      /* Use texture unit 0 for the source */
-      glUniform1i (item->render_data.program->source_location, 0);
-      gsk_gl_driver_bind_source_texture (self->gl_driver, item->render_data.texture_id);
+      case MODE_COLOR:
+        {
+          glUniform4f (item->render_data.program->color_location,
+                       item->color_data.color.red,
+                       item->color_data.color.green,
+                       item->color_data.color.blue,
+                       item->color_data.color.alpha);
+        }
+      break;
 
-      if (item->parent_data != NULL)
+      case MODE_TEXTURE:
         {
-          glUniform1i (item->render_data.program->blendMode_location, item->blend_mode);
+          g_assert(item->render_data.texture_id != 0);
+          /* Use texture unit 0 for the source */
+          glUniform1i (item->render_data.program->source_location, 0);
+          gsk_gl_driver_bind_source_texture (self->gl_driver, item->render_data.texture_id);
 
-          /* Use texture unit 1 for the mask */
-          if (item->parent_data->texture_id != 0)
+          if (item->parent_data != NULL)
             {
-              glUniform1i (item->render_data.program->mask_location, 1);
-              gsk_gl_driver_bind_mask_texture (self->gl_driver, item->parent_data->texture_id);
+              glUniform1i (item->render_data.program->blendMode_location, item->blend_mode);
+
+              /* Use texture unit 1 for the mask */
+              if (item->parent_data->texture_id != 0)
+                {
+                  glUniform1i (item->render_data.program->mask_location, 1);
+                  gsk_gl_driver_bind_mask_texture (self->gl_driver, item->parent_data->texture_id);
+                }
             }
         }
+      break;
+
+      default:
+        g_assert_not_reached ();
     }
 
   /* Pass the opacity component */
@@ -753,6 +802,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                                                              texture,
                                                                              gl_min_filter,
                                                                              gl_mag_filter);
+        item.mode = MODE_TEXTURE;
       }
       break;
 
@@ -776,6 +826,17 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                                  surface,
                                                  gl_min_filter,
                                                  gl_mag_filter);
+        item.mode = MODE_TEXTURE;
+      }
+      break;
+
+    case GSK_COLOR_NODE:
+      {
+        const GdkRGBA *c = gsk_color_node_peek_color(node);
+        program_id = self->color_program.id;
+        item.render_data.program = &self->color_program;
+        item.mode = MODE_COLOR;
+        item.color_data.color= *c;
       }
       break;
 
@@ -822,7 +883,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
         cairo_translate (cr, -node->bounds.origin.x, -node->bounds.origin.y);
 
         gsk_render_node_draw (node, cr);
-        
+
         cairo_destroy (cr);
 
         /* Upload the Cairo surface to a GL texture */
@@ -836,6 +897,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                                  GL_NEAREST, GL_NEAREST);
 
         cairo_surface_destroy (surface);
+        item.mode = MODE_TEXTURE;
       }
       break;
     }
diff --git a/gsk/resources/glsl/color.fs.glsl b/gsk/resources/glsl/color.fs.glsl
new file mode 100644
index 0000000..62d4ba0
--- /dev/null
+++ b/gsk/resources/glsl/color.fs.glsl
@@ -0,0 +1,5 @@
+uniform vec4 uColor;
+
+void main() {
+  setOutputColor(uColor);
+}
diff --git a/gsk/resources/glsl/color.vs.glsl b/gsk/resources/glsl/color.vs.glsl
new file mode 100644
index 0000000..1208513
--- /dev/null
+++ b/gsk/resources/glsl/color.vs.glsl
@@ -0,0 +1,6 @@
+void main() {
+  gl_Position = uMVP * vec4(aPosition, 0.0, 1.0);
+
+  // Flip the sampling
+  vUv = vec2(aUv.x, aUv.y);
+}


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