[gtk+/wip/ebassi/render-solid-colors: 3/3] gsk: Render nodes with solid colors



commit 0d01e12acb15475ca21c6a4e6432860264dbf9e2
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Wed Nov 16 17:32:32 2016 +0000

    gsk: Render nodes with solid colors
    
    GskRenderNodes with solid colors should be handled differently than
    nodes with texturing data.
    
    The Cairo renderer just emits a rectangle with the color information
    stored inside the node; the GL renderer, on the other hand, needs to use
    a white texture which gets rendered using a color uniform inside the
    fragment shader.

 gsk/gskcairorenderer.c                |   10 +++++++++
 gsk/gskglrenderer.c                   |   36 +++++++++++++++++++++++++++++++-
 gsk/resources/glsl/blit.fs.glsl       |    2 +-
 gsk/resources/glsl/es2_common.fs.glsl |    1 +
 gsk/resources/glsl/gl3_common.fs.glsl |    1 +
 gsk/resources/glsl/gl_common.fs.glsl  |    1 +
 6 files changed, 48 insertions(+), 3 deletions(-)
---
diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c
index 501b540..a07a2c0 100644
--- a/gsk/gskcairorenderer.c
+++ b/gsk/gskcairorenderer.c
@@ -100,6 +100,16 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self,
       cairo_paint (cr);
       cairo_surface_destroy (surface);
     }
+  else if (gsk_render_node_has_solid_color (node))
+    {
+      GdkRGBA color;
+
+      gsk_render_node_get_solid_color (node, &color);
+
+      cairo_set_source_rgba (cr, color.red, color.green, color.blue, color.alpha);
+      cairo_rectangle (cr, frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+      cairo_fill (cr);
+    }
   else
     {
       cairo_set_source_surface (cr, gsk_render_node_get_surface (node), frame.origin.x, frame.origin.y); 
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 6834e32..c430dcc 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -36,6 +36,7 @@ typedef struct {
   int position_location;
   int alpha_location;
   int blendMode_location;
+  int color_location;
 } RenderData;
 
 typedef struct {
@@ -53,6 +54,8 @@ typedef struct {
   float opacity;
   float z;
 
+  graphene_vec4_t color;
+
   const char *name;
 
   GskBlendMode blend_mode;
@@ -69,6 +72,7 @@ enum {
   MASK,
   ALPHA,
   BLEND_MODE,
+  COLOR,
   N_UNIFORMS
 };
 
@@ -202,7 +206,8 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self)
   self->uniforms[MASK] = gsk_shader_builder_add_uniform (builder, "uMask");
   self->uniforms[ALPHA] = gsk_shader_builder_add_uniform (builder, "uAlpha");
   self->uniforms[BLEND_MODE] = gsk_shader_builder_add_uniform (builder, "uBlendMode");
-  
+  self->uniforms[COLOR] = gsk_shader_builder_add_uniform (builder, "uColor");
+
   self->attributes[POSITION] = gsk_shader_builder_add_attribute (builder, "aPosition");
   self->attributes[UV] = gsk_shader_builder_add_attribute (builder, "aUv");
 
@@ -402,6 +407,7 @@ render_item (GskGLRenderer *self,
              RenderItem    *item)
 {
   float mvp[16];
+  float color[4];
   float opacity;
 
   if (item->children != NULL)
@@ -451,6 +457,12 @@ render_item (GskGLRenderer *self,
   graphene_matrix_to_float (&item->mvp, mvp);
   glUniformMatrix4fv (item->render_data.mvp_location, 1, GL_FALSE, mvp);
 
+  graphene_vec4_to_float (&item->color, color);
+  glUniform4fv (item->render_data.color_location, 1, color);
+  GSK_NOTE (OPENGL, g_print ("%*sColor <%g,%g,%g,%g>\n",
+                             2 * node_depth (item->node), "",
+                             color[0], color[1], color[2], color[3]));
+
   /* Draw the quad */
   GSK_NOTE2 (OPENGL, TRANSFORMS,
              g_print ("%*sDrawing item <%s>[%p] (w:%g, h:%g) with opacity: %g blend mode: %d\n",
@@ -508,6 +520,9 @@ render_item (GskGLRenderer *self,
       graphene_matrix_to_float (&item->mvp, mvp);
       glUniformMatrix4fv (item->render_data.mvp_location, 1, GL_FALSE, mvp);
 
+      graphene_vec4_to_float (&item->color, color);
+      glUniform4fv (item->render_data.color_location, 1, color);
+
       /* Draw the quad */
       GSK_NOTE2 (OPENGL, TRANSFORMS,
                  g_print ("%*sDrawing offscreen item <%s>[%p] (w:%g, h:%g) with opacity: %g\n",
@@ -685,6 +700,8 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
     gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[ALPHA]);
   item.render_data.blendMode_location =
     gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[BLEND_MODE]);
+  item.render_data.color_location =
+    gsk_shader_builder_get_uniform_location (self->shader_builder, program_id, self->uniforms[COLOR]);
 
   item.render_data.position_location =
     gsk_shader_builder_get_attribute_location (self->shader_builder, program_id, self->attributes[POSITION]);
@@ -707,7 +724,19 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
       item.children = NULL;
     }
 
-  if (gsk_render_node_has_texture (node))
+  if (gsk_render_node_has_solid_color (node))
+    {
+      GdkRGBA color;
+
+      gsk_render_node_get_solid_color (node, &color);
+      color.red = color.red * color.alpha;
+      color.green = color.green * color.alpha;
+      color.blue = color.blue * color.alpha;
+
+      item.render_data.texture_id = gsk_gl_driver_get_white_texture (self->gl_driver);
+      graphene_vec4_init (&item.color, color.red, color.green, color.blue, color.alpha);
+    }
+  else if (gsk_render_node_has_texture (node))
     {
       GskTexture *texture = gsk_render_node_get_texture (node);
       int gl_min_filter = GL_NEAREST, gl_mag_filter = GL_NEAREST;
@@ -718,6 +747,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                                                            texture,
                                                                            gl_min_filter,
                                                                            gl_mag_filter);
+      graphene_vec4_init_from_vec4 (&item.color, graphene_vec4_one ());
     }
   else if (gsk_render_node_has_surface (node))
     {
@@ -736,6 +766,8 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
                                                surface,
                                                gl_min_filter,
                                                gl_mag_filter);
+
+      graphene_vec4_init_from_vec4 (&item.color, graphene_vec4_one ());
     }
   else
     {
diff --git a/gsk/resources/glsl/blit.fs.glsl b/gsk/resources/glsl/blit.fs.glsl
index ceb88ef..e5abdcf 100644
--- a/gsk/resources/glsl/blit.fs.glsl
+++ b/gsk/resources/glsl/blit.fs.glsl
@@ -1,5 +1,5 @@
 void main() {
-  vec4 diffuse = Texture(uSource, vUv);
+  vec4 diffuse = Texture(uSource, vUv) * uColor;
 
   setOutputColor(vec4(diffuse.xyz, diffuse.a * uAlpha));
 }
diff --git a/gsk/resources/glsl/es2_common.fs.glsl b/gsk/resources/glsl/es2_common.fs.glsl
index 4cbe577..0399a21 100644
--- a/gsk/resources/glsl/es2_common.fs.glsl
+++ b/gsk/resources/glsl/es2_common.fs.glsl
@@ -5,6 +5,7 @@ uniform sampler2D uSource;
 uniform sampler2D uMask;
 uniform float uAlpha;
 uniform int uBlendMode;
+uniform vec4 uColor;
 
 varying vec2 vUv;
 
diff --git a/gsk/resources/glsl/gl3_common.fs.glsl b/gsk/resources/glsl/gl3_common.fs.glsl
index 50f72f5..286ae24 100644
--- a/gsk/resources/glsl/gl3_common.fs.glsl
+++ b/gsk/resources/glsl/gl3_common.fs.glsl
@@ -5,6 +5,7 @@ uniform sampler2D uMask;
 uniform mat4 uMVP;
 uniform float uAlpha;
 uniform int uBlendMode;
+uniform vec4 uColor;
 
 in vec2 vUv;
 
diff --git a/gsk/resources/glsl/gl_common.fs.glsl b/gsk/resources/glsl/gl_common.fs.glsl
index 2ed6c75..1db652e 100644
--- a/gsk/resources/glsl/gl_common.fs.glsl
+++ b/gsk/resources/glsl/gl_common.fs.glsl
@@ -3,6 +3,7 @@ uniform sampler2D uSource;
 uniform sampler2D uMask;
 uniform float uAlpha;
 uniform int uBlendMode;
+uniform vec4 uColor;
 
 varying vec2 vUv;
 


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