diff options
Diffstat (limited to 'perf')
-rw-r--r-- | perf/gtkwidgetprofiler.c | 123 | ||||
-rw-r--r-- | perf/gtkwidgetprofiler.h | 2 | ||||
-rw-r--r-- | perf/main.c | 4 |
3 files changed, 113 insertions, 16 deletions
diff --git a/perf/gtkwidgetprofiler.c b/perf/gtkwidgetprofiler.c index 01ae8420ed..3fd9f858df 100644 --- a/perf/gtkwidgetprofiler.c +++ b/perf/gtkwidgetprofiler.c @@ -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); +} diff --git a/perf/gtkwidgetprofiler.h b/perf/gtkwidgetprofiler.h index 62d19c8a92..4a96b9ffd8 100644 --- a/perf/gtkwidgetprofiler.h +++ b/perf/gtkwidgetprofiler.h @@ -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 diff --git a/perf/main.c b/perf/main.c index 303775249d..46e3d0aa2f 100644 --- a/perf/main.c +++ b/perf/main.c @@ -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; } |