[gtk/wip/baedert/for-master] gl: Linear gradients don't support 3d transforms




commit fd6b3ef5a0ea9e240f5cc5b5714ee11f1c24baf7
Author: Timm Bäder <mail baedert org>
Date:   Fri Dec 10 20:07:39 2021 +0100

    gl: Linear gradients don't support 3d transforms
    
    Add another helper similar to the one for transforms, but that only
    works on 2d transforms.
    
    Fixes #4501

 gsk/gl/gskglrenderjob.c                       |  87 ++++++++++++++++++++------
 testsuite/gsk/compare/linear-gradient-3d.node |  13 ++++
 testsuite/gsk/compare/linear-gradient-3d.png  | Bin 0 -> 151 bytes
 testsuite/gsk/meson.build                     |   8 +--
 4 files changed, 86 insertions(+), 22 deletions(-)
---
diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c
index 1862191118..a0df3e2990 100644
--- a/gsk/gl/gskglrenderjob.c
+++ b/gsk/gl/gskglrenderjob.c
@@ -245,6 +245,47 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
                                   self->corner[1].height + self->corner[2].height);
 }
 
+static inline gboolean G_GNUC_PURE
+node_supports_2d_transform (const GskRenderNode *node)
+{
+  switch ((int)gsk_render_node_get_node_type (node))
+    {
+    case GSK_COLOR_NODE:
+    case GSK_OPACITY_NODE:
+    case GSK_COLOR_MATRIX_NODE:
+    case GSK_TEXTURE_NODE:
+    case GSK_CROSS_FADE_NODE:
+    case GSK_LINEAR_GRADIENT_NODE:
+    case GSK_REPEATING_LINEAR_GRADIENT_NODE:
+    case GSK_CONIC_GRADIENT_NODE:
+    case GSK_RADIAL_GRADIENT_NODE:
+    case GSK_REPEATING_RADIAL_GRADIENT_NODE:
+    case GSK_DEBUG_NODE:
+    case GSK_TEXT_NODE:
+    case GSK_CAIRO_NODE:
+    case GSK_BLEND_NODE:
+    case GSK_BLUR_NODE:
+      return TRUE;
+
+    case GSK_SHADOW_NODE:
+      return node_supports_2d_transform (gsk_shadow_node_get_child (node));
+
+    case GSK_TRANSFORM_NODE:
+      return node_supports_2d_transform (gsk_transform_node_get_child (node));
+
+    case GSK_CONTAINER_NODE:
+      for (guint i = 0, p = gsk_container_node_get_n_children (node); i < p; i++)
+        {
+          if (!node_supports_2d_transform (gsk_container_node_get_child (node, i)))
+            return FALSE;
+        }
+      return TRUE;
+
+    default:
+      return FALSE;
+    }
+}
+
 static inline gboolean G_GNUC_PURE
 node_supports_transform (const GskRenderNode *node)
 {
@@ -257,24 +298,26 @@ node_supports_transform (const GskRenderNode *node)
 
   switch ((int)gsk_render_node_get_node_type (node))
     {
-      case GSK_COLOR_NODE:
-      case GSK_OPACITY_NODE:
-      case GSK_COLOR_MATRIX_NODE:
-      case GSK_TEXTURE_NODE:
-      case GSK_CROSS_FADE_NODE:
-      case GSK_LINEAR_GRADIENT_NODE:
-      case GSK_DEBUG_NODE:
-      case GSK_TEXT_NODE:
-        return TRUE;
-
-      case GSK_SHADOW_NODE:
-        return node_supports_transform (gsk_shadow_node_get_child (node));
-
-      case GSK_TRANSFORM_NODE:
-        return node_supports_transform (gsk_transform_node_get_child (node));
-
-      default:
-        return FALSE;
+    case GSK_COLOR_NODE:
+    case GSK_OPACITY_NODE:
+    case GSK_COLOR_MATRIX_NODE:
+    case GSK_TEXTURE_NODE:
+    case GSK_CROSS_FADE_NODE:
+    case GSK_DEBUG_NODE:
+    case GSK_TEXT_NODE:
+    case GSK_CAIRO_NODE:
+    case GSK_BLEND_NODE:
+    case GSK_BLUR_NODE:
+      return TRUE;
+
+    case GSK_SHADOW_NODE:
+      return node_supports_transform (gsk_shadow_node_get_child (node));
+
+    case GSK_TRANSFORM_NODE:
+      return node_supports_transform (gsk_transform_node_get_child (node));
+
+    default:
+      return FALSE;
     }
 }
 
@@ -2017,6 +2060,14 @@ gsk_gl_render_job_visit_transform_node (GskGLRenderJob      *job,
     break;
 
     case GSK_TRANSFORM_CATEGORY_2D:
+      if (node_supports_2d_transform (child))
+        {
+          gsk_gl_render_job_push_modelview (job, transform);
+          gsk_gl_render_job_visit_node (job, child);
+          gsk_gl_render_job_pop_modelview (job);
+          return;
+        }
+      G_GNUC_FALLTHROUGH;
     case GSK_TRANSFORM_CATEGORY_3D:
     case GSK_TRANSFORM_CATEGORY_ANY:
     case GSK_TRANSFORM_CATEGORY_UNKNOWN:
diff --git a/testsuite/gsk/compare/linear-gradient-3d.node b/testsuite/gsk/compare/linear-gradient-3d.node
new file mode 100644
index 0000000000..b3ba197779
--- /dev/null
+++ b/testsuite/gsk/compare/linear-gradient-3d.node
@@ -0,0 +1,13 @@
+clip {
+  clip: 0 -25 50 50;
+  child: transform {
+    transform: perspective(100) rotateY(45);
+    child: linear-gradient {
+        bounds: 0 -100 200 200;
+        start: 0 -100;
+        end: 0 100;
+        stops: 0.5 red,
+         0.5 lime;
+   }
+ }
+}
diff --git a/testsuite/gsk/compare/linear-gradient-3d.png b/testsuite/gsk/compare/linear-gradient-3d.png
new file mode 100644
index 0000000000..2ac3fd1e44
Binary files /dev/null and b/testsuite/gsk/compare/linear-gradient-3d.png differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index 23821da279..71e18f824d 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -93,10 +93,10 @@ informative_render_tests = [
 ]
 
 renderers = [
-  # name      exclude term
-  [ 'gl', ''    ],
-  [ 'broadway',  '-3d' ],
-  [ 'cairo',  '-3d' ],
+  # name          exclude term
+  [ 'gl', ''           ],
+  [ 'broadway',   '-3d' ],
+  [ 'cairo',      '-3d' ],
 ]
 
 foreach renderer : renderers


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