~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to clutter/clutter-profile.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#ifdef CLUTTER_ENABLE_PROFILE
 
3
 
 
4
#include "clutter-profile.h"
 
5
 
 
6
#include <stdlib.h>
 
7
 
 
8
UProfContext *_clutter_uprof_context;
 
9
#define REPORT_COLUMN0_WIDTH 40
 
10
 
 
11
static gboolean searched_for_gl_uprof_context = FALSE;
 
12
static UProfContext *gl_uprof_context = NULL;
 
13
 
 
14
typedef struct _ClutterUProfReportState
 
15
{
 
16
  gulong n_frames;
 
17
} ClutterUProfReportState;
 
18
 
 
19
static void
 
20
print_counter (UProfCounterResult *counter,
 
21
               gpointer            data)
 
22
{
 
23
  ClutterUProfReportState  *state = data;
 
24
  gulong count = uprof_counter_result_get_count (counter);
 
25
  if (count == 0)
 
26
    return;
 
27
 
 
28
  g_print (" %-*s %-5ld %-5ld\n", REPORT_COLUMN0_WIDTH - 2,
 
29
           uprof_counter_result_get_name (counter),
 
30
           uprof_counter_result_get_count (counter),
 
31
           uprof_counter_result_get_count (counter) / state->n_frames);
 
32
}
 
33
 
 
34
static char *
 
35
print_timer_fields (UProfTimerResult *timer,
 
36
                    guint            *fields_width,
 
37
                    gpointer          data)
 
38
{
 
39
  ClutterUProfReportState *state = data;
 
40
  /* Print the field titles when timer == NULL */
 
41
  if (!timer)
 
42
    return g_strdup_printf ("Per Frame");
 
43
 
 
44
  return g_strdup_printf ("%-10.2f",
 
45
                          uprof_timer_result_get_total_msecs (timer) /
 
46
                          (float)state->n_frames);
 
47
}
 
48
 
 
49
static void
 
50
print_report (UProfReport *report, UProfContext *context)
 
51
{
 
52
  GList *root_timers;
 
53
  GList *l;
 
54
  UProfTimerResult *stage_paint_timer;
 
55
  UProfTimerResult *mainloop_timer;
 
56
  UProfTimerResult *do_pick_timer;
 
57
  float fps;
 
58
  ClutterUProfReportState state;
 
59
 
 
60
  /* FIXME: We need to fix the way Clutter initializes the uprof library
 
61
   * (we don't currently call uprof_init()) and add a mechanism to know
 
62
   * if uprof_init hasn't been called so we can simply bail out of report
 
63
   * generation and not print spurious warning about missing timers.
 
64
   * Probably we can just have uprof_report_print bail out if uprof wasn't
 
65
   * initialized, so we don't have to care here.
 
66
   */
 
67
  mainloop_timer = uprof_context_get_timer_result (context, "Mainloop");
 
68
  if (!mainloop_timer)
 
69
    return;
 
70
  stage_paint_timer = uprof_context_get_timer_result (context, "Redrawing");
 
71
  if (!stage_paint_timer)
 
72
    return;
 
73
  do_pick_timer = uprof_context_get_timer_result (context, "Do pick");
 
74
  if (!do_pick_timer)
 
75
    return;
 
76
 
 
77
  g_print ("\n");
 
78
 
 
79
  state.n_frames = uprof_timer_result_get_start_count (stage_paint_timer);
 
80
  g_print ("Frame count = %lu\n", state.n_frames);
 
81
 
 
82
  fps = (float)state.n_frames / (uprof_timer_result_get_total_msecs (mainloop_timer)
 
83
                                 / 1000.0);
 
84
  g_print ("Average fps = %5.2f\n", fps);
 
85
 
 
86
  if (do_pick_timer)
 
87
    {
 
88
      int n_picks = uprof_timer_result_get_start_count (do_pick_timer);
 
89
 
 
90
      g_print ("Pick Stats:\n");
 
91
      g_print ("Pick count = %d\n", n_picks);
 
92
      g_print ("Average picks per frame = %3.2f\n",
 
93
               (float)n_picks / (float)state.n_frames);
 
94
      g_print ("Average Msecs per pick = %3.2f\n",
 
95
               (float)uprof_timer_result_get_total_msecs (do_pick_timer)
 
96
               / (float)n_picks);
 
97
 
 
98
      g_print ("\n");
 
99
    }
 
100
 
 
101
  /* XXX: UProfs default reporting code now supports dynamic sizing for the Name
 
102
   * column, the only thing it's missing is support for adding custom columns but
 
103
   * when that's added we should switch away from manual report generation. */
 
104
  g_print ("Counters:\n");
 
105
  g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "Name", "Total", "Per Frame");
 
106
  g_print (" %-*s %5s %s\n", REPORT_COLUMN0_WIDTH - 2, "----", "-----", "---------");
 
107
  uprof_context_foreach_counter (context,
 
108
                                 UPROF_COUNTER_SORT_COUNT_INC,
 
109
                                 print_counter,
 
110
                                 &state);
 
111
 
 
112
  g_print ("\n");
 
113
  g_print ("Timers:\n");
 
114
  root_timers = uprof_context_get_root_timer_results (context);
 
115
  for (l = root_timers; l != NULL; l = l->next)
 
116
    uprof_timer_result_print_and_children ((UProfTimerResult *)l->data,
 
117
                                           print_timer_fields,
 
118
                                           &state);
 
119
 
 
120
  g_print ("\n");
 
121
}
 
122
 
 
123
/* FIXME: we should be able to deal with creating the uprof context in
 
124
 * clutter_init instead. I think the only reason I did it this way originally
 
125
 * was as a quick hack.
 
126
 */
 
127
static void __attribute__ ((constructor))
 
128
clutter_uprof_constructor (void)
 
129
{
 
130
  _clutter_uprof_context = uprof_context_new ("Clutter");
 
131
}
 
132
 
 
133
#if 0
 
134
static void
 
135
print_timers (UProfContext *context)
 
136
{
 
137
  GList *root_timers;
 
138
  GList *l;
 
139
 
 
140
  root_timers = uprof_context_get_root_timer_results ();
 
141
 
 
142
  root_timers =
 
143
    g_list_sort_with_data (context->root_timers,
 
144
                           (GCompareDataFunc)_uprof_timer_compare_total_times,
 
145
                           NULL);
 
146
  for (l = context->timers; l != NULL; l = l->next)
 
147
    {
 
148
      UProfTimerState *timer = l->data;
 
149
      timer->children =
 
150
        g_list_sort_with_data (timer->children,
 
151
                               (GCompareDataFunc)
 
152
                                 _uprof_timer_compare_total_times,
 
153
                               NULL);
 
154
    }
 
155
}
 
156
#endif
 
157
 
 
158
static void __attribute__ ((destructor))
 
159
clutter_uprof_destructor (void)
 
160
{
 
161
  if (!(clutter_profile_flags & CLUTTER_PROFILE_DISABLE_REPORT))
 
162
    {
 
163
      UProfReport *report = uprof_report_new ("Clutter report");
 
164
      uprof_report_add_context (report, _clutter_uprof_context);
 
165
      uprof_report_add_context_callback (report, print_report);
 
166
      uprof_report_print (report);
 
167
      uprof_report_unref (report);
 
168
    }
 
169
  uprof_context_unref (_clutter_uprof_context);
 
170
}
 
171
 
 
172
void
 
173
_clutter_profile_suspend (void)
 
174
{
 
175
  if (G_UNLIKELY (!searched_for_gl_uprof_context))
 
176
    {
 
177
      gl_uprof_context = uprof_find_context ("OpenGL");
 
178
      searched_for_gl_uprof_context = TRUE;
 
179
    }
 
180
 
 
181
  if (gl_uprof_context)
 
182
    uprof_context_suspend (gl_uprof_context);
 
183
 
 
184
  /* NB: The Cogl context is linked to this so it will also be suspended... */
 
185
  uprof_context_suspend (_clutter_uprof_context);
 
186
}
 
187
 
 
188
void
 
189
_clutter_profile_resume (void)
 
190
{
 
191
  if (gl_uprof_context)
 
192
    uprof_context_resume (gl_uprof_context);
 
193
 
 
194
  /* NB: The Cogl context is linked to this so it will also be resumed... */
 
195
  uprof_context_resume (_clutter_uprof_context);
 
196
}
 
197
 
 
198
#endif
 
199