Refactor, GLFW->SDL
[vg.git] / vg_profiler.h
1 #ifndef VG_PROFILER_H
2 #define VG_PROFILER_H
3
4 #include "vg.h"
5 #include "vg_platform.h"
6
7 #define VG_PROFILE_SAMPLE_COUNT 128
8
9 static int vg_profiler = 0;
10
11 struct vg_profile
12 {
13 const char *name;
14
15 u32 samples[ VG_PROFILE_SAMPLE_COUNT ];
16 u32 buffer_count, buffer_current;
17
18 enum profile_mode
19 {
20 k_profile_mode_frame,
21 k_profile_mode_accum
22 }
23 mode;
24
25 u64 start;
26 };
27
28 VG_STATIC void vg_profile_begin( struct vg_profile *profile )
29 {
30 profile->start = SDL_GetPerformanceCounter();
31 }
32
33 VG_STATIC void vg_profile_increment( struct vg_profile *profile )
34 {
35 profile->buffer_current ++;
36
37 if( profile->buffer_count < VG_PROFILE_SAMPLE_COUNT )
38 profile->buffer_count ++;
39
40 if( profile->buffer_current >= VG_PROFILE_SAMPLE_COUNT )
41 profile->buffer_current = 0;
42
43 profile->samples[ profile->buffer_current ] = 0.0f;
44 }
45
46 VG_STATIC void vg_profile_end( struct vg_profile *profile )
47 {
48 u64 time_end;
49
50 time_end = SDL_GetPerformanceCounter();
51 u64 delta = profile->start - time_end;
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 float rate_mul = 1.0f / (float)SDL_GetPerformanceFrequency();
95
96 for( int i=0; i<VG_PROFILE_SAMPLE_COUNT-1; i++ )
97 {
98 float total = 0.0f;
99
100 for( int j=0; j<count; j++ )
101 {
102 ptrs[j] --;
103
104 if( ptrs[j] < 0 )
105 ptrs[j] = VG_PROFILE_SAMPLE_COUNT-1;
106
107 float sample = (float)profiles[j]->samples[ptrs[j]] * rate_mul,
108 px = (total / (budget)) * sw,
109 wx = (sample / (budget)) * sw;
110
111 ui_rect block = { panel[0] + px, panel[1] + (float)i*sh,
112 wx, sh };
113
114 u32 colour = colours[ (j+colour_offset) % vg_list_size(colours) ];
115 ui_fill_rect( block, colour );
116
117 total += sample;
118 avgs[j] += sample;
119 }
120 }
121
122 char infbuf[64];
123
124 for( int i=0; i<count; i++ )
125 {
126 snprintf( infbuf, 64, "%.4fms %s",
127 avgs[i] * (1.0f/(VG_PROFILE_SAMPLE_COUNT-1)),
128 profiles[i]->name );
129
130 ui_text( (ui_rect){ panel[0] + panel[2] + 4,
131 panel[1] + i * 14, 0, 0 },
132 infbuf,
133 1,
134 k_text_align_left );
135 }
136 }
137
138 VG_STATIC void vg_profiler_init(void)
139 {
140 vg_convar_push( (struct vg_convar){
141 .name = "vg_profiler",
142 .data = &vg_profiler,
143 .data_type = k_convar_dtype_i32,
144 .opt_i32 = { .min=0, .max=1, .clamp=1 },
145 .persistent = 1
146 });
147 }
148
149 #endif /* VG_PROFILER_H */