]> Pileus Git - ~andy/gtk/commitdiff
New function; it lets us time the expose sequence of a widget.
authorFederico Mena Quintero <federico@novell.com>
Wed, 14 Jun 2006 21:24:31 +0000 (21:24 +0000)
committerFederico Mena Quintero <federico@src.gnome.org>
Wed, 14 Jun 2006 21:24:31 +0000 (21:24 +0000)
2006-06-14  Federico Mena Quintero  <federico@novell.com>

* perf/gtkwidgetprofiler.c (gtk_widget_profiler_profile_expose):
New function; it lets us time the expose sequence of a widget.
(create_widget): New helper function.
(map_widget): New helper function.
(profile_boot): Use create_widget() instead of doing it by hand.
(profile_map_expose): Use map_widget() instead of doing it by hand.

* perf/main.c (main): Call gtk_widget_profiler_profile_expose() as well.

ChangeLog
ChangeLog.pre-2-10
perf/gtkwidgetprofiler.c
perf/gtkwidgetprofiler.h
perf/main.c

index 5503a38a52ae437fa7b4637bb94a3ffbd3cceb82..cd45d9b4ef852484acff333922bcda69511b8bdd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-06-14  Federico Mena Quintero  <federico@novell.com>
+
+       * perf/gtkwidgetprofiler.c (gtk_widget_profiler_profile_expose):
+       New function; it lets us time the expose sequence of a widget.
+       (create_widget): New helper function.
+       (map_widget): New helper function.
+       (profile_boot): Use create_widget() instead of doing it by hand.
+       (profile_map_expose): Use map_widget() instead of doing it by hand.
+
+       * perf/main.c (main): Call gtk_widget_profiler_profile_expose() as well.
+
 2006-06-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkpagesetupunixdialog.c: Use GKeyFile for the custom
index 5503a38a52ae437fa7b4637bb94a3ffbd3cceb82..cd45d9b4ef852484acff333922bcda69511b8bdd 100644 (file)
@@ -1,3 +1,14 @@
+2006-06-14  Federico Mena Quintero  <federico@novell.com>
+
+       * perf/gtkwidgetprofiler.c (gtk_widget_profiler_profile_expose):
+       New function; it lets us time the expose sequence of a widget.
+       (create_widget): New helper function.
+       (map_widget): New helper function.
+       (profile_boot): Use create_widget() instead of doing it by hand.
+       (profile_map_expose): Use map_widget() instead of doing it by hand.
+
+       * perf/main.c (main): Call gtk_widget_profiler_profile_expose() as well.
+
 2006-06-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gtk/gtkpagesetupunixdialog.c: Use GKeyFile for the custom
index 01ae8420ed832ed8faa436ca2fd85f7cecab8898..3fd9f858df0769b6fb6f67d3e2945560e2784c3a 100644 (file)
@@ -210,7 +210,7 @@ toplevel_idle_after_expose_cb (gpointer data)
                       gdk_atom_intern ("STRING", FALSE),
                       8,
                       GDK_PROP_MODE_REPLACE,
-                      "hello",
+                      (guchar *) "hello",
                       strlen ("hello"));
 
   return FALSE;
@@ -274,13 +274,11 @@ get_instrumented_toplevel (GtkWidgetProfiler *profiler,
 }
 
 static void
-profile_map_expose (GtkWidgetProfiler *profiler)
+map_widget (GtkWidgetProfiler *profiler)
 {
   GtkWidgetProfilerPrivate *priv;
-  gdouble elapsed;
 
   priv = profiler->priv;
-
   g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
 
   /* Time map.
@@ -289,12 +287,24 @@ profile_map_expose (GtkWidgetProfiler *profiler)
    * to happen.  Should we rename GTK_WIDGET_PROFILER_REPORT_MAP report to something else?
    */
 
-  g_timer_reset (priv->timer);
-
   gtk_widget_show_all (priv->toplevel);
   priv->state = STATE_INSTRUMENTED_MAPPED;
+}
+
+static void
+profile_map_expose (GtkWidgetProfiler *profiler)
+{
+  GtkWidgetProfilerPrivate *priv;
+  gdouble elapsed;
+
+  priv = profiler->priv;
+
+  g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
 
+  g_timer_reset (priv->timer);
+  map_widget (profiler);
   elapsed = g_timer_elapsed (priv->timer, NULL);
+
   report (profiler, GTK_WIDGET_PROFILER_REPORT_MAP, elapsed);
 
   /* Time expose; this gets recorded in toplevel_property_notify_event_cb() */
@@ -321,29 +331,46 @@ profile_destroy (GtkWidgetProfiler *profiler)
 }
 
 static void
-profile_boot (GtkWidgetProfiler *profiler)
+create_widget (GtkWidgetProfiler *profiler)
 {
   GtkWidgetProfilerPrivate *priv;
-  gdouble elapsed;
 
   priv = profiler->priv;
 
   g_assert (priv->state == STATE_NOT_CREATED);
 
-  /* Time creation */
-
-  g_timer_reset (priv->timer);
-
   priv->profiled_widget = create_widget_via_emission (profiler);
   priv->toplevel = get_instrumented_toplevel (profiler, priv->profiled_widget);
 
   priv->state = STATE_INSTRUMENTED_NOT_MAPPED;
+}
 
-  /* Here we include the time to anchor the widget to a toplevel, if
-   * the toplevel was missing --- hopefully not a too-long extra time.
-   */
+/* The "boot time" of a widget is the time needed to
+ *
+ *   1. Create the widget
+ *   2. Map it
+ *   3. Expose it
+ *   4. Destroy it.
+ *
+ * This runs a lot of interesting code:  instantiation, size requisition and
+ * allocation, realization, mapping, exposing, destruction.
+ */
+static void
+profile_boot (GtkWidgetProfiler *profiler)
+{
+  GtkWidgetProfilerPrivate *priv;
+  gdouble elapsed;
+
+  priv = profiler->priv;
+
+  g_assert (priv->state == STATE_NOT_CREATED);
 
+  /* Time creation */
+
+  g_timer_reset (priv->timer);
+  create_widget (profiler);
   elapsed = g_timer_elapsed (priv->timer, NULL);
+
   report (profiler, GTK_WIDGET_PROFILER_REPORT_CREATE, elapsed);
 
   /* Start timing map/expose */
@@ -355,6 +382,46 @@ profile_boot (GtkWidgetProfiler *profiler)
   profile_destroy (profiler);
 }
 
+/* To measure expose time, we trigger a full expose on the toplevel window.  We
+ * do the same as xrefresh(1), i.e. we map and unmap a window to make the other
+ * one expose.
+ */
+static void
+profile_expose (GtkWidgetProfiler *profiler)
+{
+  GtkWidgetProfilerPrivate *priv;
+  GdkWindow *window;
+  GdkWindowAttr attr;
+  int attr_mask;
+
+  priv = profiler->priv;
+
+  g_assert (priv->state == STATE_INSTRUMENTED_MAPPED);
+
+  /* Time creation */
+
+  attr.x = 0;
+  attr.y = 0;
+  attr.width = priv->toplevel->allocation.width;
+  attr.height = priv->toplevel->allocation.width;
+  attr.wclass = GDK_INPUT_OUTPUT;
+  attr.window_type = GDK_WINDOW_CHILD;
+
+  attr_mask = GDK_WA_X | GDK_WA_Y;
+
+  window = gdk_window_new (priv->toplevel->window, &attr, attr_mask);
+  gdk_window_set_back_pixmap (window, NULL, TRUE); /* avoid flicker */
+
+  gdk_window_show (window);
+  gdk_window_hide (window);
+  gdk_window_destroy (window);
+
+  /* Time expose; this gets recorded in toplevel_property_notify_event_cb() */
+
+  g_timer_reset (priv->timer);
+  gtk_main ();
+}
+
 void
 gtk_widget_profiler_profile_boot (GtkWidgetProfiler *profiler)
 {
@@ -375,3 +442,29 @@ gtk_widget_profiler_profile_boot (GtkWidgetProfiler *profiler)
 
   priv->profiling = FALSE;
 }
+
+void
+gtk_widget_profiler_profile_expose (GtkWidgetProfiler *profiler)
+{
+  GtkWidgetProfilerPrivate *priv;
+  int i, n;
+
+  g_return_if_fail (GTK_IS_WIDGET_PROFILER (profiler));
+
+  priv = profiler->priv;
+  g_return_if_fail (!priv->profiling);
+
+  reset_state (profiler);
+  priv->profiling = TRUE;
+
+  create_widget (profiler);
+  map_widget (profiler);
+
+  n = priv->n_iterations;
+  for (i = 0; i < n; i++)
+    profile_expose (profiler);
+
+  priv->profiling = FALSE;
+
+  reset_state (profiler);
+}
index 62d19c8a9250838a5c17e04ed1d2e162efae05f4..4a96b9ffd813b53570806126f81a8db2a13106dc 100644 (file)
@@ -52,6 +52,8 @@ void gtk_widget_profiler_set_num_iterations (GtkWidgetProfiler *profiler,
 
 void gtk_widget_profiler_profile_boot (GtkWidgetProfiler *profiler);
 
+void gtk_widget_profiler_profile_expose (GtkWidgetProfiler *profiler);
+
 
 G_END_DECLS
 
index 303775249df99877dd27c2e8a0ebe42449e4f310..46e3d0aa2fad6d8a846b61c878e413e59a1b776a 100644 (file)
@@ -3,7 +3,7 @@
 #include "gtkwidgetprofiler.h"
 #include "widgets.h"
 
-#define ITERS 10
+#define ITERS 100
 
 static GtkWidget *
 create_widget_cb (GtkWidgetProfiler *profiler, gpointer data)
@@ -58,7 +58,9 @@ main (int argc, char **argv)
                    G_CALLBACK (report_cb), NULL);
 
   gtk_widget_profiler_set_num_iterations (profiler, ITERS);
+
   gtk_widget_profiler_profile_boot (profiler);
+  gtk_widget_profiler_profile_expose (profiler);
   
   return 0;
 }