blob: 6ec7379dcddf33d991d0cec8fee06ffc61282981 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fps_counter.h"
#include <stddef.h>
#include <stdio.h>
#include <sys/time.h>
// Return current time in milliseconds.
static double
time_now_seconds(void * opaque)
{
struct timeval tm;
gettimeofday(&tm, NULL);
return tm.tv_sec * 1.0 + (tm.tv_usec / 1e9);
}
// Set this to 0 to disable unit-testing support.
#define SUPPORT_UNIT_TESTING 1
#if SUPPORT_UNIT_TESTING
static fps_counter_clock_callback_t s_clock_callback = &time_now_seconds;
static void * s_clock_opaque = NULL;
// Ensure that the implementation uses |clock_callback(clock_opaque)| to get
// the current time during unit-testing.
void
fps_counter_set_clock_for_testing(fps_counter_clock_callback_t clock_callback, void * clock_opaque)
{
if (!clock_callback)
{
clock_callback = &time_now_seconds;
clock_opaque = NULL;
}
s_clock_callback = clock_callback;
s_clock_opaque = clock_opaque;
}
#define GET_CLOCK_SECONDS() s_clock_callback(s_clock_opaque)
#else // !SUPPORT_UNIT_TESTING
#define GET_CLOCK_SECONDS() time_now_seconds(NULL)
#endif // !SUPPORT_UNIT_TESTING
#define SECONDS_INCREMENT 4.0
void
fps_counter_start(fps_counter_t * fps)
{
fps->current_fps = 0.;
fps->start_time = GET_CLOCK_SECONDS();
fps->next_time = fps->start_time + SECONDS_INCREMENT;
fps->frame_count = 0;
fps->frame_count_prev = 0;
}
bool
fps_counter_tick(fps_counter_t * fps)
{
fps->frame_count++;
double now_secs = GET_CLOCK_SECONDS();
if (now_secs < fps->next_time)
return false;
fps->current_fps = (fps->frame_count - fps->frame_count_prev) / (now_secs - fps->start_time);
fps->frame_count_prev = fps->frame_count;
fps->start_time = fps->next_time;
while (fps->next_time <= now_secs)
fps->next_time += SECONDS_INCREMENT;
return true;
}
bool
fps_counter_stop(fps_counter_t * fps)
{
if (fps->frame_count > fps->frame_count_prev)
return fps_counter_tick(fps);
return false;
}
void
fps_counter_tick_and_print(fps_counter_t * fps)
{
if (fps_counter_tick(fps))
{
printf("FPS: %1.f\n", fps->current_fps);
fflush(stdout);
}
}
void
fps_counter_stop_and_print(fps_counter_t * fps)
{
if (fps->frame_count > fps->frame_count_prev)
fps_counter_tick_and_print(fps);
}