simplify gitignore
[vg.git] / src / vg / vg_profiler.h
1 #ifndef VG_PROFILER_H
2 #define VG_PROFILER_H
3
4 #include "vg_platform.h"
5
6 #define VG_PROFILE_SAMPLE_COUNT 128
7
8 static int vg_profiler = 0;
9
10 struct vg_profile
11 {
12 const char *name;
13
14 float samples[ VG_PROFILE_SAMPLE_COUNT ];
15 u32 buffer_count, buffer_current;
16
17 enum profile_mode
18 {
19 k_profile_mode_frame,
20 k_profile_mode_accum
21 }
22 mode;
23
24 struct timespec start;
25 };
26
27 VG_STATIC void vg_profile_begin( struct vg_profile *profile )
28 {
29 clock_gettime( CLOCK_REALTIME, &profile->start );
30 }
31
32 VG_STATIC void vg_profile_increment( struct vg_profile *profile )
33 {
34 profile->buffer_current ++;
35
36 if( profile->buffer_count < VG_PROFILE_SAMPLE_COUNT )
37 profile->buffer_count ++;
38
39 if( profile->buffer_current >= VG_PROFILE_SAMPLE_COUNT )
40 profile->buffer_current = 0;
41
42 profile->samples[ profile->buffer_current ] = 0.0f;
43 }
44
45 VG_STATIC void vg_profile_end( struct vg_profile *profile )
46 {
47 struct timespec time_end;
48
49 clock_gettime( CLOCK_REALTIME, &time_end );
50 float delta = vg_time_diff( profile->start, time_end );
51
52
53 if( profile->mode == k_profile_mode_frame )
54 {
55 profile->samples[ profile->buffer_current ] = delta;
56 vg_profile_increment( profile );
57 }
58 else
59 {
60 profile->samples[ profile->buffer_current ] += delta;
61 }
62 }
63
64 VG_STATIC void vg_profile_drawn( struct vg_profile **profiles, u32 count,
65 float budget, ui_rect panel, u32 colour_offset )
66 {
67 if( !vg_profiler )
68 return;
69
70 if( panel[2] == 0 )
71 panel[2] = 256;
72
73 if( panel[3] == 0 )
74 panel[3] = VG_PROFILE_SAMPLE_COUNT * 2;
75
76 float sh = panel[3] / VG_PROFILE_SAMPLE_COUNT,
77 sw = panel[2];
78
79 ui_fill_rect( panel, 0xa0000000 );
80
81 assert( count <= 8 );
82 float avgs[8];
83 int ptrs[8];
84
85 for( int i=0; i<count; i++ )
86 {
87 ptrs[i] = profiles[i]->buffer_current;
88 avgs[i] = 0.0f;
89 }
90
91 u32 colours[] = { 0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000,
92 0xffff00ff, 0xffffff00 };
93
94 for( int i=0; i<VG_PROFILE_SAMPLE_COUNT-1; i++ )
95 {
96 float total = 0.0f;
97
98 for( int j=0; j<count; j++ )
99 {
100 ptrs[j] --;
101
102 if( ptrs[j] < 0 )
103 ptrs[j] = VG_PROFILE_SAMPLE_COUNT-1;
104
105 float sample = profiles[j]->samples[ptrs[j]],
106 px = (total / (budget)) * sw,
107 wx = (sample / (budget)) * sw;
108
109 ui_rect block = { panel[0] + px, panel[1] + (float)i*sh,
110 wx, sh };
111
112 u32 colour = colours[ (j+colour_offset) % vg_list_size(colours) ];
113 ui_fill_rect( block, colour );
114
115 total += sample;
116 avgs[j] += sample;
117 }
118 }
119
120 char infbuf[64];
121
122 for( int i=0; i<count; i++ )
123 {
124 snprintf( infbuf, 64, "%.4fms %s",
125 avgs[i] * (1.0f/(VG_PROFILE_SAMPLE_COUNT-1)),
126 profiles[i]->name );
127
128 ui_text( (ui_rect){ panel[0] + panel[2] + 4,
129 panel[1] + i * 14, 0, 0 },
130 infbuf,
131 1,
132 k_text_align_left );
133 }
134 }
135
136 VG_STATIC void vg_profiler_init(void)
137 {
138 vg_convar_push( (struct vg_convar){
139 .name = "vg_profiler",
140 .data = &vg_profiler,
141 .data_type = k_convar_dtype_i32,
142 .opt_i32 = { .min=0, .max=1, .clamp=1 },
143 .persistent = 1
144 });
145 }
146
147 #endif /* VG_PROFILER_H */