summaryrefslogtreecommitdiff
path: root/perf
diff options
context:
space:
mode:
Diffstat (limited to 'perf')
-rw-r--r--perf/gtkwidgetprofiler.c123
-rw-r--r--perf/gtkwidgetprofiler.h2
-rw-r--r--perf/main.c4
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;
}