[gtk/nonoverlapping-containers: 3/4] gsk: Collect opacity information
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/nonoverlapping-containers: 3/4] gsk: Collect opacity information
- Date: Tue, 5 Apr 2022 18:58:53 +0000 (UTC)
commit 38eb182947894e956e575fde36ed41275b49dc05
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Apr 5 14:55:36 2022 -0400
gsk: Collect opacity information
Collect information about whether to use offscreens
for opacity during node construction, so we don't
need to walk the tree repeatedly, later.
gsk/gskrendernode.c | 19 ++++++++++++++++---
gsk/gskrendernodeimpl.c | 26 ++++++++++++++++++++++++++
gsk/gskrendernodeprivate.h | 3 +++
3 files changed, 45 insertions(+), 3 deletions(-)
---
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 295ddf698e..14a29c358c 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -58,14 +58,14 @@ value_render_node_init (GValue *value)
{
value->data[0].v_pointer = NULL;
}
-
+
static void
value_render_node_free_value (GValue *value)
{
if (value->data[0].v_pointer != NULL)
gsk_render_node_unref (value->data[0].v_pointer);
}
-
+
static void
value_render_node_copy_value (const GValue *src,
GValue *dst)
@@ -75,7 +75,7 @@ value_render_node_copy_value (const GValue *src,
else
dst->data[0].v_pointer = NULL;
}
-
+
static gpointer
value_render_node_peek_pointer (const GValue *value)
{
@@ -738,3 +738,16 @@ gsk_render_node_prefers_high_depth (const GskRenderNode *node)
{
return node->prefers_high_depth;
}
+
+/* Whether we need an offscreen to handle opacity correctly for this node.
+ * We don't if there is only one drawing node inside (could be child
+ * node, or grandchild, or...).
+ *
+ * For containers with multiple children, we can avoid the offscreen if
+ * the children are known not to overlap.
+ */
+gboolean
+gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node)
+{
+ return node->offscreen_for_opacity;
+}
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 53b7d35f9d..175c458848 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -139,6 +139,7 @@ gsk_color_node_new (const GdkRGBA *rgba,
self = gsk_render_node_alloc (GSK_COLOR_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
self->color = *rgba;
graphene_rect_init_from_rect (&node->bounds, bounds);
@@ -284,6 +285,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_LINEAR_GRADIENT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
graphene_point_init_from_point (&self->start, start);
@@ -336,6 +338,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_REPEATING_LINEAR_GRADIENT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
graphene_point_init_from_point (&self->start, start);
@@ -584,6 +587,7 @@ gsk_radial_gradient_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_RADIAL_GRADIENT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
graphene_point_init_from_point (&self->center, center);
@@ -652,6 +656,7 @@ gsk_repeating_radial_gradient_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_REPEATING_RADIAL_GRADIENT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
graphene_point_init_from_point (&self->center, center);
@@ -1030,6 +1035,7 @@ gsk_conic_gradient_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_CONIC_GRADIENT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
graphene_point_init_from_point (&self->center, center);
@@ -1413,6 +1419,7 @@ gsk_border_node_new (const GskRoundedRect *outline,
self = gsk_render_node_alloc (GSK_BORDER_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
gsk_rounded_rect_init_copy (&self->outline, outline);
memcpy (self->border_width, border_width, sizeof (self->border_width));
@@ -1559,6 +1566,7 @@ gsk_texture_node_new (GdkTexture *texture,
self = gsk_render_node_alloc (GSK_TEXTURE_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
self->texture = g_object_ref (texture);
graphene_rect_init_from_rect (&node->bounds, bounds);
@@ -2014,6 +2022,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline,
self = gsk_render_node_alloc (GSK_INSET_SHADOW_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
gsk_rounded_rect_init_copy (&self->outline, outline);
self->color = *color;
@@ -2313,6 +2322,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline,
self = gsk_render_node_alloc (GSK_OUTSET_SHADOW_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
gsk_rounded_rect_init_copy (&self->outline, outline);
self->color = *color;
@@ -2506,6 +2516,7 @@ gsk_cairo_node_new (const graphene_rect_t *bounds)
self = gsk_render_node_alloc (GSK_CAIRO_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
graphene_rect_init_from_rect (&node->bounds, bounds);
@@ -2748,9 +2759,11 @@ gsk_container_node_new (GskRenderNode **children,
self->disjoint &= !graphene_rect_intersection (&bounds, &(children[i]->bounds), NULL);
graphene_rect_union (&bounds, &(children[i]->bounds), &bounds);
node->prefers_high_depth |= gsk_render_node_prefers_high_depth (children[i]);
+ node->offscreen_for_opacity |= children[i]->offscreen_for_opacity;
}
graphene_rect_init_from_rect (&node->bounds, &bounds);
+ node->offscreen_for_opacity |= !self->disjoint;
}
return node;
@@ -2983,6 +2996,7 @@ gsk_transform_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_TRANSFORM_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
self->transform = gsk_transform_ref (transform);
@@ -3127,6 +3141,7 @@ gsk_opacity_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_OPACITY_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
self->opacity = CLAMP (opacity, 0.0, 1.0);
@@ -3330,6 +3345,7 @@ gsk_color_matrix_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_COLOR_MATRIX_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
graphene_matrix_init_from_matrix (&self->color_matrix, color_matrix);
@@ -3478,6 +3494,7 @@ gsk_repeat_node_new (const graphene_rect_t *bounds,
self = gsk_render_node_alloc (GSK_REPEAT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = TRUE;
graphene_rect_init_from_rect (&node->bounds, bounds);
@@ -3615,6 +3632,7 @@ gsk_clip_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_CLIP_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
graphene_rect_normalize_r (clip, &self->clip);
@@ -3748,6 +3766,7 @@ gsk_rounded_clip_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_ROUNDED_CLIP_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
gsk_rounded_rect_init_copy (&self->clip, clip);
@@ -3967,6 +3986,7 @@ gsk_shadow_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_SHADOW_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
self->n_shadows = n_shadows;
@@ -4163,6 +4183,7 @@ gsk_blend_node_new (GskRenderNode *bottom,
self = gsk_render_node_alloc (GSK_BLEND_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = TRUE;
self->bottom = gsk_render_node_ref (bottom);
self->top = gsk_render_node_ref (top);
@@ -4313,6 +4334,7 @@ gsk_cross_fade_node_new (GskRenderNode *start,
self = gsk_render_node_alloc (GSK_CROSS_FADE_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = TRUE;
self->start = gsk_render_node_ref (start);
self->end = gsk_render_node_ref (end);
@@ -4499,6 +4521,7 @@ gsk_text_node_new (PangoFont *font,
self = gsk_render_node_alloc (GSK_TEXT_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = FALSE;
self->font = g_object_ref (font);
self->color = *color;
@@ -4905,6 +4928,7 @@ gsk_blur_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_BLUR_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
self->radius = radius;
@@ -5034,6 +5058,7 @@ gsk_debug_node_new (GskRenderNode *child,
self = gsk_render_node_alloc (GSK_DEBUG_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = child->offscreen_for_opacity;
self->child = gsk_render_node_ref (child);
self->message = message;
@@ -5195,6 +5220,7 @@ gsk_gl_shader_node_new (GskGLShader *shader,
self = gsk_render_node_alloc (GSK_GL_SHADER_NODE);
node = (GskRenderNode *) self;
+ node->offscreen_for_opacity = TRUE;
graphene_rect_init_from_rect (&node->bounds, bounds);
self->shader = g_object_ref (shader);
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 637e6cb4fd..02bd846979 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -29,6 +29,7 @@ struct _GskRenderNode
graphene_rect_t bounds;
guint prefers_high_depth : 1;
+ guint offscreen_for_opacity : 1;
};
struct _GskRenderNodeClass
@@ -115,6 +116,8 @@ gboolean gsk_render_node_prefers_high_depth (const GskRenderNode *no
gboolean gsk_container_node_is_disjoint (const GskRenderNode *node);
+gboolean gsk_render_node_use_offscreen_for_opacity (const GskRenderNode *node);
+
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]