[gtk/modern-testsuite] ngl: Fix opacity handling
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/modern-testsuite] ngl: Fix opacity handling
- Date: Wed, 15 Sep 2021 18:45:29 +0000 (UTC)
commit 768ac8a97a3809aacd34c1daf70e67f2598c951b
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Sep 15 08:26:54 2021 -0400
ngl: Fix opacity handling
We need to use an offscreen whenever there is overlapping
children somewhere in the tree below, just checking the
direct child of the opacity node is not enough.
Fixes: #4261
gsk/ngl/gsknglrenderjob.c | 82 +++++++++++++++++++++++++++++++++++++++--------
1 file changed, 69 insertions(+), 13 deletions(-)
---
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 4b04310e66..6bc631bbd4 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -2768,6 +2768,58 @@ gsk_ngl_render_job_visit_cross_fade_node (GskNglRenderJob *job,
gsk_ngl_render_job_end_draw (job);
}
+static gboolean
+is_non_branching (const GskRenderNode *node)
+{
+ switch ((int)gsk_render_node_get_node_type (node))
+ {
+ case GSK_COLOR_NODE:
+ case GSK_LINEAR_GRADIENT_NODE:
+ case GSK_REPEATING_LINEAR_GRADIENT_NODE:
+ case GSK_RADIAL_GRADIENT_NODE:
+ case GSK_REPEATING_RADIAL_GRADIENT_NODE:
+ case GSK_CONIC_GRADIENT_NODE:
+ case GSK_BORDER_NODE:
+ case GSK_TEXTURE_NODE:
+ case GSK_INSET_SHADOW_NODE:
+ case GSK_OUTSET_SHADOW_NODE:
+ case GSK_TEXT_NODE:
+ case GSK_CAIRO_NODE:
+ return TRUE;
+
+ case GSK_TRANSFORM_NODE:
+ return is_non_branching (gsk_transform_node_get_child (node));
+
+ case GSK_OPACITY_NODE:
+ return is_non_branching (gsk_opacity_node_get_child (node));
+
+ case GSK_COLOR_MATRIX_NODE:
+ return is_non_branching (gsk_color_matrix_node_get_child (node));
+
+ case GSK_CLIP_NODE:
+ return is_non_branching (gsk_clip_node_get_child (node));
+
+ case GSK_ROUNDED_CLIP_NODE:
+ return is_non_branching (gsk_rounded_clip_node_get_child (node));
+
+ case GSK_SHADOW_NODE:
+ return is_non_branching (gsk_shadow_node_get_child (node));
+
+ case GSK_BLUR_NODE:
+ return is_non_branching (gsk_shadow_node_get_child (node));
+
+ case GSK_DEBUG_NODE:
+ return is_non_branching (gsk_debug_node_get_child (node));
+
+ case GSK_CONTAINER_NODE:
+ return gsk_container_node_get_n_children (node) == 1 &&
+ is_non_branching (gsk_container_node_get_child (node, 0));
+
+ default:
+ return FALSE;
+ }
+}
+
static inline void
gsk_ngl_render_job_visit_opacity_node (GskNglRenderJob *job,
const GskRenderNode *node)
@@ -2778,24 +2830,32 @@ gsk_ngl_render_job_visit_opacity_node (GskNglRenderJob *job,
if (!ALPHA_IS_CLEAR (new_alpha))
{
- float prev_alpha = gsk_ngl_render_job_set_alpha (job, new_alpha);
-
- if (gsk_render_node_get_node_type (child) == GSK_CONTAINER_NODE)
+ /* Handle a few easy cases without offscreen. We bail out
+ * as soon as we see nodes with multiple children - in theory,
+ * we would only need offscreens for overlapping children.
+ */
+ if (is_non_branching (child))
+ {
+ float prev_alpha = gsk_ngl_render_job_set_alpha (job, new_alpha);
+ gsk_ngl_render_job_visit_node (job, child);
+ gsk_ngl_render_job_set_alpha (job, prev_alpha);
+ }
+ else
{
GskNglRenderOffscreen offscreen = {0};
+ float prev_alpha;
offscreen.bounds = &child->bounds;
offscreen.force_offscreen = TRUE;
offscreen.reset_clip = TRUE;
- /* The semantics of an opacity node mandate that when, e.g., two
- * color nodes overlap, there may not be any blending between them.
- */
if (!gsk_ngl_render_job_visit_node_with_offscreen (job, child, &offscreen))
return;
g_assert (offscreen.texture_id);
+ prev_alpha = gsk_ngl_render_job_set_alpha (job, new_alpha);
+
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_ngl_program_set_uniform_texture (job->current_program,
UNIFORM_SHARED_SOURCE, 0,
@@ -2804,13 +2864,9 @@ gsk_ngl_render_job_visit_opacity_node (GskNglRenderJob *job,
offscreen.texture_id);
gsk_ngl_render_job_draw_offscreen (job, &node->bounds, &offscreen);
gsk_ngl_render_job_end_draw (job);
- }
- else
- {
- gsk_ngl_render_job_visit_node (job, child);
- }
- gsk_ngl_render_job_set_alpha (job, prev_alpha);
+ gsk_ngl_render_job_set_alpha (job, prev_alpha);
+ }
}
}
@@ -3999,7 +4055,7 @@ gsk_ngl_render_job_new (GskNglDriver *driver,
job->scale_y = scale_factor;
job->viewport = *viewport;
- gsk_ngl_render_job_set_alpha (job, 1.0);
+ gsk_ngl_render_job_set_alpha (job, 1.0f);
gsk_ngl_render_job_set_projection_from_rect (job, viewport, NULL);
gsk_ngl_render_job_set_modelview (job, gsk_transform_scale (NULL, scale_factor, scale_factor));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]