[gtk/wip/baedert/for-master: 2/3] gl renderer: Nine-slice unblurred outset shadows




commit e9298c67d58cf427141643062441b54b6d236628
Author: Timm Bäder <mail baedert org>
Date:   Sat Oct 31 08:54:27 2020 +0100

    gl renderer: Nine-slice unblurred outset shadows
    
    See #3284

 gsk/gl/gskglrenderer.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 1 deletion(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 0678e81f1e..f689e12619 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -482,6 +482,50 @@ load_offscreen_vertex_data (GskQuadVertex    vertex_data[GL_N_VERTICES],
                     max_x, max_y);
 }
 
+static void
+load_float_vertex_data (GskQuadVertex    vertex_data[GL_N_VERTICES],
+                        RenderOpBuilder *builder,
+                        float            x,
+                        float            y,
+                        float            width,
+                        float            height)
+{
+  const float min_x = builder->dx + x;
+  const float min_y = builder->dy + y;
+  const float max_x = min_x + width;
+  const float max_y = min_y + height;
+
+  vertex_data[0].position[0] = min_x;
+  vertex_data[0].position[1] = min_y;
+  vertex_data[0].uv[0] = 0;
+  vertex_data[0].uv[1] = 0;
+
+  vertex_data[1].position[0] = min_x;
+  vertex_data[1].position[1] = max_y;
+  vertex_data[1].uv[0] = 0;
+  vertex_data[1].uv[1] = 1;
+
+  vertex_data[2].position[0] = max_x;
+  vertex_data[2].position[1] = min_y;
+  vertex_data[2].uv[0] = 1;
+  vertex_data[2].uv[1] = 0;
+
+  vertex_data[3].position[0] = max_x;
+  vertex_data[3].position[1] = max_y;
+  vertex_data[3].uv[0] = 1;
+  vertex_data[3].uv[1] = 1;
+
+  vertex_data[4].position[0] = min_x;
+  vertex_data[4].position[1] = max_y;
+  vertex_data[4].uv[0] = 0;
+  vertex_data[4].uv[1] = 1;
+
+  vertex_data[5].position[0] = max_x;
+  vertex_data[5].position[1] = min_y;
+  vertex_data[5].uv[0] = 1;
+  vertex_data[5].uv[1] = 0;
+}
+
 static void gsk_gl_renderer_setup_render_mode (GskGLRenderer   *self);
 static gboolean add_offscreen_ops             (GskGLRenderer   *self,
                                                RenderOpBuilder       *builder,
@@ -2148,15 +2192,30 @@ render_inset_shadow_node (GskGLRenderer   *self,
 
 }
 
+/* Spread *grows* the outline. The offset moves the shadow and leaves the
+ * inner rect where it was */
 static inline void
 render_unblurred_outset_shadow_node (GskGLRenderer   *self,
                                      GskRenderNode   *node,
                                      RenderOpBuilder *builder)
 {
   const GskRoundedRect *outline = gsk_outset_shadow_node_peek_outline (node);
+  const float x = node->bounds.origin.x;
+  const float y = node->bounds.origin.y;
+  const float w = node->bounds.size.width;
+  const float h = node->bounds.size.height;
   const float spread = gsk_outset_shadow_node_get_spread (node);
   const float dx = gsk_outset_shadow_node_get_dx (node);
   const float dy = gsk_outset_shadow_node_get_dy (node);
+  const float edge_sizes[] = { // Top, right, bottom, left
+    spread - dy, spread + dx, spread + dy, spread - dx
+  };
+  const float corner_sizes[][2] = { // top left, top right, bottom right, bottom left
+    { outline->corner[0].width + spread - dx, outline->corner[0].height + spread - dy },
+    { outline->corner[1].width + spread + dx, outline->corner[1].height + spread - dy },
+    { outline->corner[2].width + spread + dx, outline->corner[2].height + spread + dy },
+    { outline->corner[3].width + spread - dx, outline->corner[3].height + spread + dy },
+  };
 
   ops_set_program (builder, &self->programs->unblurred_outset_shadow_program);
   ops_set_unblurred_outset_shadow (builder, transform_rect (self, builder, outline),
@@ -2164,7 +2223,40 @@ render_unblurred_outset_shadow_node (GskGLRenderer   *self,
                                    gsk_outset_shadow_node_peek_color (node),
                                    dx, dy);
 
-  load_vertex_data (ops_draw (builder, NULL), node, builder);
+  /* Corners... */
+  if (corner_sizes[0][0] > 0 && corner_sizes[0][1] > 0) /* Top left */
+      load_float_vertex_data (ops_draw (builder, NULL), builder,
+                              x, y,
+                              corner_sizes[0][0], corner_sizes[0][1]);
+  if (corner_sizes[1][0] > 0 && corner_sizes[1][1] > 0) /* Top right */
+      load_float_vertex_data (ops_draw (builder, NULL), builder,
+                              x + w - corner_sizes[1][0], y,
+                              corner_sizes[1][0], corner_sizes[1][1]);
+  if (corner_sizes[2][0] > 0 && corner_sizes[2][1] > 0) /* Bottom right */
+      load_float_vertex_data (ops_draw (builder, NULL), builder,
+                              x + w - corner_sizes[2][0], y + h - corner_sizes[2][1],
+                              corner_sizes[2][0], corner_sizes[2][1]);
+  if (corner_sizes[3][0] > 0 && corner_sizes[3][1] > 0) /* Bottom left */
+      load_float_vertex_data (ops_draw (builder, NULL), builder,
+                              x, y + h - corner_sizes[3][1],
+                              corner_sizes[3][0], corner_sizes[3][1]);
+  /* Edges... */;
+  if (edge_sizes[0] > 0) /* Top */
+    load_float_vertex_data (ops_draw (builder, NULL), builder,
+                            x + corner_sizes[0][0], y,
+                            w - corner_sizes[0][0] - corner_sizes[1][0], edge_sizes[0]);
+  if (edge_sizes[1] > 0) /* Right */
+    load_float_vertex_data (ops_draw (builder, NULL), builder,
+                            x + w - edge_sizes[1], y + corner_sizes[1][1],
+                            edge_sizes[1], h - corner_sizes[1][1] - corner_sizes[2][1]);
+  if (edge_sizes[2] > 0) /* Bottom */
+    load_float_vertex_data (ops_draw (builder, NULL), builder,
+                            x + corner_sizes[3][0], y + h - edge_sizes[2],
+                            w - corner_sizes[3][0] - corner_sizes[2][0], edge_sizes[2]);
+  if (edge_sizes[3] > 0) /* Left */
+    load_float_vertex_data (ops_draw (builder, NULL), builder,
+                            x, y + corner_sizes[0][1],
+                            edge_sizes[3], h - corner_sizes[0][1] - corner_sizes[3][1]);
 }
 
 


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