[gtk/wip/baedert/for-master: 213/213] gl renderer: Fix nested rounded clip rendering



commit 09f3d9916b06e3d236dee0b0148423b70d02ba05
Author: Timm Bäder <mail baedert org>
Date:   Tue May 12 20:11:13 2020 +0200

    gl renderer: Fix nested rounded clip rendering
    
    If the inner clip intersects with the corners of the outer clip, we
    potentially need a texture. We should add more fine-grained checks for
    this in the future though.
    
    Test case included.

 gsk/gl/gskglrenderer.c                          |  33 ++++++++++++++++++++--
 testsuite/gsk/compare/nested-rounded-clips.node |  35 ++++++++++++++++++++++++
 testsuite/gsk/compare/nested-rounded-clips.png  | Bin 0 -> 469 bytes
 testsuite/gsk/meson.build                       |   1 +
 4 files changed, 67 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index ac8680ba0f..52fe7e9819 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -1163,6 +1163,35 @@ render_clip_node (GskGLRenderer   *self,
   render_clipped_child (self, builder, clip, child);
 }
 
+static inline gboolean
+rounded_inner_rect_contains_rect (const GskRoundedRect  *rounded,
+                                  const graphene_rect_t *rect)
+{
+  const graphene_rect_t *rounded_bounds = &rounded->bounds;
+  graphene_rect_t inner;
+  float offset_x, offset_y;
+
+  /* TODO: This is pretty conservative and we could to further, more
+   *       fine-grained checks to avoid offscreen drawing. */
+
+  offset_x = MAX (rounded->corner[GSK_CORNER_TOP_LEFT].width,
+                  rounded->corner[GSK_CORNER_BOTTOM_LEFT].width);
+  offset_y = MAX (rounded->corner[GSK_CORNER_TOP_LEFT].height,
+                  rounded->corner[GSK_CORNER_TOP_RIGHT].height);
+
+
+  inner.origin.x = rounded_bounds->origin.x + offset_x;
+  inner.origin.y = rounded_bounds->origin.y + offset_y;
+  inner.size.width = rounded_bounds->size.width - offset_x -
+                     MAX (rounded->corner[GSK_CORNER_TOP_RIGHT].width,
+                          rounded->corner[GSK_CORNER_BOTTOM_RIGHT].width);
+  inner.size.height= rounded_bounds->size.height - offset_y -
+                     MAX (rounded->corner[GSK_CORNER_BOTTOM_LEFT].height,
+                          rounded->corner[GSK_CORNER_BOTTOM_RIGHT].height);
+
+  return graphene_rect_contains_rect (&inner, rect);
+}
+
 static inline void
 render_rounded_clip_node (GskGLRenderer       *self,
                           GskRenderNode       *node,
@@ -1182,8 +1211,8 @@ render_rounded_clip_node (GskGLRenderer       *self,
 
   if (!ops_has_clip (builder))
     need_offscreen = FALSE;
-  else if (graphene_rect_contains_rect (&builder->current_clip->bounds,
-                                        &transformed_clip.bounds))
+  else if (rounded_inner_rect_contains_rect (builder->current_clip,
+                                             &transformed_clip.bounds))
     need_offscreen = FALSE;
   else
     need_offscreen = TRUE;
diff --git a/testsuite/gsk/compare/nested-rounded-clips.node b/testsuite/gsk/compare/nested-rounded-clips.node
new file mode 100644
index 0000000000..98646b28f7
--- /dev/null
+++ b/testsuite/gsk/compare/nested-rounded-clips.node
@@ -0,0 +1,35 @@
+  transform  {
+    child: rounded-clip {
+      child: rounded-clip {
+        clip: 10 10 30 30 / 5;
+        child: color {
+          color: teal;
+          bounds: 12 12 26 26;
+        }
+      }
+      clip: 10 10 30 30 / 25 0 0 0;
+    }
+
+    transform: scale(5);
+  }
+
+color {
+  color: black;
+  bounds: 55 100 40 40;
+}
+
+color {
+  color: black;
+  bounds: 70 80 20 20;
+}
+
+color {
+  color: black;
+  bounds: 90 70 40 40;
+}
+
+color {
+  color: black;
+  bounds: 105 55 30 20;
+}
+
diff --git a/testsuite/gsk/compare/nested-rounded-clips.png b/testsuite/gsk/compare/nested-rounded-clips.png
new file mode 100644
index 0000000000..8b954e1467
Binary files /dev/null and b/testsuite/gsk/compare/nested-rounded-clips.png differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index e9fdc661b7..225ce98261 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -66,6 +66,7 @@ compare_render_tests = [
   'blend-invisible-child',
   'transform-in-transform',
   'transform-in-transform-in-transform',
+  'nested-rounded-clips',
 ]
 
 # these are too sensitive to differences in the renderers


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