[gtk/wip/baedert/for-master: 20/22] gl renderer: Fix viewport computation when rendering offscreen




commit 79f273348d9546c3d2a7e1ee9ce4516eb3dc20da
Author: Timm Bäder <mail baedert org>
Date:   Fri Jan 29 09:43:44 2021 +0100

    gl renderer: Fix viewport computation when rendering offscreen
    
    Fixes #3615

 gsk/gl/gskglrenderer.c                |  32 ++++++++++++++++----------------
 testsuite/gsk/compare/issue-3615.node |  27 +++++++++++++++++++++++++++
 testsuite/gsk/compare/issue-3615.png  | Bin 0 -> 385 bytes
 testsuite/gsk/meson.build             |   1 +
 4 files changed, 44 insertions(+), 16 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 7f1aa2c6cd..5a15bf5911 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -3833,7 +3833,7 @@ add_offscreen_ops (GskGLRenderer         *self,
 {
   const float dx = builder->dx;
   const float dy = builder->dy;
-  float width, height;
+  float scaled_width, scaled_height;
   float scale_x;
   float scale_y;
   int render_target;
@@ -3889,8 +3889,6 @@ add_offscreen_ops (GskGLRenderer         *self,
       return TRUE;
     }
 
-  width = bounds->size.width;
-  height = bounds->size.height;
   scale_x = builder->scale_x;
   scale_y = builder->scale_y;
 
@@ -3901,23 +3899,23 @@ add_offscreen_ops (GskGLRenderer         *self,
   {
     const int max_texture_size = gsk_gl_driver_get_max_texture_size (self->gl_driver);
 
-    width = ceilf (width * scale_x);
-    if (width > max_texture_size)
+    scaled_width = ceilf (bounds->size.width * scale_x);
+    if (scaled_width > max_texture_size)
       {
-        scale_x *= (float)max_texture_size / width;
-        width = max_texture_size;
+        scale_x *= (float)max_texture_size / scaled_width;
+        scaled_width = max_texture_size;
       }
 
-    height = ceilf (height * scale_y);
-    if (height > max_texture_size)
+    scaled_height = ceilf (bounds->size.height * scale_y);
+    if (scaled_height > max_texture_size)
       {
-        scale_y *= (float)max_texture_size / height;
-        height = max_texture_size;
+        scale_y *= (float)max_texture_size / scaled_height;
+        scaled_height = max_texture_size;
       }
   }
 
   gsk_gl_driver_create_render_target (self->gl_driver,
-                                      width, height,
+                                      scaled_width, scaled_height,
                                       filter, filter,
                                       &texture_id, &render_target);
   if (gdk_gl_context_has_debug (self->gl_context))
@@ -3932,9 +3930,11 @@ add_offscreen_ops (GskGLRenderer         *self,
                                           render_target);
     }
 
-  viewport = GRAPHENE_RECT_INIT ((bounds->origin.x + dx) * scale_x,
-                                 (bounds->origin.y + dy) * scale_y,
-                                 width, height);
+  ops_transform_bounds_modelview (builder, bounds, &viewport);
+  /* Code above will scale the size with the scale we use in the render ops,
+   * but for the viewport size, we need our own size limited by the texture size */
+  viewport.size.width = scaled_width;
+  viewport.size.height = scaled_height;
 
   init_projection_matrix (&item_proj, &viewport);
   prev_render_target = ops_set_render_target (builder, render_target);
@@ -3962,7 +3962,7 @@ add_offscreen_ops (GskGLRenderer         *self,
                                              g_type_name_from_instance ((GTypeInstance *) child_node),
                                              child_node,
                                              k ++),
-                            width, height);
+                            scaled_width, scaled_height);
     }
 #endif
 
diff --git a/testsuite/gsk/compare/issue-3615.node b/testsuite/gsk/compare/issue-3615.node
new file mode 100644
index 0000000000..4830529fe0
--- /dev/null
+++ b/testsuite/gsk/compare/issue-3615.node
@@ -0,0 +1,27 @@
+transform {
+  child: clip {
+    child: transform {
+      child: rounded-clip {
+        child: color {
+          bounds: 0 0 50 50;
+          color: rgb(255,0,0);
+        }
+        clip: 0 0 30 30 / 15;
+      }
+      transform: scale(10);
+    }
+    clip: 250 0 587 166;
+  }
+  transform: translate(0, 100);
+}
+
+color { color: black; bounds: 250 135 5 10; }
+color { color: black; bounds: 255 140 5 10; }
+color { color: black; bounds: 260 145 5 10; }
+color { color: black; bounds: 265 150 5 10; }
+color { color: black; bounds: 270 158 5 10; }
+color { color: black; bounds: 275 166 5 10; }
+color { color: black; bounds: 280 175 5 10; }
+color { color: black; bounds: 285 184 5 13; }
+color { color: black; bounds: 290 195 5 20; }
+color { color: black; bounds: 295 211 5 55; }
diff --git a/testsuite/gsk/compare/issue-3615.png b/testsuite/gsk/compare/issue-3615.png
new file mode 100644
index 0000000000..32200a88c6
Binary files /dev/null and b/testsuite/gsk/compare/issue-3615.png differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index c23d371e3e..dbe7b9710c 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -75,6 +75,7 @@ compare_render_tests = [
   'clip-in-rounded-clip1',
   'clip-in-rounded-clip2',
   'clip-in-rounded-clip3',
+  'issue-3615'
 ]
 
 # these are too sensitive to differences in the renderers


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