diff options
author | Matthias Clasen <mclasen@redhat.com> | 2023-05-11 13:11:56 +0000 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2023-05-11 13:11:56 +0000 |
commit | f11dd83ab53f04fc8e5e20fd6815add6cf10ff58 (patch) | |
tree | 8fbc2dbf43fd101ff3258bf984dd240bd47dbcce | |
parent | f10603e97d3502603cfc3346f934937b3178a420 (diff) | |
parent | b1945b38e846013c96e3cc29d4117060240903e9 (diff) | |
download | gtk+-f11dd83ab53f04fc8e5e20fd6815add6cf10ff58.tar.gz |
Merge branch 'matthiasc/for-main' into 'main'
gsk: Dispose the driver when the display is closed
See merge request GNOME/gtk!5948
-rw-r--r-- | .gitlab-ci.yml | 1 | ||||
-rw-r--r-- | gsk/gl/gskglcommandqueue.c | 2 | ||||
-rw-r--r-- | gsk/gl/gskgldriver.c | 27 | ||||
-rw-r--r-- | gsk/gskrenderer.c | 31 | ||||
-rw-r--r-- | gsk/gskrendererprivate.h | 2 | ||||
-rw-r--r-- | gtk/gtkpopover.c | 3 | ||||
-rw-r--r-- | gtk/gtktexthandle.c | 3 | ||||
-rw-r--r-- | gtk/gtktooltipwindow.c | 3 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 4 | ||||
-rw-r--r-- | gtk/gtkwindow.c | 3 | ||||
-rw-r--r-- | meson.build | 8 | ||||
-rw-r--r-- | testsuite/gsk/compare-render.c | 17 | ||||
-rw-r--r-- | testsuite/gsk/misc.c | 194 | ||||
-rw-r--r-- | testsuite/gsk/shader.c | 2 | ||||
-rw-r--r-- | testsuite/gsk/transform.c | 126 |
15 files changed, 370 insertions, 56 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 95bfa130b5..947c9e36ad 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -103,7 +103,6 @@ fedora-x86_64: - .gitlab-ci/run-tests.sh _build x11 - .gitlab-ci/run-tests.sh _build wayland - .gitlab-ci/run-tests.sh _build wayland_gles - - .gitlab-ci/run-tests.sh _build broadway release-build: extends: .build-fedora-default diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c index 30e3c83ba5..e7af501582 100644 --- a/gsk/gl/gskglcommandqueue.c +++ b/gsk/gl/gskglcommandqueue.c @@ -41,6 +41,7 @@ G_DEFINE_TYPE (GskGLCommandQueue, gsk_gl_command_queue, G_TYPE_OBJECT) +#if 0 G_GNUC_UNUSED static inline void print_uniform (GskGLUniformFormat format, guint array_count, @@ -231,6 +232,7 @@ gsk_gl_command_queue_capture_png (GskGLCommandQueue *self, gdk_texture_save_to_png (texture, filename); g_object_unref (texture); } +#endif static inline gboolean will_ignore_batch (GskGLCommandQueue *self) diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c index 1530056fcf..e81502cbe7 100644 --- a/gsk/gl/gskgldriver.c +++ b/gsk/gl/gskgldriver.c @@ -264,23 +264,20 @@ gsk_gl_driver_dispose (GObject *object) g_clear_object (&self->command_queue); } - if (self->autorelease_framebuffers->len > 0) + if (self->autorelease_framebuffers != NULL && + self->autorelease_framebuffers->len > 0) { glDeleteFramebuffers (self->autorelease_framebuffers->len, (GLuint *)(gpointer)self->autorelease_framebuffers->data); self->autorelease_framebuffers->len = 0; } - g_clear_pointer (&self->texture_pool, g_array_unref); - - g_assert (!self->textures || g_hash_table_size (self->textures) == 0); - g_assert (!self->texture_id_to_key || g_hash_table_size (self->texture_id_to_key) == 0); - g_assert (!self->key_to_texture_id|| g_hash_table_size (self->key_to_texture_id) == 0); - g_clear_object (&self->glyphs_library); g_clear_object (&self->icons_library); g_clear_object (&self->shadows_library); + g_clear_pointer (&self->texture_pool, g_array_unref); + g_clear_pointer (&self->autorelease_framebuffers, g_array_unref); g_clear_pointer (&self->key_to_texture_id, g_hash_table_unref); g_clear_pointer (&self->textures, g_hash_table_unref); @@ -474,6 +471,19 @@ gsk_gl_driver_new (GskGLCommandQueue *command_queue, return g_steal_pointer (&self); } +static void +free_driver (GskGLDriver *driver) +{ + g_object_run_dispose (G_OBJECT (driver)); + g_object_unref (driver); +} + +static void +display_closed (GdkDisplay *display) +{ + g_object_set_data (G_OBJECT (display), "GSK_GL_DRIVER", NULL); +} + /** * gsk_gl_driver_for_display: * @display: A #GdkDisplay that is known to support GL @@ -519,7 +529,8 @@ gsk_gl_driver_for_display (GdkDisplay *display, g_object_set_data_full (G_OBJECT (display), "GSK_GL_DRIVER", g_object_ref (driver), - g_object_unref); + (GDestroyNotify) free_driver); + g_signal_connect (display, "closed", G_CALLBACK (display_closed), NULL); failure: g_clear_object (&command_queue); diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 5bd214e026..3ff7c6abdd 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -238,24 +238,6 @@ gsk_renderer_get_surface (GskRenderer *renderer) return priv->surface; } -/*< private > - * gsk_renderer_get_root_node: - * @renderer: a `GskRenderer` - * - * Retrieves the `GskRenderNode` used by @renderer. - * - * Returns: (transfer none) (nullable): a `GskRenderNode` - */ -GskRenderNode * -gsk_renderer_get_root_node (GskRenderer *renderer) -{ - GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); - - g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL); - - return priv->root_node; -} - /** * gsk_renderer_is_realized: (attributes org.gtk.Method.get_property=realized) * @renderer: a `GskRenderer` @@ -313,6 +295,11 @@ gsk_renderer_realize (GskRenderer *renderer, } priv->is_realized = TRUE; + + g_object_notify (G_OBJECT (renderer), "realized"); + if (surface) + g_object_notify (G_OBJECT (renderer), "surface"); + return TRUE; } @@ -326,17 +313,25 @@ void gsk_renderer_unrealize (GskRenderer *renderer) { GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); + gboolean has_surface; g_return_if_fail (GSK_IS_RENDERER (renderer)); if (!priv->is_realized) return; + has_surface = priv->surface != NULL; + GSK_RENDERER_GET_CLASS (renderer)->unrealize (renderer); + g_clear_object (&priv->surface); g_clear_pointer (&priv->prev_node, gsk_render_node_unref); priv->is_realized = FALSE; + + g_object_notify (G_OBJECT (renderer), "realized"); + if (has_surface) + g_object_notify (G_OBJECT (renderer), "surface"); } /** diff --git a/gsk/gskrendererprivate.h b/gsk/gskrendererprivate.h index 1496a8658c..d286dae628 100644 --- a/gsk/gskrendererprivate.h +++ b/gsk/gskrendererprivate.h @@ -50,8 +50,6 @@ struct _GskRendererClass const cairo_region_t *invalid); }; -GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer); - GskProfiler * gsk_renderer_get_profiler (GskRenderer *renderer); GskDebugFlags gsk_renderer_get_debug_flags (GskRenderer *renderer); diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index 42e2b06384..b9fa4d2b72 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -1017,8 +1017,7 @@ gtk_popover_unrealize (GtkWidget *widget) g_signal_handlers_disconnect_by_func (priv->surface, surface_render, widget); g_signal_handlers_disconnect_by_func (priv->surface, surface_event, widget); gdk_surface_set_widget (priv->surface, NULL); - gdk_surface_destroy (priv->surface); - g_clear_object (&priv->surface); + g_clear_pointer (&priv->surface, gdk_surface_destroy); } static gboolean diff --git a/gtk/gtktexthandle.c b/gtk/gtktexthandle.c index a27db0bc6f..898e08f3b6 100644 --- a/gtk/gtktexthandle.c +++ b/gtk/gtktexthandle.c @@ -280,8 +280,7 @@ gtk_text_handle_unrealize (GtkWidget *widget) g_signal_handlers_disconnect_by_func (handle->surface, surface_mapped_changed, widget); gdk_surface_set_widget (handle->surface, NULL); - gdk_surface_destroy (handle->surface); - g_clear_object (&handle->surface); + g_clear_pointer (&handle->surface, gdk_surface_destroy); } static void diff --git a/gtk/gtktooltipwindow.c b/gtk/gtktooltipwindow.c index 341a606cf6..0802e09691 100644 --- a/gtk/gtktooltipwindow.c +++ b/gtk/gtktooltipwindow.c @@ -240,8 +240,7 @@ gtk_tooltip_window_unrealize (GtkWidget *widget) g_signal_handlers_disconnect_by_func (window->surface, surface_render, widget); g_signal_handlers_disconnect_by_func (window->surface, surface_event, widget); gdk_surface_set_widget (window->surface, NULL); - gdk_surface_destroy (window->surface); - g_clear_object (&window->surface); + g_clear_pointer (&window->surface, gdk_surface_destroy); } diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index b959b75789..61ac33bf1a 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -10239,8 +10239,8 @@ gtk_widget_do_pick (GtkWidget *widget, gsk_transform_unref (transform); graphene_point3d_init (&p0, x, y, 0); graphene_point3d_init (&p1, x, y, 1); - graphene_matrix_transform_point3d (&inv, &p0, &p0); - graphene_matrix_transform_point3d (&inv, &p1, &p1); + gsk_matrix_transform_point3d (&inv, &p0, &p0); + gsk_matrix_transform_point3d (&inv, &p1, &p1); if (fabs (p0.z - p1.z) < 1.f / 4096) continue; diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 34ede32264..3b83dd12ab 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4451,8 +4451,7 @@ gtk_window_unrealize (GtkWidget *widget) GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget); gdk_surface_set_widget (surface, NULL); - gdk_surface_destroy (surface); - g_clear_object (&priv->surface); + g_clear_pointer (&priv->surface, gdk_surface_destroy); } static void diff --git a/meson.build b/meson.build index a46257faa6..65eba0bd3a 100644 --- a/meson.build +++ b/meson.build @@ -880,9 +880,9 @@ endif #### Summary #### -summary('Display backends', display_backends) -summary('Print backends', print_backends) -summary('Media backends', media_backends) +summary('Display backends', display_backends, section: 'Components') +summary('Print backends', print_backends, section: 'Components') +summary('Media backends', media_backends, section: 'Components') summary('Vulkan support', vulkan_dep.found(), section: 'Features') summary('Cloud support', cloudproviders_dep.found(), section: 'Features') @@ -893,7 +893,6 @@ summary('Tracker support', tracker3_dep.found(), section: 'Features') summary('Compiler', cc.get_id(), section: 'Toolchain') summary('Linker', cc.get_linker_id(), section: 'Toolchain') -# Build summary('Debugging', get_option('debug'), section: 'Build') summary('Optimization', get_option('optimization'), section: 'Build') summary('Introspection', build_gir, section: 'Build') @@ -904,7 +903,6 @@ summary('Tests', get_option('build-tests'), section: 'Build') summary('Demos', get_option('build-demos'), section: 'Build') summary('Examples', get_option('build-examples'), section: 'Build') -# Directories summary('prefix', gtk_prefix, section: 'Directories') summary('includedir', gtk_includedir, section: 'Directories') summary('libdir', gtk_libdir, section: 'Directories') diff --git a/testsuite/gsk/compare-render.c b/testsuite/gsk/compare-render.c index b75f703955..bf86ac4150 100644 --- a/testsuite/gsk/compare-render.c +++ b/testsuite/gsk/compare-render.c @@ -300,8 +300,9 @@ main (int argc, char **argv) GdkPixbuf *pixbuf, *pixbuf2; node2 = gsk_transform_node_new (node, gsk_transform_scale (NULL, -1, 1)); - rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); + save_node (node2, node_file, "-flipped.node"); + rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); save_image (rendered_texture, node_file, "-flipped.out.png"); pixbuf = gdk_pixbuf_new_from_file (png_file, &error); @@ -316,7 +317,6 @@ main (int argc, char **argv) if (diff_texture) { - save_node (node2, node_file, "-flipped.node"); save_image (diff_texture, node_file, "-flipped.diff.png"); g_object_unref (diff_texture); success = FALSE; @@ -357,6 +357,8 @@ main (int argc, char **argv) offset_y += node_bounds.size.height; node2 = gsk_repeat_node_new (&bounds, node, &node_bounds); + save_node (node2, node_file, "-repeated.node"); + rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); save_image (rendered_texture, node_file, "-repeated.out.png"); @@ -388,7 +390,6 @@ main (int argc, char **argv) if (diff_texture) { - save_node (node2, node_file, "-repeated.node"); save_image (diff_texture, node_file, "-repeated.diff.png"); g_object_unref (diff_texture); success = FALSE; @@ -405,8 +406,9 @@ main (int argc, char **argv) GdkPixbuf *pixbuf, *pixbuf2; node2 = gsk_transform_node_new (node, gsk_transform_rotate (NULL, 90)); - rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); + save_node (node2, node_file, "-rotated.node"); + rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); save_image (rendered_texture, node_file, "-rotated.out.png"); pixbuf = gdk_pixbuf_new_from_file (png_file, &error); @@ -421,7 +423,6 @@ main (int argc, char **argv) if (diff_texture) { - save_node (node2, node_file, "-rotated.node"); save_image (diff_texture, node_file, "-rotated.diff.png"); g_object_unref (diff_texture); success = FALSE; @@ -451,8 +452,9 @@ main (int argc, char **argv) gsk_render_node_unref (mask_node); gsk_render_node_unref (nodes[0]); gsk_render_node_unref (nodes[1]); - rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); + save_node (node2, node_file, "-masked.node"); + rendered_texture = gsk_renderer_render_texture (renderer, node2, NULL); save_image (rendered_texture, node_file, "-masked.out.png"); pixbuf = gdk_pixbuf_new_from_file (png_file, &error); @@ -467,7 +469,6 @@ main (int argc, char **argv) if (diff_texture) { - save_node (node2, node_file, "-masked.node"); save_image (diff_texture, node_file, "-masked.diff.png"); g_object_unref (diff_texture); success = FALSE; @@ -480,5 +481,7 @@ main (int argc, char **argv) gsk_render_node_unref (node); + gdk_display_close (gdk_display_get_default ()); + return success ? 0 : 1; } diff --git a/testsuite/gsk/misc.c b/testsuite/gsk/misc.c index 7b4af1cf28..26c23b2301 100644 --- a/testsuite/gsk/misc.c +++ b/testsuite/gsk/misc.c @@ -1,10 +1,17 @@ #include <gtk/gtk.h> #include "gsk/gskrendernodeprivate.h" +#ifdef GDK_RENDERING_GL +#include <gsk/gl/gskglrenderer.h> +#endif + +#include <gobject/gvaluecollector.h> + static void test_rendernode_gvalue (void) { GValue value = G_VALUE_INIT; + GValue value2 = G_VALUE_INIT; GskRenderNode *node, *node2; g_assert_false (GSK_VALUE_HOLDS_RENDER_NODE (&value)); @@ -23,7 +30,45 @@ test_rendernode_gvalue (void) g_value_reset (&value); gsk_value_take_render_node (&value, node); + g_value_init (&value2, GSK_TYPE_RENDER_NODE); + g_value_copy (&value, &value2); + g_assert_true (gsk_value_get_render_node (&value2) == node); + + gsk_value_set_render_node (&value, NULL); + gsk_value_take_render_node (&value2, NULL); + g_value_unset (&value); + g_value_unset (&value2); +} + +static void +test_collect_varargs (GskRenderNode *node, ...) +{ + va_list ap; + char *err = NULL; + GValue value = G_VALUE_INIT; + + g_value_init (&value, GSK_TYPE_RENDER_NODE); + + va_start (ap, node); + G_VALUE_COLLECT (&value, ap, 0, &err); + va_end (ap); + + g_assert_true (gsk_value_get_render_node (&value) == node); + + g_value_unset (&value); +} + +static void +test_rendernode_varargs (void) +{ + GskRenderNode *node; + + node = gsk_color_node_new (&(GdkRGBA){0,1,1,1}, &GRAPHENE_RECT_INIT (0, 0, 50, 50)); + + test_collect_varargs (node, node, NULL); + + gsk_render_node_unref (node); } static void @@ -82,6 +127,151 @@ test_conic_gradient_angle (void) gsk_render_node_unref (node); } +static void +test_container_disjoint (void) +{ + GskRenderNode *node, *nodes[2]; + + nodes[0] = gsk_color_node_new (&(GdkRGBA){0,1,1,1}, &GRAPHENE_RECT_INIT (0, 0, 50, 50)); + nodes[1] = gsk_color_node_new (&(GdkRGBA){0,1,1,1}, &GRAPHENE_RECT_INIT (50, 0, 50, 50)); + node = gsk_container_node_new (nodes, 2); + + g_assert_true (gsk_container_node_is_disjoint (node)); + + gsk_render_node_unref (node); + gsk_render_node_unref (nodes[0]); + gsk_render_node_unref (nodes[1]); + + nodes[0] = gsk_color_node_new (&(GdkRGBA){0,1,1,1}, &GRAPHENE_RECT_INIT (0, 0, 50, 50)); + nodes[1] = gsk_color_node_new (&(GdkRGBA){0,1,1,1}, &GRAPHENE_RECT_INIT (25, 0, 50, 50)); + node = gsk_container_node_new (nodes, 2); + + g_assert_false (gsk_container_node_is_disjoint (node)); + + gsk_render_node_unref (node); + gsk_render_node_unref (nodes[0]); + gsk_render_node_unref (nodes[1]); +} + +const char shader1[] = +"uniform float progress;\n" +"uniform sampler2D u_texture1;\n" +"uniform sampler2D u_texture2;\n" +"" +"vec4 getFromColor (vec2 uv) {\n" +" return GskTexture(u_texture1, uv);\n" +"}\n" +"\n" +"vec4 getToColor (vec2 uv) {\n" +" return GskTexture(u_texture2, uv);\n" +"}\n" +"\n" +"// author: bobylito\n" +"// license: MIT\n" +"const float SQRT_2 = 1.414213562373;\n" +"uniform float dots;// = 20.0;\n" +"uniform vec2 center; //= vec2(0, 0);\n" +"\n" +"uniform int test1 = -2;\n" +"uniform uint test2 = 2u; \n" +"uniform bool test3;\n" +"uniform vec3 test4;\n" +"uniform vec4 test5;\n" +"\n" +"vec4 transition(vec2 uv) {\n" +" bool nextImage = distance(fract(uv * dots), vec2(0.5, 0.5)) < ( progress / distance(uv, center));\n" +" return nextImage ? getToColor(uv) : getFromColor(uv);\n" +"}\n" +"\n" +"void mainImage(out vec4 fragColor, in vec2 fragCoord, in vec2 resolution, in vec2 uv)\n" +"{\n" +" fragColor = transition(uv);\n" +"}\n"; + +static void +test_renderer (GskRenderer *renderer) +{ + GdkDisplay *display; + gboolean realized; + GdkSurface *surface; + gboolean res; + GError *error = NULL; + GskGLShader *shader; + GBytes *bytes; + + g_assert (GSK_IS_RENDERER (renderer)); + + display = gdk_display_open (NULL); + + g_object_get (renderer, + "realized", &realized, + "surface", &surface, + NULL); + + g_assert_false (realized); + g_assert_null (surface); + + g_assert_null (gsk_renderer_get_surface (renderer)); + + surface = gdk_surface_new_toplevel (display); + + res = gsk_renderer_realize (renderer, surface, &error); + + g_assert_true (res); + + g_assert_true (gsk_renderer_is_realized (renderer)); + g_assert_true (gsk_renderer_get_surface (renderer) == surface); + + bytes = g_bytes_new_static (shader1, sizeof (shader1)); + shader = gsk_gl_shader_new_from_bytes (bytes); + g_bytes_unref (bytes); + res = gsk_gl_shader_compile (shader, renderer, &error); + if (GSK_IS_GL_RENDERER (renderer)) + { + g_assert_true (res); + g_assert_no_error (error); + } + else + { + g_assert_false (res); + g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED); + g_clear_error (&error); + } + + gsk_renderer_unrealize (renderer); + + g_assert_false (gsk_renderer_is_realized (renderer)); + g_assert_null (gsk_renderer_get_surface (renderer)); + + gdk_surface_destroy (surface); + + gdk_display_close (display); +} + +static void +test_cairo_renderer (void) +{ + GskRenderer *renderer; + + renderer = gsk_cairo_renderer_new (); + test_renderer (renderer); + g_clear_object (&renderer); +} + +static void +test_gl_renderer (void) +{ +#ifdef GDK_RENDERING_GL + GskRenderer *renderer; + + renderer = gsk_gl_renderer_new (); + test_renderer (renderer); + g_clear_object (&renderer); +#else + g_test_skip ("no GL support"); +#endif +} + int main (int argc, char *argv[]) { @@ -89,8 +279,12 @@ main (int argc, char *argv[]) gtk_init (); g_test_add_func ("/rendernode/gvalue", test_rendernode_gvalue); + g_test_add_func ("/rendernode/varargs", test_rendernode_varargs); g_test_add_func ("/rendernode/border/uniform", test_bordernode_uniform); g_test_add_func ("/rendernode/conic-gradient/angle", test_conic_gradient_angle); + g_test_add_func ("/rendernode/container/disjoint", test_container_disjoint); + g_test_add_func ("/renderer/cairo", test_cairo_renderer); + g_test_add_func ("/renderer/gl", test_gl_renderer); return g_test_run (); } diff --git a/testsuite/gsk/shader.c b/testsuite/gsk/shader.c index 4bc4f0245b..517f4b6d71 100644 --- a/testsuite/gsk/shader.c +++ b/testsuite/gsk/shader.c @@ -286,7 +286,7 @@ test_compile (void) gsk_renderer_unrealize (renderer); g_object_unref (renderer); - g_object_unref (surface); + gdk_surface_destroy (surface); g_bytes_unref (bytes); } diff --git a/testsuite/gsk/transform.c b/testsuite/gsk/transform.c index 855eb57f72..01220a2b2f 100644 --- a/testsuite/gsk/transform.c +++ b/testsuite/gsk/transform.c @@ -406,6 +406,10 @@ test_print_parse (void) } } } + + ret = gsk_transform_parse ("rotate(45);", &parsed); + g_assert_false (ret); + g_assert_null (parsed); } static void @@ -735,16 +739,37 @@ test_to_2d_components (void) gsk_transform_unref (transform); gsk_transform_unref (transform2); + + transform = gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (2, 3)); + + gsk_transform_to_2d_components (transform, + &skew_x, &skew_y, + &scale_x, &scale_y, + &angle, + &dx, &dy); + g_assert_cmpfloat_with_epsilon (skew_x, 0, 0.0001); + g_assert_cmpfloat_with_epsilon (skew_y, 0, 0.0001); + g_assert_cmpfloat_with_epsilon (scale_x, 1, 0.0001); + g_assert_cmpfloat_with_epsilon (scale_y, 1, 0.0001); + g_assert_cmpfloat_with_epsilon (angle, 0, 0.0001); + g_assert_cmpfloat_with_epsilon (dx, 2, 0.0001); + g_assert_cmpfloat_with_epsilon (dy, 3, 0.0001); + + gsk_transform_unref (transform); } static void test_transform_point (void) { - GskTransform *t, *t2; + GskTransform *t, *t2, *t3; graphene_point_t p; t = gsk_transform_scale (gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (1, 2)), 2, 2); t2 = gsk_transform_translate (gsk_transform_scale (NULL, 2, 2), &GRAPHENE_POINT_INIT (1, 2)); + t3 = gsk_transform_rotate (NULL, 90); + + gsk_transform_transform_point (NULL, &GRAPHENE_POINT_INIT (1,1), &p); + g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (1, 1))); gsk_transform_transform_point (t, &GRAPHENE_POINT_INIT (1,1), &p); g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (3, 4))); @@ -752,14 +777,44 @@ test_transform_point (void) gsk_transform_transform_point (t2, &GRAPHENE_POINT_INIT (1,1), &p); g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (4, 6))); + gsk_transform_transform_point (t3, &GRAPHENE_POINT_INIT (2,1), &p); + g_assert_true (graphene_point_equal (&p, &GRAPHENE_POINT_INIT (-1, 2))); + gsk_transform_unref (t); gsk_transform_unref (t2); + gsk_transform_unref (t3); +} + +static void +test_scale_transform (void) +{ + GskTransform *t1, *t2; + char *string; + gboolean res; + GskTransform *x; + + t1 = gsk_transform_scale (NULL, 4, 9); + t2 = gsk_transform_scale (gsk_transform_scale (NULL, 2, 3), 2, 3); + + g_assert_true (gsk_transform_get_category (t1) == GSK_TRANSFORM_CATEGORY_2D_AFFINE); + g_assert_true (gsk_transform_get_category (t2) == GSK_TRANSFORM_CATEGORY_2D_AFFINE); + g_assert_true (gsk_transform_equal (t1, t2)); + + string = gsk_transform_to_string (t1); + res = gsk_transform_parse (string, &x); + g_assert_true (res); + g_assert_true (gsk_transform_equal (t1, x)); + + gsk_transform_unref (t1); + gsk_transform_unref (t2); + g_free (string); + gsk_transform_unref (x); } static void test_skew_transform (void) { - GskTransform *t1, *t2, *t3; + GskTransform *t1, *t2, *t3, *t4; char *string; gboolean res; GskTransform *x; @@ -767,6 +822,7 @@ test_skew_transform (void) t1 = gsk_transform_skew (NULL, 30, 60); t2 = gsk_transform_skew (NULL, 0, 30); t3 = gsk_transform_skew (NULL, 0, -30); + t4 = gsk_transform_skew (NULL, 30, 0); g_assert_true (gsk_transform_get_category (t1) == GSK_TRANSFORM_CATEGORY_2D); g_assert_true (gsk_transform_get_category (t2) == GSK_TRANSFORM_CATEGORY_2D); @@ -779,12 +835,30 @@ test_skew_transform (void) res = gsk_transform_parse (string, &x); g_assert_true (res); g_assert_true (gsk_transform_equal (t1, x)); + g_free (string); + gsk_transform_unref (x); + + string = gsk_transform_to_string (t3); + res = gsk_transform_parse (string, &x); + g_assert_true (res); + g_assert_true (gsk_transform_equal (t3, x)); + g_free (string); + gsk_transform_unref (x); + + string = gsk_transform_to_string (t4); + res = gsk_transform_parse (string, &x); + g_assert_true (res); + g_assert_true (gsk_transform_equal (t4, x)); + g_free (string); + gsk_transform_unref (x); + + t3 = gsk_transform_transform (t3, t4); + g_assert_true (gsk_transform_get_category (t3) == GSK_TRANSFORM_CATEGORY_2D); gsk_transform_unref (t1); gsk_transform_unref (t2); gsk_transform_unref (t3); - g_free (string); - gsk_transform_unref (x); + gsk_transform_unref (t4); } static void @@ -811,6 +885,7 @@ static void test_rotate_transform (void) { GskTransform *t1, *t2, *t3; + graphene_vec3_t vec; t1 = gsk_transform_rotate (NULL, 60); t2 = gsk_transform_rotate (NULL, 20); @@ -826,6 +901,11 @@ test_rotate_transform (void) t3 = gsk_transform_rotate (NULL, -60); g_assert_true (gsk_transform_equal (t1, t3)); + gsk_transform_unref (t2); + t2 = gsk_transform_rotate_3d (NULL, -60, graphene_vec3_init (&vec, 0, 0, 1)); + g_assert_true (gsk_transform_get_category (t2) == GSK_TRANSFORM_CATEGORY_2D); + g_assert_true (gsk_transform_equal (t1, t2)); + gsk_transform_unref (t1); gsk_transform_unref (t2); gsk_transform_unref (t3); @@ -851,6 +931,42 @@ test_rotate3d_transform (void) gsk_transform_unref (t2); } +static void +test_matrix_transform (void) +{ + GskTransform *t1, *t2; + float xx, yx, xy, yy, dx, dy; + graphene_matrix_t m; + + if (!gsk_transform_parse ("matrix(2, 0, 0, 3, 1, -1)", &t1)) + g_assert_not_reached (); + g_assert_true (gsk_transform_get_category (t1) == GSK_TRANSFORM_CATEGORY_2D); + + gsk_transform_to_2d (t1, &xx, &yx, &xy, &yy, &dx, &dy); + g_assert_cmpfloat (xx, ==, 2.f); + g_assert_cmpfloat (yx, ==, 0.f); + g_assert_cmpfloat (xy, ==, 0.f); + g_assert_cmpfloat (yy, ==, 3.f); + g_assert_cmpfloat (dx, ==, 1.f); + g_assert_cmpfloat (dy, ==, -1.f); + + graphene_matrix_init_from_float (&m, + (const float[]) { 2.f, 0.f, 0.f, 0.f, + 0.f, 3.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 1., -1.f, 0.f, 1.f}); + t2 = gsk_transform_matrix (NULL, &m); + + g_assert_true (gsk_transform_equal (t1, t2)); + + t1 = gsk_transform_invert (t1); + t2 = gsk_transform_transform (t2, t1); + graphene_assert_fuzzy_transform_equal (t2, NULL, EPSILON); + + gsk_transform_unref (t1); + gsk_transform_unref (t2); +} + int main (int argc, char *argv[]) @@ -869,10 +985,12 @@ main (int argc, g_test_add_func ("/transform/point", test_transform_point); g_test_add_func ("/transform/to-2d", test_to_2d); g_test_add_func ("/transform/to-2d-components", test_to_2d_components); + g_test_add_func ("/transform/scale", test_scale_transform); g_test_add_func ("/transform/skew", test_skew_transform); g_test_add_func ("/transform/perspective", test_perspective_transform); g_test_add_func ("/transform/rotate", test_rotate_transform); g_test_add_func ("/transform/rotate3d", test_rotate3d_transform); + g_test_add_func ("/transform/matrix", test_matrix_transform); return g_test_run (); } |