static char * seconds_column_cb (UProfReport *report, UProfTimerResult *timer, void *user_data) { gulong msecs = uprof_timer_result_get_total_msecs (timer); return g_strdup_printf ("this took\n»»%d«« sec", (int)(msecs/1000)); }
static char * timer_per_frame_cb (UProfReport *report, UProfTimerResult *timer, void *user_data) { ClutterUProfReportState *state = user_data; int n_frames = state->n_frames ? state->n_frames : 1; return g_strdup_printf ("%-10.2f", uprof_timer_result_get_total_msecs (timer) / (float)n_frames); }
static char * print_timer_fields (UProfTimerResult *timer, guint *fields_width, gpointer data) { ClutterUProfReportState *state = data; /* Print the field titles when timer == NULL */ if (!timer) return g_strdup_printf ("Per Frame"); return g_strdup_printf ("%-10.2f", uprof_timer_result_get_total_msecs (timer) / (float)state->n_frames); }
static gboolean _clutter_uprof_report_prepare (UProfReport *report, void **closure_ret, void *user_data) { UProfContext *mainloop_context; UProfTimerResult *mainloop_timer; UProfTimerResult *stage_paint_timer; UProfTimerResult *do_pick_timer; ClutterUProfReportState *state; /* NB: uprof provides a shared context for mainloop statistics which allows * this to work even if the application and not Clutter owns the mainloop. * * This is the case when running Mutter for example but because Mutter will * follow the same convention of using the shared context then we can always * be sure of where to look for the mainloop results. */ mainloop_context = uprof_get_mainloop_context (); mainloop_timer = uprof_context_get_timer_result (mainloop_context, "Mainloop"); /* just bail out if the mainloop timer wasn't hit */ if (!mainloop_timer) return FALSE; state = g_new0 (ClutterUProfReportState, 1); *closure_ret = state; stage_paint_timer = uprof_context_get_timer_result (_clutter_uprof_context, "Redrawing"); if (stage_paint_timer) { state->n_frames = uprof_timer_result_get_start_count (stage_paint_timer); uprof_report_add_statistic (report, "Frames", "Frame count information"); uprof_report_add_statistic_attribute (report, "Frames", "Count", "Count", "The total number of frames", UPROF_ATTRIBUTE_TYPE_INT, get_n_frames_cb, state); state->fps = (float) state->n_frames / (uprof_timer_result_get_total_msecs (mainloop_timer) / 1000.0); uprof_report_add_statistic_attribute (report, "Frames", "Average FPS", "Average\nFPS", "The average frames per second", UPROF_ATTRIBUTE_TYPE_FLOAT, get_fps_cb, state); } do_pick_timer = uprof_context_get_timer_result (_clutter_uprof_context, "Picking"); if (do_pick_timer) { state->n_picks = uprof_timer_result_get_start_count (do_pick_timer); state->msecs_picking = uprof_timer_result_get_total_msecs (do_pick_timer); uprof_report_add_statistic (report, "Picks", "Picking information"); uprof_report_add_statistic_attribute (report, "Picks", "Count", "Count", "The total number of picks", UPROF_ATTRIBUTE_TYPE_INT, get_n_picks_cb, state); uprof_report_add_statistic_attribute (report, "Picks", "Picks Per Frame", "Picks\nPer Frame", "The average number of picks " "per frame", UPROF_ATTRIBUTE_TYPE_FLOAT, get_picks_per_frame_cb, state); uprof_report_add_statistic_attribute (report, "Picks", "Msecs Per Pick", "Msecs\nPer Pick", "The average number of " "milliseconds per pick", UPROF_ATTRIBUTE_TYPE_FLOAT, get_msecs_per_pick_cb, state); } uprof_report_add_counters_attribute (clutter_uprof_report, "Per Frame", "Per Frame", "The number of counts per frame", UPROF_ATTRIBUTE_TYPE_INT, counter_per_frame_cb, state); uprof_report_add_timers_attribute (clutter_uprof_report, "Per Frame\nmsecs", "Per Frame", "The time spent in the timer per frame", UPROF_ATTRIBUTE_TYPE_FLOAT, timer_per_frame_cb, state); return TRUE; }
static void print_report (UProfReport *report, UProfContext *context) { GList *root_timers; GList *l; UProfTimerResult *stage_paint_timer; UProfTimerResult *mainloop_timer; UProfTimerResult *do_pick_timer; float fps; ClutterUProfReportState state; /* FIXME: We need to fix the way Clutter initializes the uprof library * (we don't currently call uprof_init()) and add a mechanism to know * if uprof_init hasn't been called so we can simply bail out of report * generation and not print spurious warning about missing timers. * Probably we can just have uprof_report_print bail out if uprof wasn't * initialized, so we don't have to care here. */ mainloop_timer = uprof_context_get_timer_result (context, "Mainloop"); if (!mainloop_timer) return; stage_paint_timer = uprof_context_get_timer_result (context, "Redrawing"); if (!stage_paint_timer) return; do_pick_timer = uprof_context_get_timer_result (context, "Do pick"); if (!do_pick_timer) return; g_print ("\n"); state.n_frames = uprof_timer_result_get_start_count (stage_paint_timer); g_print ("Frame count = %lu\n", state.n_frames); fps = (float)state.n_frames / (uprof_timer_result_get_total_msecs (mainloop_timer) / 1000.0); g_print ("Average fps = %5.2f\n", fps); if (do_pick_timer) { int n_picks = uprof_timer_result_get_start_count (do_pick_timer); g_print ("Pick Stats:\n"); g_print ("Pick count = %d\n", n_picks); g_print ("Average picks per frame = %3.2f\n", (float)n_picks / (float)state.n_frames); g_print ("Average Msecs per pick = %3.2f\n", (float)uprof_timer_result_get_total_msecs (do_pick_timer) / (float)n_picks); g_print ("\n"); } /* XXX: UProfs default reporting code now supports dynamic sizing for the Name * column, the only thing it's missing is support for adding custom columns but * when that's added we should switch away from manual report generation. */ g_print ("Counters:\n"); g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "Name", "Total", "Per Frame"); g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "----", "-----", "---------"); uprof_context_foreach_counter (context, UPROF_COUNTER_SORT_COUNT_INC, print_counter, &state); g_print ("\n"); g_print ("Timers:\n"); root_timers = uprof_context_get_root_timer_results (context); for (l = root_timers; l != NULL; l = l->next) uprof_timer_result_print_and_children ((UProfTimerResult *)l->data, print_timer_fields, &state); g_print ("\n"); }