From dd330689438c880548bfd684e333a98a34f9b9d9 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jul 2024 20:27:59 +0200 Subject: [PATCH] gpu: Implement add_first_node for containers Containers can walk the list of children back to front, trying to find the topmost node that fully covers the viewport. And then they can skip drawing all the nodes before that one. --- gsk/gpu/gskgpunodeprocessor.c | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 35463fd292..de0a0f6e07 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -2881,16 +2881,50 @@ static void gsk_gpu_node_processor_add_container_node (GskGpuNodeProcessor *self, GskRenderNode *node) { + gsize i; + if (self->opacity < 1.0 && !gsk_container_node_is_disjoint (node)) { gsk_gpu_node_processor_add_without_opacity (self, node); return; } - for (guint i = 0; i < gsk_container_node_get_n_children (node); i++) + for (i = 0; i < gsk_container_node_get_n_children (node); i++) gsk_gpu_node_processor_add_node (self, gsk_container_node_get_child (node, i)); } +static gboolean +gsk_gpu_node_processor_add_first_container_node (GskGpuNodeProcessor *self, + GskGpuImage *target, + const cairo_rectangle_int_t *clip, + GskRenderPassType pass_type, + GskRenderNode *node) +{ + gsize i, n; + + n = gsk_container_node_get_n_children (node); + if (n == 0) + return FALSE; + + for (i = n - 1; ; i--) + { + if (gsk_gpu_node_processor_add_first_node (self, + target, + clip, + pass_type, + gsk_container_node_get_child (node, i))) + break; + + if (i == 0) + return FALSE; + } + + for (i = i + 1; i < n; i++) + gsk_gpu_node_processor_add_node (self, gsk_container_node_get_child (node, i)); + + return TRUE; +} + static void gsk_gpu_node_processor_add_debug_node (GskGpuNodeProcessor *self, GskRenderNode *node) @@ -2944,7 +2978,7 @@ static const struct GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR, GSK_GPU_HANDLE_OPACITY, gsk_gpu_node_processor_add_container_node, - NULL + gsk_gpu_node_processor_add_first_container_node, NULL, }, [GSK_CAIRO_NODE] = {