vulkan: Don't draw fully clipped nodes
authorBenjamin Otte <otte@redhat.com>
Thu, 18 May 2023 01:03:10 +0000 (03:03 +0200)
committerBenjamin Otte <otte@redhat.com>
Sun, 4 Jun 2023 17:42:01 +0000 (19:42 +0200)
... if they are container nodes. Other nodes will get culled by the
vertex shader.

gsk/vulkan/gskvulkanclip.c
gsk/vulkan/gskvulkanclipprivate.h
gsk/vulkan/gskvulkanrenderpass.c

index 674c5011f17dd3941ba57abdcdbdb4c97b4f7f9f..dcc42c51837fe9e29110b647362aa80d145d412f 100644 (file)
@@ -240,6 +240,34 @@ gsk_vulkan_clip_transform (GskVulkanClip         *dest,
     }
 }
 
+gboolean
+gsk_vulkan_clip_intersects_rect (const GskVulkanClip    *self,
+                                 const graphene_point_t *offset,
+                                 const graphene_rect_t  *rect)
+{
+  graphene_rect_t r = *rect;
+  r.origin.x += offset->x;
+  r.origin.y += offset->y;
+
+  switch (self->type)
+    {
+    default:
+      g_assert_not_reached();
+    case GSK_VULKAN_CLIP_ALL_CLIPPED:
+      return FALSE;
+
+    case GSK_VULKAN_CLIP_NONE:
+      return TRUE;
+
+    case GSK_VULKAN_CLIP_RECT:
+      return graphene_rect_intersection (&self->rect.bounds, &r, NULL);
+
+    case GSK_VULKAN_CLIP_ROUNDED_CIRCULAR:
+    case GSK_VULKAN_CLIP_ROUNDED:
+      return gsk_rounded_rect_intersects_rect (&self->rect, &r);
+    }
+}
+
 gboolean
 gsk_vulkan_clip_contains_rect (const GskVulkanClip    *self,
                                const graphene_point_t *offset,
index b311c076234842793a8c7e97c668b9f9cb5661a5..303cbf0cb87ca0501d95206ae581b6f13c2b3d51 100644 (file)
@@ -57,6 +57,9 @@ gboolean                gsk_vulkan_clip_transform                       (GskVulk
 gboolean                gsk_vulkan_clip_contains_rect                   (const GskVulkanClip    *self,
                                                                          const graphene_point_t *offset,
                                                                          const graphene_rect_t  *rect) G_GNUC_WARN_UNUSED_RESULT;
+gboolean                gsk_vulkan_clip_intersects_rect                 (const GskVulkanClip    *self,
+                                                                         const graphene_point_t *offset,
+                                                                         const graphene_rect_t  *rect) G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 
index 8bbdc9ed2c673b9ffaede3b2c860b58e7e9a34d0..4b2fe0699dde23c52329d3274d4d3e97dff06644 100644 (file)
@@ -331,6 +331,9 @@ gsk_vulkan_render_pass_add_container_node (GskVulkanRenderPass       *self,
                                            const GskVulkanParseState *state,
                                            GskRenderNode             *node)
 {
+  if (!gsk_vulkan_clip_intersects_rect (&state->clip, &state->offset, &node->bounds))
+    return TRUE;
+
   for (guint i = 0; i < gsk_container_node_get_n_children (node); i++)
     gsk_vulkan_render_pass_add_node (self, render, state, gsk_container_node_get_child (node, i));