New function; it lets us time the expose sequence of a widget.

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.
This commit is contained in:
Federico Mena Quintero 2006-06-14 21:24:31 +00:00 committed by Federico Mena Quintero
parent c42ab53bb1
commit 02c7cf7bee
5 changed files with 141 additions and 22 deletions

View 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

View 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

View 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;
@ -273,6 +273,24 @@ get_instrumented_toplevel (GtkWidgetProfiler *profiler,
return window;
}
static void
map_widget (GtkWidgetProfiler *profiler)
{
GtkWidgetProfilerPrivate *priv;
priv = profiler->priv;
g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
/* Time map.
*
* FIXME: we are really timing a show_all(); we don't really wait for all the "map_event" signals
* to happen. Should we rename GTK_WIDGET_PROFILER_REPORT_MAP report to something else?
*/
gtk_widget_show_all (priv->toplevel);
priv->state = STATE_INSTRUMENTED_MAPPED;
}
static void
profile_map_expose (GtkWidgetProfiler *profiler)
{
@ -283,18 +301,10 @@ profile_map_expose (GtkWidgetProfiler *profiler)
g_assert (priv->state == STATE_INSTRUMENTED_NOT_MAPPED);
/* Time map.
*
* FIXME: we are really timing a show_all(); we don't really wait for all the "map_event" signals
* 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;
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() */
@ -320,6 +330,31 @@ profile_destroy (GtkWidgetProfiler *profiler)
report (profiler, GTK_WIDGET_PROFILER_REPORT_DESTROY, elapsed);
}
static void
create_widget (GtkWidgetProfiler *profiler)
{
GtkWidgetProfilerPrivate *priv;
priv = profiler->priv;
g_assert (priv->state == STATE_NOT_CREATED);
priv->profiled_widget = create_widget_via_emission (profiler);
priv->toplevel = get_instrumented_toplevel (profiler, priv->profiled_widget);
priv->state = STATE_INSTRUMENTED_NOT_MAPPED;
}
/* 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)
{
@ -333,17 +368,9 @@ profile_boot (GtkWidgetProfiler *profiler)
/* 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.
*/
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);
}

View 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

View 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;
}