build system revision
[vg.git] / vg_profiler.c
diff --git a/vg_profiler.c b/vg_profiler.c
new file mode 100644 (file)
index 0000000..d203c92
--- /dev/null
@@ -0,0 +1,116 @@
+#include "vg_platform.h"
+#include "vg_profiler.h"
+#include "vg_engine.h"
+#include "vg_imgui.h"
+
+int vg_profiler = 0;
+
+void vg_profile_begin( struct vg_profile *profile )
+{
+   profile->start = SDL_GetPerformanceCounter();
+}
+
+void vg_profile_increment( struct vg_profile *profile )
+{
+   profile->buffer_current ++;
+
+   if( profile->buffer_count < VG_PROFILE_SAMPLE_COUNT )
+      profile->buffer_count ++;
+
+   if( profile->buffer_current >= VG_PROFILE_SAMPLE_COUNT )
+      profile->buffer_current = 0;
+
+   profile->samples[ profile->buffer_current ] = 0;
+}
+
+void vg_profile_end( struct vg_profile *profile )
+{
+   u64 time_end = SDL_GetPerformanceCounter(),
+       delta    = time_end - profile->start;
+
+   if( profile->mode == k_profile_mode_frame ){
+      profile->samples[ profile->buffer_current ] = delta;
+      vg_profile_increment( profile );
+   }
+   else{
+      profile->samples[ profile->buffer_current ] += delta;
+   }
+}
+
+void vg_profile_drawn( struct vg_profile **profiles, u32 count,
+                       f64 budget, ui_rect panel,
+                       int dir, i32 normalize )
+{
+   if( panel[2] == 0 )
+      panel[2] = 256;
+
+   if( panel[3] == 0 )
+      panel[3] = VG_PROFILE_SAMPLE_COUNT * 2;
+
+   f64 sh = (f32)panel[3^dir] / (f32)VG_PROFILE_SAMPLE_COUNT,
+       sw = (f32)panel[2^dir];
+
+   ui_fill( panel, 0xa0000000 );
+
+   if( count > 8 ) vg_fatal_error( "Too many profiles\n" );
+
+   f64 avgs[8];
+   u32 colours[8];
+   for( u32 i=0; i<count; i ++ ){
+      avgs[i] = 0.0;
+      colours[i] = ui_colour( k_ui_red + ((i*3)&0xe) );
+   }
+
+   f64 rate_mul = 1000.0 / (f64)SDL_GetPerformanceFrequency();
+
+   for( i32 i=0; i<VG_PROFILE_SAMPLE_COUNT; i++ ){
+      f64 total = 0.0;
+
+      if( normalize ){
+         budget = 0.0;
+         for( u32 j=0; j<count; j++ )
+            budget += (f64)profiles[j]->samples[i] * rate_mul;
+      }
+
+      for( int j=0; j<count; j++ ){
+         f64 sample  = (f64)profiles[j]->samples[i] * rate_mul,
+                px   = (total  / budget) * sw,
+                wx   = (sample / budget) * sw;
+
+         ui_rect block;
+         block[0^dir] = panel[0^dir] + px;
+         block[1^dir] = panel[1^dir] + (f32)i*sh;
+         block[2^dir] = VG_MAX( 1, wx-1 );
+         block[3^dir] = ceilf(sh)-1;
+         ui_fill( block, colours[j] );
+
+         total += sample;
+         avgs[j] += sample;
+      }
+   }
+
+   char infbuf[64];
+
+   snprintf( infbuf, 64, "accuracy: %.7fms", rate_mul );
+   ui_text( (ui_rect){ panel[0] + 4,
+                       panel[1] + panel[3] - 14, 500, 30 }, 
+                       infbuf,
+                       1,
+                       k_ui_align_left, 0 );
+
+   for( int i=0; i<count; i++ ){
+      snprintf( infbuf, 64, "%.4fms %s", 
+                        avgs[i] * (1.0f/(VG_PROFILE_SAMPLE_COUNT-1)),
+                        profiles[i]->name );
+
+      ui_text( (ui_rect){ panel[0] + 4,
+                          panel[1] + panel[3] + 4 + i*14, 
+                          panel[2]-8, 14 }, 
+                          infbuf, 1, k_ui_align_left, 0 );
+   }
+}
+
+void vg_profiler_init(void)
+{
+   VG_VAR_I32( vg_profiler, flags=VG_VAR_PERSISTENT );
+}