[gtk+/wip/baedert/drawing] gl renderer: Start border node implementation



commit 8ff773d02a7e33ba6f46a8194e727c813eb48819
Author: Timm Bäder <mail baedert org>
Date:   Sat Jul 1 15:04:32 2017 +0200

    gl renderer: Start border node implementation

 gsk/Makefile.am                   |    2 +
 gsk/gskglrenderer.c               |  122 ++++++++++++++++++++++++++++--------
 gsk/resources/glsl/border.fs.glsl |   22 +++++++
 gsk/resources/glsl/border.vs.glsl |    6 ++
 4 files changed, 125 insertions(+), 27 deletions(-)
---
diff --git a/gsk/Makefile.am b/gsk/Makefile.am
index 7fe143e..4917f6f 100644
--- a/gsk/Makefile.am
+++ b/gsk/Makefile.am
@@ -123,6 +123,8 @@ gsk_private_source_shaders = \
        resources/glsl/color.fs.glsl \
        resources/glsl/linear_gradient.vs.glsl \
        resources/glsl/linear_gradient.fs.glsl \
+       resources/glsl/border.vs.glsl \
+       resources/glsl/border.fs.glsl \
        resources/glsl/es2_common.fs.glsl \
        resources/glsl/es2_common.vs.glsl \
        resources/glsl/gl3_common.fs.glsl \
diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c
index 05bedd2..74aea8e 100644
--- a/gsk/gskglrenderer.c
+++ b/gsk/gskglrenderer.c
@@ -38,15 +38,20 @@ typedef struct {
   /* Shader-specific locations */
   union {
     struct {
-      int color_location;
-    };
+      int color;
+    } color_locations;
     struct {
-      int start_location;
-      int end_location;
-      int colors_location;
-      int offsets_location;
-      int n_stops_location;
-    };
+      int start;
+      int end;
+      int colors;
+      int offsets;
+      int n_stops;
+    } linear_gradient_locations;
+    struct {
+      int widths;
+      int colors;
+      int bounds;
+    } border_locations;
   };
 } Program;
 
@@ -64,6 +69,7 @@ enum {
   MODE_COLOR = 1,
   MODE_TEXTURE,
   MODE_LINEAR_GRADIENT,
+  MODE_BORDER,
   N_MODES
 };
 
@@ -93,6 +99,11 @@ typedef struct {
       graphene_point_t start;
       graphene_point_t end;
     } linear_gradient_data;
+    struct {
+      float widths[4];
+      float colors[16];
+      float bounds[4];
+    } border_data;
   };
 
   const char *name;
@@ -140,8 +151,6 @@ typedef enum {
   RENDER_SCISSOR
 } RenderMode;
 
-#define NUM_PROGRAMS 4
-
 struct _GskGLRenderer
 {
   GskRenderer parent_instance;
@@ -170,9 +179,7 @@ struct _GskGLRenderer
       Program blit_program;
       Program color_program;
       Program linear_gradient_program;
-    };
-    struct {
-      Program programs[NUM_PROGRAMS];
+      Program border_program;
     };
   };
 
@@ -370,7 +377,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
       goto out;
     }
   init_common_locations (self, &self->color_program);
-  self->color_program.color_location = glGetUniformLocation(self->color_program.id, "uColor");
+  self->color_program.color_locations.color = glGetUniformLocation(self->color_program.id, "uColor");
 
   self->linear_gradient_program.id =
     gsk_shader_builder_create_program (builder, "linear_gradient.vs.glsl", "linear_gradient.fs.glsl", 
&shader_error);
@@ -383,12 +390,30 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
       goto out;
     }
   init_common_locations (self, &self->linear_gradient_program);
-  self->linear_gradient_program.start_location = glGetUniformLocation(self->linear_gradient_program.id, 
"uStart");
-  self->linear_gradient_program.end_location = glGetUniformLocation(self->linear_gradient_program.id, 
"uEnd");
-  self->linear_gradient_program.colors_location = glGetUniformLocation(self->linear_gradient_program.id, 
"uColors");
-  self->linear_gradient_program.offsets_location = glGetUniformLocation(self->linear_gradient_program.id, 
"uOffsets");
-  g_assert (self->linear_gradient_program.offsets_location >= 0);
-  self->linear_gradient_program.n_stops_location = glGetUniformLocation(self->linear_gradient_program.id, 
"nStops");
+  self->linear_gradient_program.linear_gradient_locations.start = 
glGetUniformLocation(self->linear_gradient_program.id, "uStart");
+  self->linear_gradient_program.linear_gradient_locations.end = 
glGetUniformLocation(self->linear_gradient_program.id, "uEnd");
+  self->linear_gradient_program.linear_gradient_locations.colors = 
glGetUniformLocation(self->linear_gradient_program.id, "uColors");
+  self->linear_gradient_program.linear_gradient_locations.offsets = 
glGetUniformLocation(self->linear_gradient_program.id, "uOffsets");
+  self->linear_gradient_program.linear_gradient_locations.n_stops = 
glGetUniformLocation(self->linear_gradient_program.id, "nStops");
+
+  self->border_program.id = gsk_shader_builder_create_program (builder,
+                                                               "border.vs.glsl",
+                                                               "border.fs.glsl",
+                                                               &shader_error);
+  if (shader_error != NULL)
+    {
+      g_propagate_prefixed_error (error,
+                                  shader_error,
+                                  "Unable to create 'border' program: ");
+      g_object_unref (builder);
+      goto out;
+    }
+  init_common_locations (self, &self->border_program);
+  self->border_program.border_locations.widths = glGetUniformLocation (self->border_program.id, "uWidths");
+  /*g_assert (self->border_program.border_locations.widths >= 0);*/
+  self->border_program.border_locations.colors = glGetUniformLocation (self->border_program.id, "uColors");
+  g_assert (self->border_program.border_locations.colors >= 0);
+  self->border_program.border_locations.bounds = glGetUniformLocation (self->border_program.id, "uBounds");
 
   res = TRUE;
 
@@ -569,7 +594,7 @@ render_item (GskGLRenderer    *self,
     {
       case MODE_COLOR:
         {
-          glUniform4f (item->render_data.program->color_location,
+          glUniform4f (item->render_data.program->color_locations.color,
                        item->color_data.color.red,
                        item->color_data.color.green,
                        item->color_data.color.blue,
@@ -579,28 +604,45 @@ render_item (GskGLRenderer    *self,
 
       case MODE_LINEAR_GRADIENT:
         {
-          glUniform2f (item->render_data.program->start_location,
+          glUniform2f (item->render_data.program->linear_gradient_locations.start,
                        item->linear_gradient_data.start.x,
                        item->linear_gradient_data.start.y);
 
-          glUniform2f (item->render_data.program->end_location,
+          glUniform2f (item->render_data.program->linear_gradient_locations.end,
                        item->linear_gradient_data.end.x,
                        item->linear_gradient_data.end.y);
 
-          glUniform1i (item->render_data.program->n_stops_location,
+          glUniform1i (item->render_data.program->linear_gradient_locations.n_stops,
                        item->linear_gradient_data.n_stops);
 
-          glUniform4fv (item->render_data.program->colors_location,
+          glUniform4fv (item->render_data.program->linear_gradient_locations.colors,
                         item->linear_gradient_data.n_stops * 4,
                         item->linear_gradient_data.colors);
 
-          g_assert (item->render_data.program->offsets_location >= 0);
-          glUniform1fv (item->render_data.program->offsets_location,
+          glUniform1fv (item->render_data.program->linear_gradient_locations.offsets,
                         item->linear_gradient_data.n_stops,
                         item->linear_gradient_data.offsets);
         }
       break;
 
+      case MODE_BORDER:
+        {
+          glUniform1fv (item->render_data.program->border_locations.widths,
+                        4,
+                        item->border_data.widths);
+
+          glUniform4fv (item->render_data.program->border_locations.colors,
+                        16,
+                        item->border_data.colors);
+
+          glUniform4f (item->render_data.program->border_locations.bounds,
+                       item->border_data.bounds[0],
+                       item->border_data.bounds[1],
+                       item->border_data.bounds[2],
+                       item->border_data.bounds[3]);
+        }
+      break;
+
       case MODE_TEXTURE:
         {
           g_assert(item->render_data.texture_id != 0);
@@ -931,6 +973,32 @@ gsk_gl_renderer_add_render_item (GskGLRenderer           *self,
       }
       break;
 
+    case GSK_BORDER_NODE:
+      {
+        int i;
+        const float *widths = gsk_border_node_peek_widths (node);
+        const GdkRGBA *colors = gsk_border_node_peek_colors (node);
+
+        program_id = self->border_program.id;
+        item.render_data.program = &self->border_program;
+        item.mode = MODE_BORDER;
+
+        for (i = 0; i < 4; i ++)
+          {
+            item.border_data.widths[i] = widths[i];
+            item.border_data.colors[(i * 4) + 0] = colors[i].red;
+            item.border_data.colors[(i * 4) + 1] = colors[i].green;
+            item.border_data.colors[(i * 4) + 2] = colors[i].blue;
+            item.border_data.colors[(i * 4) + 3] = colors[i].alpha;
+          }
+
+        item.border_data.bounds[0] = node->bounds.origin.x;
+        item.border_data.bounds[1] = node->bounds.origin.y;
+        item.border_data.bounds[2] = node->bounds.size.width;
+        item.border_data.bounds[3] = node->bounds.size.height;
+      }
+      break;
+
     case GSK_ROUNDED_CLIP_NODE:
       {
         GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
diff --git a/gsk/resources/glsl/border.fs.glsl b/gsk/resources/glsl/border.fs.glsl
new file mode 100644
index 0000000..1ddb04c
--- /dev/null
+++ b/gsk/resources/glsl/border.fs.glsl
@@ -0,0 +1,22 @@
+uniform vec4 uColors[4];
+uniform float uWidths[4];
+uniform vec4 uBounds;
+
+void main() {
+  vec2 pos = gl_FragCoord.xy;
+  pos.y = uViewport.y - pos.y;
+
+  // TODO: Rounded corners
+  // TODO: Intersections!
+  if (pos.y <= uBounds.y + uWidths[0]) {
+    setOutputColor(uColors[0]);
+  } else if (pos.y >= uBounds.y + uBounds.w - uWidths[2]){
+    setOutputColor(uColors[2]);
+  } else if (pos.x <= uBounds.x + uWidths[3]) {
+    setOutputColor(uColors[3]);
+  } else if (pos.x >= uBounds.x + uBounds.z - uWidths[1]) {
+    setOutputColor(uColors[1]);
+  }else {
+    setOutputColor(vec4(0, 0, 0, 0));
+  }
+}
diff --git a/gsk/resources/glsl/border.vs.glsl b/gsk/resources/glsl/border.vs.glsl
new file mode 100644
index 0000000..1208513
--- /dev/null
+++ b/gsk/resources/glsl/border.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]