1 #ifdef CLUTTER_ENABLE_PROFILE
5 /* XXX - we need this for g_atexit() */
6 #define G_DISABLE_DEPRECATION_WARNINGS
7 #include "clutter-profile.h"
9 UProfContext *_clutter_uprof_context;
11 static UProfReport *clutter_uprof_report;
13 static gboolean searched_for_gl_uprof_context = FALSE;
14 static UProfContext *gl_uprof_context = NULL;
16 typedef struct _ClutterUProfReportState
22 } ClutterUProfReportState;
25 timer_per_frame_cb (UProfReport *report,
26 UProfTimerResult *timer,
29 ClutterUProfReportState *state = user_data;
30 int n_frames = state->n_frames ? state->n_frames : 1;
32 return g_strdup_printf ("%-10.2f",
33 uprof_timer_result_get_total_msecs (timer) /
38 counter_per_frame_cb (UProfReport *report,
39 UProfCounterResult *counter,
42 ClutterUProfReportState *state = user_data;
43 int n_frames = state->n_frames ? state->n_frames : 1;
45 return g_strdup_printf ("%-5ld",
46 uprof_counter_result_get_count (counter) /
51 get_n_frames_cb (UProfReport *report,
52 const char *statistic,
53 const char *attribute,
56 ClutterUProfReportState *state = user_data;
58 return g_strdup_printf ("%lu", state->n_frames);
62 get_fps_cb (UProfReport *report,
63 const char *statistic,
64 const char *attribute,
67 ClutterUProfReportState *state = user_data;
69 return g_strdup_printf ("%5.2f\n", state->fps);
73 get_n_picks_cb (UProfReport *report,
74 const char *statistic,
75 const char *attribute,
78 ClutterUProfReportState *state = user_data;
80 return g_strdup_printf ("%lu", state->n_picks);
84 get_picks_per_frame_cb (UProfReport *report,
85 const char *statistic,
86 const char *attribute,
89 ClutterUProfReportState *state = user_data;
90 int n_frames = state->n_frames ? state->n_frames : 1;
92 return g_strdup_printf ("%3.2f",
93 (float)state->n_picks / (float)n_frames);
97 get_msecs_per_pick_cb (UProfReport *report,
98 const char *statistic,
99 const char *attribute,
102 ClutterUProfReportState *state = user_data;
103 int n_picks = state->n_picks ? state->n_picks : 1;
105 return g_strdup_printf ("%3.2f", state->msecs_picking / (float)n_picks);
109 _clutter_uprof_report_prepare (UProfReport *report,
113 UProfContext *mainloop_context;
114 UProfTimerResult *mainloop_timer;
115 UProfTimerResult *stage_paint_timer;
116 UProfTimerResult *do_pick_timer;
117 ClutterUProfReportState *state;
119 /* NB: uprof provides a shared context for mainloop statistics which allows
120 * this to work even if the application and not Clutter owns the mainloop.
122 * This is the case when running Mutter for example but because Mutter will
123 * follow the same convention of using the shared context then we can always
124 * be sure of where to look for the mainloop results. */
125 mainloop_context = uprof_get_mainloop_context ();
126 mainloop_timer = uprof_context_get_timer_result (mainloop_context,
128 /* just bail out if the mainloop timer wasn't hit */
132 state = g_new0 (ClutterUProfReportState, 1);
133 *closure_ret = state;
135 stage_paint_timer = uprof_context_get_timer_result (_clutter_uprof_context,
137 if (stage_paint_timer)
139 state->n_frames = uprof_timer_result_get_start_count (stage_paint_timer);
141 uprof_report_add_statistic (report,
143 "Frame count information");
144 uprof_report_add_statistic_attribute (report, "Frames",
146 "The total number of frames",
147 UPROF_ATTRIBUTE_TYPE_INT,
152 state->fps = (float) state->n_frames
153 / (uprof_timer_result_get_total_msecs (mainloop_timer)
155 uprof_report_add_statistic_attribute (report, "Frames",
156 "Average FPS", "Average\nFPS",
157 "The average frames per second",
158 UPROF_ATTRIBUTE_TYPE_FLOAT,
163 do_pick_timer = uprof_context_get_timer_result (_clutter_uprof_context,
167 state->n_picks = uprof_timer_result_get_start_count (do_pick_timer);
168 state->msecs_picking =
169 uprof_timer_result_get_total_msecs (do_pick_timer);
171 uprof_report_add_statistic (report,
173 "Picking information");
174 uprof_report_add_statistic_attribute (report, "Picks",
176 "The total number of picks",
177 UPROF_ATTRIBUTE_TYPE_INT,
181 uprof_report_add_statistic_attribute (report, "Picks",
184 "The average number of picks "
186 UPROF_ATTRIBUTE_TYPE_FLOAT,
187 get_picks_per_frame_cb,
190 uprof_report_add_statistic_attribute (report, "Picks",
193 "The average number of "
194 "milliseconds per pick",
195 UPROF_ATTRIBUTE_TYPE_FLOAT,
196 get_msecs_per_pick_cb,
200 uprof_report_add_counters_attribute (clutter_uprof_report,
203 "The number of counts per frame",
204 UPROF_ATTRIBUTE_TYPE_INT,
205 counter_per_frame_cb,
207 uprof_report_add_timers_attribute (clutter_uprof_report,
210 "The time spent in the timer per frame",
211 UPROF_ATTRIBUTE_TYPE_FLOAT,
219 _clutter_uprof_report_done (UProfReport *report, void *closure, void *user_data)
225 print_exit_report (void)
227 if (!(clutter_profile_flags & CLUTTER_PROFILE_DISABLE_REPORT))
228 uprof_report_print (clutter_uprof_report);
230 uprof_report_unref (clutter_uprof_report);
232 uprof_context_unref (_clutter_uprof_context);
236 _clutter_uprof_init (void)
238 UProfContext *cogl_context;
240 _clutter_uprof_context = uprof_context_new ("Clutter");
241 uprof_context_link (_clutter_uprof_context, uprof_get_mainloop_context ());
242 g_atexit (print_exit_report);
244 cogl_context = uprof_find_context ("Cogl");
246 uprof_context_link (_clutter_uprof_context, cogl_context);
248 /* We make the report object up-front so we can use uprof-tool
249 * to fetch reports at runtime via dbus... */
250 clutter_uprof_report = uprof_report_new ("Clutter report");
251 uprof_report_add_context (clutter_uprof_report, _clutter_uprof_context);
252 uprof_report_set_init_fini_callbacks (clutter_uprof_report,
253 _clutter_uprof_report_prepare,
254 _clutter_uprof_report_done,
259 _clutter_profile_suspend (void)
261 if (G_UNLIKELY (!searched_for_gl_uprof_context))
263 gl_uprof_context = uprof_find_context ("OpenGL");
264 searched_for_gl_uprof_context = TRUE;
267 if (gl_uprof_context)
268 uprof_context_suspend (gl_uprof_context);
270 /* NB: The Cogl context is linked to this so it will also be suspended... */
271 uprof_context_suspend (_clutter_uprof_context);
275 _clutter_profile_resume (void)
277 if (gl_uprof_context)
278 uprof_context_resume (gl_uprof_context);
280 /* NB: The Cogl context is linked to this so it will also be resumed... */
281 uprof_context_resume (_clutter_uprof_context);