[gtk] gl renderer: Fix opacity nodes with overlapping child nodes



commit b9b507266888a7e94cb6ef10f3e9bdea834f86d0
Author: Timm Bäder <mail baedert org>
Date:   Sat Jul 13 17:35:59 2019 +0200

    gl renderer: Fix opacity nodes with overlapping child nodes

 gsk/gl/gskglrenderer.c                             |  45 +++++++++++++++++++--
 .../gsk/compare/opacity-overlapping-children.node  |  13 ++++++
 .../gsk/compare/opacity-overlapping-children.png   | Bin 0 -> 512 bytes
 testsuite/gsk/meson.build                          |   3 +-
 4 files changed, 56 insertions(+), 5 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 46c9e64c1c..65fdc0c13e 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -1015,12 +1015,49 @@ render_opacity_node (GskGLRenderer   *self,
                      GskRenderNode   *node,
                      RenderOpBuilder *builder)
 {
+  GskRenderNode *child = gsk_opacity_node_get_child (node);
+  const float opacity = gsk_opacity_node_get_opacity (node);
   float prev_opacity;
 
-  prev_opacity = ops_set_opacity (builder,
-                                  builder->current_opacity * gsk_opacity_node_get_opacity (node));
+  if (gsk_render_node_get_node_type (child) == GSK_CONTAINER_NODE)
+    {
+      const float min_x = builder->dx + node->bounds.origin.x;
+      const float min_y = builder->dy + node->bounds.origin.y;
+      const float max_x = min_x + node->bounds.size.width;
+      const float max_y = min_y + node->bounds.size.height;
+      gboolean is_offscreen;
+      TextureRegion region;
+
+      /* The semantics of an opacity node mandate that when, e.g., two color nodes overlap,
+       * there may not be any blending between them */
+      add_offscreen_ops (self, builder, &child->bounds,
+                         child,
+                         &region, &is_offscreen,
+                         FORCE_OFFSCREEN | RESET_OPACITY | RESET_CLIP);
 
-  gsk_gl_renderer_add_render_ops (self, gsk_opacity_node_get_child (node), builder);
+      prev_opacity = ops_set_opacity (builder,
+                                      builder->current_opacity * opacity);
+
+      ops_set_program (builder, &self->blit_program);
+      ops_set_texture (builder, region.texture_id);
+
+      ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) {
+        { { min_x, min_y }, { region.x,  region.y2 }, },
+        { { min_x, max_y }, { region.x,  region.y  }, },
+        { { max_x, min_y }, { region.x2, region.y2 }, },
+
+        { { max_x, max_y }, { region.x2, region.y  }, },
+        { { min_x, max_y }, { region.x,  region.y  }, },
+        { { max_x, min_y }, { region.x2, region.y2 }, },
+      });
+    }
+  else
+    {
+      prev_opacity = ops_set_opacity (builder,
+                                      builder->current_opacity * opacity);
+
+      gsk_gl_renderer_add_render_ops (self, child, builder);
+    }
 
   ops_set_opacity (builder, prev_opacity);
 }
@@ -1290,7 +1327,7 @@ render_rounded_clip_node (GskGLRenderer       *self,
         { { min_x, min_y }, { 0, 1 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
- 
+
         { { max_x, max_y }, { 1, 0 }, },
         { { min_x, max_y }, { 0, 0 }, },
         { { max_x, min_y }, { 1, 1 }, },
diff --git a/testsuite/gsk/compare/opacity-overlapping-children.node 
b/testsuite/gsk/compare/opacity-overlapping-children.node
new file mode 100644
index 0000000000..0267b594e4
--- /dev/null
+++ b/testsuite/gsk/compare/opacity-overlapping-children.node
@@ -0,0 +1,13 @@
+opacity {
+  opacity: 0.4;
+  child: container {
+     color {
+       color: blue;
+       bounds: 0 0 100 100;
+     }
+     color {
+       color: red;
+       bounds: 50 50 100 100;
+     }
+  }
+}
\ No newline at end of file
diff --git a/testsuite/gsk/compare/opacity-overlapping-children.png 
b/testsuite/gsk/compare/opacity-overlapping-children.png
new file mode 100644
index 0000000000..ef6784028a
Binary files /dev/null and b/testsuite/gsk/compare/opacity-overlapping-children.png differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index 2208c1a6d6..574f9368ca 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -58,7 +58,8 @@ compare_render_tests = [
   'texture-url',
   'color-matrix-identity',
   'clip-nested1',
-  'scale-up-down'
+  'scale-up-down',
+  'opacity-overlapping-children',
 ]
 
 renderers = [


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]