• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

Makefile.amH A D18-Dec-20202.4 KiB10078

Makefile.inH A D03-May-202228.7 KiB918797

READMEH A D18-Dec-20206.6 KiB221159

appwindow.cH A D18-Dec-20207.3 KiB234184

gtkwidgetprofiler.cH A D18-Dec-202010.6 KiB471320

gtkwidgetprofiler.hH A D18-Dec-20201.9 KiB6140

main.cH A D18-Dec-20201.4 KiB6749

marshalers.cH A D21-Dec-20205.5 KiB126107

marshalers.hH A D21-Dec-20201.3 KiB3120

marshalers.listH A D18-Dec-202036 32

textview.cH A D18-Dec-20202.1 KiB6154

treeview.cH A D18-Dec-20203.8 KiB10285

typebuiltins.cH A D21-Dec-20201 KiB2618

typebuiltins.c.templateH A D18-Dec-2020802 3628

typebuiltins.hH A D21-Dec-2020579 208

typebuiltins.h.templateH A D18-Dec-2020518 2517

widgets.hH A D18-Dec-2020123 84

README

1README for gtk+/perf
2--------------------
3
4This is a framework for testing performance in GTK+.   For GTK+, being
5performant does not only mean "paint widgets fast".  It also means
6things like the time needed to set up widgets, to map and draw a
7window for the first time, and emitting/propagating signals.
8
9The following is accurate as of 2006/Jun/14.
10
11
12Background
13----------
14
15A widget's lifetime looks more or less like this:
16
17	1. Instantiation
18	2. Size request
19	3. Size allocate
20	5. Realize
21	4. Map
22	5. Expose
23	6. Destroy
24
25Some of these stages are particularly interesting:
26
27- Instantiation means creating the widget.  This may be as simple as a
28  few malloc()s and setting some fields.  It could also be a
29  complicated operation if the widget needs to contact an external
30  server to create itself, or if it needs to read data files.
31
32- Size requisition is when GTK+ asks the widget, "how big do you want
33  to be on the screen"?  This can be an expensive operation.  The
34  widget has to measure its text, measure its icons (and thus load its
35  icons), and generally run through its internal layout code.
36
37- Realization is when the widget creates its GDK resources, like its
38  GdkWindow and graphics contexts it may need.  This could be
39  expensive if the widget needs to load data files for cursors or
40  backgrounds.
41
42- Expose is when the widget gets repainted.  This will happen many
43  times throughout the lifetime of the widget:  every time you drag a
44  window on top of it, every time its data changes and it needs to
45  redraw, every time it gets resized.
46
47GtkWidgetProfiler is a mechanism to let you get individual timings for
48each of the stages in the lifetime of a widget.  It also lets you run
49some stages many times in a sequence, so that you can run a real
50profiler and get an adequate number of samples.  For example,
51GtkWidgetProfiler lets you say "repaint this widget 1000 times".
52
53Why is this not as simple as doing
54
55	start_timer ();
56	for (i = 0; i < 1000; i++) {
57		gtk_widget_queue_draw (widget);
58		while (gtk_events_pending ())
59			gtk_main_iteration ();
60	}
61	stop_timer ();
62
63Huh?
64
65Because X is an asynchronous window system.  So, when you send the
66"paint" commands, your program will regain control but it will take
67some time for the X server to actually process those commands.
68GtkWidgetProfiler has special code to wait for the X server and give
69you accurate timings.
70
71
72Using the framework
73-------------------
74
75Right now the framework is very simple; it just has utility functions
76to time widget creation, mapping, exposure, and destruction.  To run
77such a test, you use the GtkWidgetProfiler object in
78gtkwidgetprofiler.h.
79
80The gtk_widget_profiler_profile_boot() function will emit the
81"create-widget" signal so that you can create your widget for
82testing.  It will then take timings for the widget, and emit the
83"report" signal as appropriate.
84
85The "create-widget" signal:
86
87  The handler has this form:
88
89    GtkWidget *create_widget_callback (GtkWidgetProfiler *profiler,
90				       gpointer user_data);
91
92  You need to create a widget in your handler, and return it.  Do not
93  show the widget; the profiler will do that by itself at the right
94  time, and will actually complain if you show the widget.
95
96
97The "report" signal:
98
99  This function will get called when the profiler wants to report that
100  it finished timing an important stage in the lifecycle of your
101  widget.  The handler has this form:
102
103    void report_callback (GtkWidgetProfiler      *profiler,
104			  GtkWidgetProfilerReport report,
105			  GtkWidget              *widget,
106			  gdouble                 elapsed,
107			  gpointer                user_data);
108
109  The "report" argument tells you what happened to your widget:
110
111    GTK_WIDGET_PROFILER_REPORT_CREATE.  A timer gets started right
112    before the profiler emits the "create-widget" signal,, and it gets
113    stopped when your callback returns with the new widget.  This
114    measures the time it takes to set up your widget, but not show it.
115
116    GTK_WIDGET_PROFILER_REPORT_MAP.  A timer gets started right before
117    the profiler calls gtk_widget_show_all() on your widget, and it
118    gets stopped when the the widget has been mapped.
119
120    GTK_WIDGET_PROFILER_REPORT_EXPOSE.  A timer gets started right before
121    the profiler starts waiting for GTK+ and the X server to finish
122    painting your widget, and it gets stopped when the widget is fully
123    painted to the screen.
124
125    GTK_WIDGET_PROFILER_REPORT_DESTROY.  A timer gets started right
126    before the profiler calls gtk_widget_destroy() on your widget, and
127    it gets stopped when gtk_widget_destroy() returns.
128
129As a very basic example of using GtkWidgetProfiler is this:
130
131----------------------------------------------------------------------
132#include <stdio.h>
133#include <gtk/gtk.h>
134#include "gtkwidgetprofiler.h"
135
136static GtkWidget *
137create_widget_cb (GtkWidgetProfiler *profiler, gpointer data)
138{
139  GtkWidget *window;
140
141  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
142  /* ... fill the window with widgets, and don't show them ... */
143
144  return window;
145}
146
147static void
148report_cb (GtkWidgetProfiler *profiler, GtkWidgetProfilerReport report, GtkWidget *widget, gdouble elapsed, gpointer data)
149{
150  const char *type;
151
152  switch (report) {
153  case GTK_WIDGET_PROFILER_REPORT_CREATE:
154    type = "widget creation";
155    break;
156
157  case GTK_WIDGET_PROFILER_REPORT_MAP:
158    type = "widget map";
159    break;
160
161  case GTK_WIDGET_PROFILER_REPORT_EXPOSE:
162    type = "widget expose";
163    break;
164
165  case GTK_WIDGET_PROFILER_REPORT_DESTROY:
166    type = "widget destruction";
167    break;
168
169  default:
170    g_assert_not_reached ();
171    type = NULL;
172  }
173
174  fprintf (stderr, "%s: %g sec\n", type, elapsed);
175
176  if (report == GTK_WIDGET_PROFILER_REPORT_DESTROY)
177    fputs ("\n", stderr);
178}
179
180int
181main (int argc, char **argv)
182{
183  GtkWidgetProfiler *profiler;
184
185  gtk_init (&argc, &argv);
186
187  profiler = gtk_widget_profiler_new ();
188  g_signal_connect (profiler, "create-widget",
189		    G_CALLBACK (create_widget_cb), NULL);
190  g_signal_connect (profiler, "report",
191		    G_CALLBACK (report_cb), NULL);
192
193  gtk_widget_profiler_set_num_iterations (profiler, 100);
194  gtk_widget_profiler_profile_boot (profiler);
195
196  gtk_widget_profiler_profile_expose (profiler);
197
198  return 0;
199}
200
201----------------------------------------------------------------------
202
203
204Getting meaningful results
205--------------------------
206
207Getting times for widget creation/mapping/exposing/destruction is
208interesting, but how do you actually find the places that need
209optimizing?
210
211Why, you run the tests under a profiler, of course.
212
213FIXME: document how to do this.
214
215
216Feedback
217--------
218
219Please mail your feedback to Federico Mena-Quintero <federico@novell.com>.
220This performance framework is a work in progress.
221