[gtk/gl-linear] Add some tests for the axis-aligned check



commit 3b6941b04bd4de4c7aa47ee140d347e8b9e8e6df
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Sep 7 14:20:38 2020 -0400

    Add some tests for the axis-aligned check

 testsuite/gsk/transform.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)
---
diff --git a/testsuite/gsk/transform.c b/testsuite/gsk/transform.c
index 6439952c3e..9a2fa1ffe3 100644
--- a/testsuite/gsk/transform.c
+++ b/testsuite/gsk/transform.c
@@ -406,6 +406,122 @@ test_print_parse (void)
     }
 }
 
+static void
+gsk_matrix_transform_rect (const graphene_matrix_t *m,
+                           const graphene_rect_t   *r,
+                           graphene_quad_t         *res)
+{
+  graphene_point_t ret[4];
+  graphene_rect_t rr;
+
+  graphene_rect_normalize_r (r, &rr);
+
+#define TRANSFORM_POINT(matrix, rect, corner, out_p)   do {\
+  graphene_vec4_t __s; \
+  graphene_point_t __p; \
+  float w; \
+  graphene_rect_get_ ## corner (rect, &__p); \
+  graphene_vec4_init (&__s, __p.x, __p.y, 0.f, 1.f); \
+  graphene_matrix_transform_vec4 (matrix, &__s, &__s); \
+  w = graphene_vec4_get_w (&__s); \
+  out_p.x = graphene_vec4_get_x (&__s) / w; \
+  out_p.y = graphene_vec4_get_y (&__s) / w;           } while (0)
+
+  TRANSFORM_POINT (m, &rr, top_left, ret[0]);
+  TRANSFORM_POINT (m, &rr, top_right, ret[1]);
+  TRANSFORM_POINT (m, &rr, bottom_right, ret[2]);
+  TRANSFORM_POINT (m, &rr, bottom_left, ret[3]);
+
+#undef TRANSFORM_POINT
+
+  graphene_quad_init (res, &ret[0], &ret[1], &ret[2], &ret[3]);
+}
+
+/* This is an auxiliary function used in the GL renderer to
+ * determine if transforming an axis-aligned rectangle produces
+ * axis-aligned output, to decide whether to use linear
+ * interpolation or not.
+ *
+ * Keep this in sync with gsk/gl/gskglrenderer.c
+ */
+static gboolean
+result_is_axis_aligned (GskTransform          *transform,
+                        const graphene_rect_t *bounds)
+{
+  graphene_matrix_t m;
+  graphene_quad_t q;
+  graphene_rect_t b;
+  graphene_point_t b1, b2;
+  const graphene_point_t *p;
+  int i;
+
+  gsk_transform_to_matrix (transform, &m);
+  gsk_matrix_transform_rect (&m, bounds, &q);
+  graphene_quad_bounds (&q, &b);
+  graphene_rect_get_top_left (&b, &b1);
+  graphene_rect_get_bottom_right (&b, &b2);
+
+  for (i = 0; i < 4; i++)
+    {
+      p = graphene_quad_get_point (&q, i);
+      if (fabs (p->x - b1.x) > FLT_EPSILON && fabs (p->x - b2.x) > FLT_EPSILON)
+        return FALSE;
+      if (fabs (p->y - b1.y) > FLT_EPSILON && fabs (p->y - b2.y) > FLT_EPSILON)
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+test_axis_aligned (void)
+{
+  graphene_rect_t r = GRAPHENE_RECT_INIT (0, 0, 10, 10);
+  GskTransform *transform = NULL;
+
+  transform = gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (10, 10));
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  transform = gsk_transform_translate_3d (NULL, &GRAPHENE_POINT3D_INIT(0, 10, 10));
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  transform = gsk_transform_rotate (NULL, 90);
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  transform = gsk_transform_scale (NULL, 2, 3);
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  /* rotating around the y axis does not affect axis alignedness,
+   * as long as we don't involve perspective
+   */
+  transform = gsk_transform_rotate_3d (NULL, 45, graphene_vec3_y_axis ());
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  /* rotating by 45 around the z axis, not axis aligned */
+  transform = gsk_transform_rotate (NULL, 45);
+  g_assert_false (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  /* perspective is harmless as long as we stay in the z=0 plane */
+  transform = gsk_transform_perspective (NULL, 100);
+  g_assert_true (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+
+  /* a complex transform that makes things look '3d' */
+  transform = gsk_transform_translate_3d (NULL, &GRAPHENE_POINT3D_INIT (0, 0, 50));
+  transform = gsk_transform_perspective (transform, 170);
+  transform = gsk_transform_translate_3d (transform, &GRAPHENE_POINT3D_INIT (50, 0, 50));
+  transform = gsk_transform_rotate (transform, 20);
+  transform = gsk_transform_rotate_3d (transform, 20, graphene_vec3_y_axis ());
+  g_assert_false (result_is_axis_aligned (transform, &r));
+  gsk_transform_unref (transform);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -418,6 +534,7 @@ main (int   argc,
   g_test_add_func ("/transform/identity-equal", test_identity_equal);
   g_test_add_func ("/transform/invert", test_invert);
   g_test_add_func ("/transform/print-parse", test_print_parse);
+  g_test_add_func ("/transform/check-axis-aligneness", test_axis_aligned);
 
   return g_test_run ();
 }


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