[gtk+/wip/frame-synchronization: 17/19] Add a test of an animated resizing window



commit 883aaab938e23efd2879df0c914cc1b33c0b0d3b
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Sep 18 18:21:08 2012 -0400

    Add a test of an animated resizing window
    
    Add a test of a window with an animated size and contents. The
    test accepts load factor command line argument to see how things
    work as the drawing of the content requires more GPU resources.

 tests/Makefile.am         |    2 +
 tests/animated-resizing.c |  197 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 199 insertions(+), 0 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 567e46c..0626078 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -25,6 +25,7 @@ testsocket_programs = testsocket testsocket_child
 endif
 
 noinst_PROGRAMS =  $(TEST_PROGS)	\
+	animated-resizing		\
 	simple				\
 	flicker				\
 	print-editor			\
@@ -148,6 +149,7 @@ endif
 
 endif
 
+animated_resizing_DEPENDENCIES = $(TEST_DEPS)
 flicker_DEPENDENCIES = $(TEST_DEPS)
 simple_DEPENDENCIES = $(TEST_DEPS)
 print_editor_DEPENDENCIES = $(TEST_DEPS)
diff --git a/tests/animated-resizing.c b/tests/animated-resizing.c
new file mode 100644
index 0000000..bf36551
--- /dev/null
+++ b/tests/animated-resizing.c
@@ -0,0 +1,197 @@
+/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
+
+#include <gtk/gtk.h>
+#include <math.h>
+
+#define WIDTH 600
+#define HEIGHT 600
+#define WINDOW_SIZE_JITTER 200
+#define CYCLE_TIME 5.
+
+static GtkWidget *window;
+static int window_width = WIDTH, window_height = HEIGHT;
+
+static double angle;
+static int frames_since_last_print = 0;
+
+static double load_factor = 1.0;
+static double cb_no_resize = FALSE;
+
+static cairo_surface_t *source_surface;
+
+static void
+ensure_resources(cairo_surface_t *target)
+{
+  cairo_t *cr;
+  int i, j;
+
+  if (source_surface != NULL)
+    return;
+
+  source_surface = cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA, 2048, 2048);
+  cr = cairo_create(source_surface);
+
+  cairo_save(cr);
+  cairo_set_source_rgba(cr, 0, 0, 0, 0);
+  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint(cr);
+  cairo_restore(cr);
+
+  cairo_set_line_width(cr, 1.0);
+
+  for (j = 0; j < 16; j++)
+    for (i = 0; i < 16; i++)
+      {
+        cairo_set_source_rgba(cr,
+                              ((i * 41) % 16) / 15.,
+                              ((i * 31) % 16) / 15.,
+                              ((i * 23) % 16) / 15.,
+                              0.25);
+        cairo_arc(cr,
+                  i * 128 + 64, j * 128 + 64,
+                  64 - 0.5, 0, 2 * M_PI);
+        cairo_fill_preserve(cr);
+        cairo_set_source_rgba(cr,
+                              ((i * 41) % 16) / 15.,
+                              ((i * 31) % 16) / 15.,
+                              ((i * 23) % 16) / 15.,
+                              1.0);
+        cairo_stroke(cr);
+      }
+}
+
+static void
+on_window_draw (GtkWidget *widget,
+                cairo_t   *cr)
+
+{
+  GRand *rand = g_rand_new_with_seed(0);
+  int i;
+  int width, height;
+
+  width = gtk_widget_get_allocated_width (widget);
+  height = gtk_widget_get_allocated_height (widget);
+
+  ensure_resources (cairo_get_target (cr));
+
+  cairo_set_source_rgb(cr, 1, 1, 1);
+  cairo_paint(cr);
+
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_set_line_width(cr, 1.0);
+  cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
+  cairo_stroke (cr);
+
+  for(i = 0; i < load_factor * 150; i++)
+    {
+      int source = g_rand_int_range(rand, 0, 255);
+      double phi = g_rand_double_range(rand, 0, 2 * M_PI) + angle;
+      double r = g_rand_double_range(rand, 0, width / 2 - 64);
+      int x, y;
+
+      int source_x = (source % 16) * 128;
+      int source_y = (source / 16) * 128;
+
+      x = round(width / 2 + r * cos(phi) - 64);
+      y = round(height / 2 - r * sin(phi) - 64);
+
+      cairo_set_source_surface(cr, source_surface,
+                               x - source_x, y - source_y);
+      cairo_rectangle(cr, x, y, 128, 128);
+      cairo_fill(cr);
+    }
+
+  g_rand_free(rand);
+}
+
+static void
+on_frame (GtkTimeline *timeline,
+          double       progress)
+{
+  int jitter;
+  double current_time;
+  static double last_print_time = 0;
+
+  current_time = g_get_monotonic_time () / 1000000.;
+  if (current_time >= last_print_time + 5)
+    {
+      if (frames_since_last_print != 0)
+        {
+          g_print ("%g\n", frames_since_last_print / (current_time - last_print_time));
+          frames_since_last_print = 0;
+        }
+
+      last_print_time = current_time;
+    }
+  frames_since_last_print++;
+
+  angle = 2 * M_PI * progress;
+  jitter = WINDOW_SIZE_JITTER * sin(angle);
+
+  if (!cb_no_resize)
+    {
+      window_width = WIDTH + jitter;
+      window_height = HEIGHT + jitter;
+    }
+
+  gtk_window_resize (GTK_WINDOW (window),
+                     window_width, window_height);
+
+  gtk_widget_queue_draw (window);
+}
+
+static GOptionEntry options[] = {
+  { "factor", 'f', 0, G_OPTION_ARG_DOUBLE, &load_factor, "Load factor", "FACTOR" },
+  { "no-resize", 'n', 0, G_OPTION_ARG_NONE, &cb_no_resize, "No Resize", NULL },
+  { NULL }
+};
+
+int
+main(int argc, char **argv)
+{
+  GError *error = NULL;
+  GdkScreen *screen;
+  GdkRectangle monitor_bounds;
+  GtkTimeline *timeline;
+
+  if (!gtk_init_with_args (&argc, &argv, "",
+                           options, NULL, NULL))
+    {
+      g_printerr ("Option parsing failed: %s", error->message);
+      return 1;
+    }
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
+  gtk_window_set_gravity (GTK_WINDOW (window), GDK_GRAVITY_CENTER);
+  gtk_widget_set_app_paintable (window, TRUE);
+
+  g_signal_connect (window, "draw",
+                    G_CALLBACK (on_window_draw), NULL);
+  g_signal_connect (window, "destroy",
+                    G_CALLBACK (gtk_main_quit), NULL);
+
+  timeline = gtk_timeline_new (window, CYCLE_TIME * 1000);
+  gtk_timeline_set_loop (timeline, TRUE);
+  gtk_timeline_set_progress_type (timeline, GTK_TIMELINE_PROGRESS_LINEAR);
+
+  g_signal_connect (timeline, "frame",
+                    G_CALLBACK (on_frame), NULL);
+  on_frame (timeline, 0.);
+  gtk_timeline_start (timeline);
+
+  screen = gtk_widget_get_screen (window);
+  gdk_screen_get_monitor_geometry (screen,
+                                   gdk_screen_get_primary_monitor (screen),
+                                   &monitor_bounds);
+
+  gtk_window_move (GTK_WINDOW (window),
+                   monitor_bounds.x + (monitor_bounds.width - window_width) / 2,
+                   monitor_bounds.y + (monitor_bounds.height - window_height) / 2);
+
+  gtk_widget_show (window);
+
+  gtk_main ();
+
+  return 0;
+}



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