gsk: Add high depth rendernode api
authorMatthias Clasen <mclasen@redhat.com>
Fri, 1 Oct 2021 20:23:12 +0000 (16:23 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 7 Oct 2021 01:35:25 +0000 (21:35 -0400)
Add private api to find out if the content
of a render node should be considered 'deep'.

The information is collected at creation time,
so there is no tree-walking involved when we
are using this information in the renderer.

Currently, this comes down to whether there are
any texture nodes with high depth textures in the subtree.
In the future, we may want to allow marking gradient
nodes in this way as well.

gsk/gskrendernode.c
gsk/gskrendernodeimpl.c
gsk/gskrendernodeprivate.h

index 9c4332fe010f2a36aee1b38494096b7cf74a0a00..6381d334d8e53b498cb02b3548926b7e991fd226 100644 (file)
@@ -725,3 +725,8 @@ gsk_value_dup_render_node (const GValue *value)
   return gsk_render_node_ref (value->data[0].v_pointer);
 }
 
+gboolean
+gsk_render_node_prefers_high_depth (const GskRenderNode *node)
+{
+  return node->prefers_high_depth;
+}
index fd2a9e5d4422136636f27faff0e96d0c85f36a54..28cb14ae642ec1bad5672ac55e983478c1fcec82 100644 (file)
@@ -28,6 +28,7 @@
 #include "gsktransformprivate.h"
 
 #include "gdk/gdktextureprivate.h"
+#include "gdk/gdkmemoryformatprivate.h"
 #include "gdk/gdk-private.h"
 
 #include <hb-ot.h>
@@ -1560,6 +1561,8 @@ gsk_texture_node_new (GdkTexture            *texture,
   self->texture = g_object_ref (texture);
   graphene_rect_init_from_rect (&node->bounds, bounds);
 
+  node->prefers_high_depth = gdk_memory_format_prefers_high_depth (gdk_texture_get_format (texture));
+
   return node;
 }
 
@@ -2730,11 +2733,13 @@ gsk_container_node_new (GskRenderNode **children,
 
       self->children[0] = gsk_render_node_ref (children[0]);
       graphene_rect_init_from_rect (&bounds, &(children[0]->bounds));
+      node->prefers_high_depth = gsk_render_node_prefers_high_depth (children[0]);
 
       for (guint i = 1; i < n_children; i++)
         {
           self->children[i] = gsk_render_node_ref (children[i]);
           graphene_rect_union (&bounds, &(children[i]->bounds), &bounds);
+          node->prefers_high_depth |= gsk_render_node_prefers_high_depth (children[i]);
         }
 
       graphene_rect_init_from_rect (&node->bounds, &bounds);
@@ -2965,6 +2970,8 @@ gsk_transform_node_new (GskRenderNode *child,
                                   &child->bounds,
                                   &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3100,6 +3107,8 @@ gsk_opacity_node_new (GskRenderNode *child,
 
   graphene_rect_init_from_rect (&node->bounds, &child->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3302,6 +3311,8 @@ gsk_color_matrix_node_new (GskRenderNode           *child,
 
   graphene_rect_init_from_rect (&node->bounds, &child->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3451,6 +3462,8 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
   else
     graphene_rect_init_from_rect (&self->child_bounds, &child->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3582,6 +3595,8 @@ gsk_clip_node_new (GskRenderNode         *child,
 
   graphene_rect_intersection (&self->clip, &child->bounds, &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3713,6 +3728,8 @@ gsk_rounded_clip_node_new (GskRenderNode         *child,
 
   graphene_rect_intersection (&self->clip.bounds, &child->bounds, &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -3932,6 +3949,8 @@ gsk_shadow_node_new (GskRenderNode   *child,
 
   gsk_shadow_node_get_bounds (self, &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -4125,6 +4144,8 @@ gsk_blend_node_new (GskRenderNode *bottom,
 
   graphene_rect_union (&bottom->bounds, &top->bounds, &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (bottom) || gsk_render_node_prefers_high_depth (top);
+
   return node;
 }
 
@@ -4273,6 +4294,8 @@ gsk_cross_fade_node_new (GskRenderNode *start,
 
   graphene_rect_union (&start->bounds, &end->bounds, &node->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (start) || gsk_render_node_prefers_high_depth (end);
+
   return node;
 }
 
@@ -4864,6 +4887,8 @@ gsk_blur_node_new (GskRenderNode *child,
                        - clip_radius,
                        - clip_radius);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -4986,6 +5011,8 @@ gsk_debug_node_new (GskRenderNode *child,
 
   graphene_rect_init_from_rect (&node->bounds, &child->bounds);
 
+  node->prefers_high_depth = gsk_render_node_prefers_high_depth (child);
+
   return node;
 }
 
@@ -5150,7 +5177,10 @@ gsk_gl_shader_node_new (GskGLShader           *shader,
     {
       self->children = g_malloc_n (n_children, sizeof (GskRenderNode *));
       for (guint i = 0; i < n_children; i++)
-        self->children[i] = gsk_render_node_ref (children[i]);
+        {
+          self->children[i] = gsk_render_node_ref (children[i]);
+          node->prefers_high_depth |= gsk_render_node_prefers_high_depth (children[i]);
+        }
     }
 
   return node;
index ac20813b65ac313cf501ee3f78cea79877b25224..cdb75afd2fff95977061e0568e8cf390815ac6c6 100644 (file)
@@ -27,6 +27,8 @@ struct _GskRenderNode
   gatomicrefcount ref_count;
 
   graphene_rect_t bounds;
+
+  guint prefers_high_depth : 1;
 };
 
 struct _GskRenderNodeClass
@@ -109,6 +111,7 @@ GskRenderNode ** gsk_container_node_get_children        (const GskRenderNode *no
 void             gsk_transform_node_get_translate       (const GskRenderNode *node,
                                                          float               *dx,
                                                          float               *dy);
+gboolean       gsk_render_node_prefers_high_depth       (const GskRenderNode *node);
 
 
 G_END_DECLS