[gtk+/wip/baedert/gl: 54/95] gl renderer: Implement unblurred outset shadows



commit 32e6fbd1dd11fbace49e268b9598ffe380e247c3
Author: Timm Bäder <mail baedert org>
Date:   Fri Dec 1 08:30:11 2017 +0100

    gl renderer: Implement unblurred outset shadows

 gsk/gl/gskglrenderer.c                   |   48 ++++++++++++++++++++++++++++-
 gsk/gl/gskglrenderopsprivate.h           |   24 +++++++++++++--
 gsk/meson.build                          |    1 +
 gsk/resources/glsl/outset_shadow.fs.glsl |   27 +++++++++++++++++
 4 files changed, 95 insertions(+), 5 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 948e4eb..325ee83 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -170,6 +170,7 @@ struct _GskGLRenderer
       Program linear_gradient_program;
       Program blur_program;
       Program inset_shadow_program;
+      Program outset_shadow_program;
     };
   };
 
@@ -272,6 +273,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
       { "linear gradient", "blit.vs.glsl",  "linear_gradient.fs.glsl" },
       { "blur",            "blit.vs.glsl",  "blur.fs.glsl" },
       { "inset shadow",    "blit.vs.glsl",  "inset_shadow.fs.glsl" },
+      { "outset shadow",   "blit.vs.glsl",  "outset_shadow.fs.glsl" },
   };
 
   builder = gsk_shader_builder_new ();
@@ -374,6 +376,14 @@ gsk_gl_renderer_create_programs (GskGLRenderer  *self,
   INIT_PROGRAM_UNIFORM_LOCATION2 (inset_shadow, corner_widths);
   INIT_PROGRAM_UNIFORM_LOCATION2 (inset_shadow, corner_heights);
 
+  /* outset shadow */
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, color);
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, spread);
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, offset);
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, outline);
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_widths);
+  INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_heights);
+
   g_object_unref (builder);
   return TRUE;
 }
@@ -1012,12 +1022,36 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer   *self,
       }
     break;
 
+    case GSK_OUTSET_SHADOW_NODE:
+      {
+        RenderOp op;
+
+        /* TODO: Implement blurred outset shadows as well */
+        if (gsk_outset_shadow_node_get_blur_radius (node) > 0)
+          goto do_default;
+
+        op.op = OP_CHANGE_OUTSET_SHADOW;
+        rgba_to_float (gsk_outset_shadow_node_peek_color (node), op.outset_shadow.color);
+        rounded_rect_to_floats (gsk_outset_shadow_node_peek_outline (node),
+                                op.outset_shadow.outline,
+                                op.outset_shadow.corner_widths,
+                                op.outset_shadow.corner_heights);
+        op.outset_shadow.radius = gsk_outset_shadow_node_get_blur_radius (node);
+        op.outset_shadow.spread = gsk_outset_shadow_node_get_spread (node);
+        op.outset_shadow.offset[0] = gsk_outset_shadow_node_get_dx (node);
+        op.outset_shadow.offset[1] = -gsk_outset_shadow_node_get_dy (node);
+
+        ops_set_program (builder, &self->outset_shadow_program);
+        ops_add (builder, &op);
+        ops_draw (builder, vertex_data);
+      }
+    break;
+
 do_default:
 
     case GSK_REPEATING_LINEAR_GRADIENT_NODE:
-    case GSK_BORDER_NODE:
-    case GSK_OUTSET_SHADOW_NODE:
     case GSK_SHADOW_NODE:
+    case GSK_BORDER_NODE:
     case GSK_CROSS_FADE_NODE:
     case GSK_BLEND_NODE:
     case GSK_REPEAT_NODE:
@@ -1323,6 +1357,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
           glUniform4fv (program->inset_shadow.corner_heights_location, 1, op->inset_shadow.corner_heights);
           break;
 
+       case OP_CHANGE_OUTSET_SHADOW:
+          g_assert (program == &self->outset_shadow_program);
+          glUniform4fv (program->outset_shadow.color_location, 1, op->outset_shadow.color);
+          glUniform2fv (program->outset_shadow.offset_location, 1, op->outset_shadow.offset);
+          glUniform1f (program->outset_shadow.spread_location, op->outset_shadow.spread);
+          glUniform4fv (program->outset_shadow.outline_location, 1, op->outset_shadow.outline);
+          glUniform4fv (program->outset_shadow.corner_widths_location, 1, op->outset_shadow.corner_widths);
+          glUniform4fv (program->outset_shadow.corner_heights_location, 1, op->outset_shadow.corner_heights);
+          break;
+
         case OP_DRAW:
           OP_PRINT (" -> draw %ld, size %ld and program %s\n",
                     op->draw.vao_offset, op->draw.vao_size, program->name);
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 44c3e21..ec9bc94 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 8
+#define GL_N_PROGRAMS 9
 
 enum {
   OP_NONE,
@@ -28,8 +28,9 @@ enum {
   OP_CHANGE_COLOR_MATRIX    =  12,
   OP_CHANGE_BLUR            =  13,
   OP_CHANGE_INSET_SHADOW    =  14,
-  OP_CLEAR                  =  15,
-  OP_DRAW                   =  16,
+  OP_CHANGE_OUTSET_SHADOW   =  15,
+  OP_CLEAR                  =  16,
+  OP_DRAW                   =  17,
 };
 
 typedef struct
@@ -81,6 +82,14 @@ typedef struct
       int corner_widths_location;
       int corner_heights_location;
     } inset_shadow;
+    struct {
+      int color_location;
+      int spread_location;
+      int offset_location;
+      int outline_location;
+      int corner_widths_location;
+      int corner_heights_location;
+    } outset_shadow;
   };
 
 } Program;
@@ -128,6 +137,15 @@ typedef struct
       float offset[2];
       float color[4];
     } inset_shadow;
+    struct {
+      float outline[4];
+      float corner_widths[4];
+      float corner_heights[4];
+      float radius;
+      float spread;
+      float offset[2];
+      float color[4];
+    } outset_shadow;
   };
 } RenderOp;
 
diff --git a/gsk/meson.build b/gsk/meson.build
index 01bbd32..f05cb34 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -10,6 +10,7 @@ gsk_private_source_shaders = [
   'resources/glsl/blur.vs.glsl',
   'resources/glsl/blur.fs.glsl',
   'resources/glsl/inset_shadow.fs.glsl',
+  'resources/glsl/outset_shadow.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/outset_shadow.fs.glsl b/gsk/resources/glsl/outset_shadow.fs.glsl
new file mode 100644
index 0000000..c927172
--- /dev/null
+++ b/gsk/resources/glsl/outset_shadow.fs.glsl
@@ -0,0 +1,27 @@
+uniform float u_spread;
+uniform float u_blur_radius;
+uniform vec4 u_color;
+uniform vec2 u_offset;
+uniform vec4 u_outline;
+uniform vec4 u_corner_widths;
+uniform vec4 u_corner_heights;
+
+
+void main() {
+  vec4 f = gl_FragCoord;
+
+  f.x += u_viewport.x;
+  f.y = (u_viewport.y + u_viewport.w) - f.y;
+
+  RoundedRect outline = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
+                                    u_corner_widths, u_corner_heights);
+  RoundedRect outside = rounded_rect_shrink(outline, vec4(- u_spread));
+
+
+  vec2 offset = vec2(u_offset.x, - u_offset.y);
+  vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
+  color = color * clamp (rounded_rect_coverage (outside, f.xy - offset) -
+                         rounded_rect_coverage (outline, f.xy),
+                         0.0, 1.0);
+  setOutputColor(color);
+}


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