From 27d57b789a62162419a1969f3364e896d35bf2bc Mon Sep 17 00:00:00 2001 From: Themaister Date: Mon, 4 Feb 2013 21:46:56 +0100 Subject: [PATCH] Add basic FPS measurement routines. --- driver.c | 40 ++++++++++++++++++++++++++++++++++------ general.h | 10 +++++++++- gfx/gfx_common.c | 3 +++ retroarch.c | 4 ++-- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/driver.c b/driver.c index 0ebdb6b595..2796c27ee9 100644 --- a/driver.c +++ b/driver.c @@ -438,25 +438,25 @@ void init_audio(void) init_dsp_plugin(); #endif - g_extern.audio_data.buffer_free_samples_count = 0; + g_extern.measure_data.buffer_free_samples_count = 0; } static void compute_audio_buffer_statistics(void) { - unsigned samples = min(g_extern.audio_data.buffer_free_samples_count, AUDIO_BUFFER_FREE_SAMPLES_COUNT); + unsigned samples = min(g_extern.measure_data.buffer_free_samples_count, AUDIO_BUFFER_FREE_SAMPLES_COUNT); if (!samples) return; uint64_t accum = 0; for (unsigned i = 0; i < samples; i++) - accum += g_extern.audio_data.buffer_free_samples[i]; + accum += g_extern.measure_data.buffer_free_samples[i]; int avg = accum / samples; uint64_t accum_var = 0; for (unsigned i = 0; i < samples; i++) { - int diff = avg - g_extern.audio_data.buffer_free_samples[i]; + int diff = avg - g_extern.measure_data.buffer_free_samples[i]; accum_var += diff * diff; } @@ -472,9 +472,9 @@ static void compute_audio_buffer_statistics(void) unsigned high_water_count = 0; for (unsigned i = 0; i < samples; i++) { - if (g_extern.audio_data.buffer_free_samples[i] >= low_water_size) + if (g_extern.measure_data.buffer_free_samples[i] >= low_water_size) low_water_count++; - else if (g_extern.audio_data.buffer_free_samples[i] <= high_water_size) + else if (g_extern.measure_data.buffer_free_samples[i] <= high_water_size) high_water_count++; } @@ -485,6 +485,31 @@ static void compute_audio_buffer_statistics(void) (100.0 * high_water_count) / samples); } +static void compute_monitor_fps_statistics(void) +{ + unsigned samples = min(g_extern.measure_data.fps_samples_count, MEASURE_FPS_SAMPLES_COUNT); + if (!samples) + return; + + // Measure statistics on frame time, *not* FPS. + double accum = 0.0; + for (unsigned i = 0; i < samples; i++) + accum += 1.0 / g_extern.measure_data.fps_samples[i]; + + double avg = accum / samples; + double accum_var = 0.0; + for (unsigned i = 0; i < samples; i++) + { + double diff = avg - 1.0 / g_extern.measure_data.fps_samples[i]; + accum_var += diff * diff; + } + + double stddev = sqrt(accum_var / samples); + + RARCH_LOG("Average monitor FPS: %.6f FPS. Standard deviation: %.6f FPS.\n", + 1.0 / avg, 1.0 / (avg - stddev) - 1.0 / avg); +} + void uninit_audio(void) { free(g_extern.audio_data.conv_outsamples); @@ -811,6 +836,8 @@ void init_video_input(void) RARCH_ERR("Failed to load overlay.\n"); } #endif + + g_extern.measure_data.fps_samples_count = 0; } void uninit_video_input(void) @@ -837,6 +864,7 @@ void uninit_video_input(void) #endif deinit_shader_dir(); + compute_monitor_fps_statistics(); } driver_t driver; diff --git a/general.h b/general.h index 17770cf557..4af006469d 100644 --- a/general.h +++ b/general.h @@ -404,10 +404,18 @@ struct global float volume_db; float volume_gain; + } audio_data; + + struct + { #define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024) unsigned buffer_free_samples[AUDIO_BUFFER_FREE_SAMPLES_COUNT]; uint64_t buffer_free_samples_count; - } audio_data; + +#define MEASURE_FPS_SAMPLES_COUNT (8 * 1024) + float fps_samples[MEASURE_FPS_SAMPLES_COUNT]; + uint64_t fps_samples_count; + } measure_data; struct { diff --git a/gfx/gfx_common.c b/gfx/gfx_common.c index a98a7ab376..826738221d 100644 --- a/gfx/gfx_common.c +++ b/gfx/gfx_common.c @@ -100,6 +100,9 @@ bool gfx_get_fps(char *buf, size_t size, bool always_write) last_fps = tv_to_fps(&tmp_tv, &new_tv, 180); + unsigned write_index = g_extern.measure_data.fps_samples_count++ & (MEASURE_FPS_SAMPLES_COUNT - 1); + g_extern.measure_data.fps_samples[write_index] = last_fps; + #ifdef RARCH_CONSOLE snprintf(buf, size, "FPS: %6.1f || Frames: %d", last_fps, g_extern.frame_count); #else diff --git a/retroarch.c b/retroarch.c index a3a3ea4570..3c1dd6486c 100644 --- a/retroarch.c +++ b/retroarch.c @@ -182,8 +182,8 @@ static void readjust_audio_input_rate(void) //RARCH_LOG_OUTPUT("Audio buffer is %u%% full\n", // (unsigned)(100 - (avail * 100) / g_extern.audio_data.driver_buffer_size)); - unsigned write_index = (g_extern.audio_data.buffer_free_samples_count++) & (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); - g_extern.audio_data.buffer_free_samples[write_index] = avail; + unsigned write_index = g_extern.measure_data.buffer_free_samples_count++ & (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); + g_extern.measure_data.buffer_free_samples[write_index] = avail; int half_size = g_extern.audio_data.driver_buffer_size / 2; int delta_mid = avail - half_size;