fix race condition in frame count with video_threaded on

This commit is contained in:
Brad Parker 2017-01-17 18:42:58 -05:00
parent 4fbd41852a
commit a220815b40
8 changed files with 71 additions and 50 deletions

View File

@ -282,7 +282,7 @@ bool video_context_driver_check_window(gfx_ctx_size_t *size_data)
size_data->quit,
size_data->resize,
size_data->width,
size_data->height, ((unsigned int)*video_driver_get_frame_count_ptr()));
size_data->height, (unsigned int)video_driver_get_frame_count());
return true;
}

View File

@ -65,6 +65,34 @@
#define FPS_UPDATE_INTERVAL 256
#ifdef HAVE_THREADS
#define video_driver_lock() \
if (display_lock) \
slock_lock(display_lock)
#define video_driver_unlock() \
if (display_lock) \
slock_unlock(display_lock)
#define video_driver_lock_free() \
slock_free(display_lock); \
display_lock = NULL
#define video_driver_threaded_lock() \
if (video_driver_is_threaded()) \
video_driver_lock()
#define video_driver_threaded_unlock() \
if (video_driver_is_threaded()) \
video_driver_unlock()
#else
#define video_driver_lock() ((void)0)
#define video_driver_unlock() ((void)0)
#define video_driver_lock_free() ((void)0)
#define video_driver_threaded_lock() ((void)0)
#define video_driver_threaded_unlock() ((void)0)
#endif
typedef struct video_pixel_scaler
{
struct scaler_ctx *scaler;
@ -1037,10 +1065,15 @@ bool video_monitor_get_fps(
static retro_time_t curr_time;
static retro_time_t fps_time;
retro_time_t new_time = cpu_features_get_time_usec();
uint64_t frame_count;
video_driver_threaded_lock();
frame_count = video_driver_frame_count;
video_driver_threaded_unlock();
*buf = '\0';
if (video_driver_frame_count)
if (frame_count)
{
static float last_fps;
bool ret = false;
@ -1050,7 +1083,7 @@ bool video_monitor_get_fps(
video_driver_frame_time_samples[write_index] = new_time - fps_time;
fps_time = new_time;
if ((video_driver_frame_count % FPS_UPDATE_INTERVAL) == 0)
if ((frame_count % FPS_UPDATE_INTERVAL) == 0)
{
char frames_text[64];
@ -1072,7 +1105,7 @@ bool video_monitor_get_fps(
strlcat(buf, "Frames: ", size);
snprintf(frames_text, sizeof(frames_text), STRING_REP_UINT64,
(unsigned long long)video_driver_frame_count);
(unsigned long long)frame_count);
strlcat(buf, frames_text, size);
ret = true;
@ -1082,7 +1115,7 @@ bool video_monitor_get_fps(
snprintf(buf_fps, size_fps, "FPS: %6.1f || %s: " STRING_REP_UINT64,
last_fps,
msg_hash_to_str(MSG_FRAMES),
(unsigned long long)video_driver_frame_count);
(unsigned long long)frame_count);
return ret;
}
@ -1320,26 +1353,6 @@ void video_driver_menu_settings(void **list_data, void *list_info_data,
#endif
}
#ifdef HAVE_THREADS
#define video_driver_lock() \
if (display_lock) \
slock_lock(display_lock)
#define video_driver_unlock() \
if (display_lock) \
slock_unlock(display_lock)
#define video_driver_lock_free() \
slock_free(display_lock); \
display_lock = NULL
#else
#define video_driver_lock() ((void)0)
#define video_driver_unlock() ((void)0)
#define video_driver_lock_free() ((void)0)
#endif
static void video_driver_lock_new(void)
{
video_driver_lock_free();
@ -1687,9 +1700,13 @@ bool video_driver_read_viewport(uint8_t *buffer)
return false;
}
uint64_t *video_driver_get_frame_count_ptr(void)
uint64_t video_driver_get_frame_count(void)
{
return &video_driver_frame_count;
uint64_t frame_count;
video_driver_threaded_lock();
frame_count = video_driver_frame_count;
video_driver_threaded_unlock();
return frame_count;
}
bool video_driver_frame_filter_alive(void)
@ -2058,7 +2075,8 @@ void video_driver_frame(const void *data, unsigned width,
static struct retro_perf_counter video_frame_conv = {0};
unsigned output_width = 0;
unsigned output_height = 0;
unsigned output_pitch = 0;
unsigned output_pitch = 0;
uint64_t frame_count = 0;
const char *msg = NULL;
if (!video_driver_active)
@ -2115,13 +2133,16 @@ void video_driver_frame(const void *data, unsigned width,
&& video_info.font_enable && msg)
strlcpy(video_driver_msg, msg, sizeof(video_driver_msg));
video_driver_threaded_lock();
frame_count = video_driver_frame_count;
video_driver_frame_count++;
video_driver_threaded_unlock();
if (!current_video || !current_video->frame(
video_driver_data, data, width, height,
video_driver_frame_count,
frame_count,
pitch, video_driver_msg, video_info))
video_driver_active = false;
video_driver_frame_count++;
}
void video_driver_display_type_set(enum rarch_display_type type)

View File

@ -275,7 +275,7 @@ bool video_driver_find_driver(void);
void video_driver_apply_state_changes(void);
bool video_driver_read_viewport(uint8_t *buffer);
bool video_driver_cached_frame(void);
uint64_t *video_driver_get_frame_count_ptr(void);
uint64_t video_driver_get_frame_count(void);
bool video_driver_frame_filter_alive(void);
bool video_driver_frame_filter_is_32bit(void);
void video_driver_default_settings(void);

View File

@ -809,9 +809,9 @@ static void mui_render_menu_list(mui_handle_t *mui,
float sum = 0;
unsigned header_height = 0;
size_t i = 0;
uint64_t *frame_count = NULL;
uint64_t frame_count = NULL;
file_list_t *list = NULL;
frame_count = video_driver_get_frame_count_ptr();
frame_count = video_driver_get_frame_count();
if (!menu_display_get_update_pending())
return;
@ -859,7 +859,7 @@ static void mui_render_menu_list(mui_handle_t *mui,
y,
width,
height,
*frame_count / 20,
frame_count / 20,
font_hover_color,
entry_selected,
rich_label,
@ -1037,7 +1037,7 @@ static void mui_frame(void *data)
size_t selection = 0;
size_t title_margin = 0;
mui_handle_t *mui = (mui_handle_t*)data;
uint64_t *frame_count = video_driver_get_frame_count_ptr();
uint64_t frame_count = video_driver_get_frame_count();
settings_t *settings = config_get_ptr();
bool background_rendered = false;
bool libretro_running = menu_display_libretro_running();
@ -1360,7 +1360,7 @@ static void mui_frame(void *data)
ticker.s = title_buf;
ticker.len = ticker_limit;
ticker.idx = *frame_count / 100;
ticker.idx = frame_count / 100;
ticker.str = title;
ticker.selected = true;
@ -1383,7 +1383,7 @@ static void mui_frame(void *data)
ticker.s = title_buf_msg_tmp;
ticker.len = ticker_limit;
ticker.idx = *frame_count / 20;
ticker.idx = frame_count / 20;
ticker.str = title_buf_msg;
ticker.selected = true;

View File

@ -394,11 +394,11 @@ static void rgui_render(void *data)
char title_msg[64];
char msg[255];
bool msg_force = false;
uint64_t *frame_count = NULL;
uint64_t frame_count = NULL;
settings_t *settings = config_get_ptr();
rgui_t *rgui = (rgui_t*)data;
frame_count = video_driver_get_frame_count_ptr();
frame_count = video_driver_get_frame_count();
msg[0] = title[0] = title_buf[0] = title_msg[0] = '\0';
@ -503,7 +503,7 @@ static void rgui_render(void *data)
ticker.s = title_buf;
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10;
ticker.idx = *frame_count / RGUI_TERM_START_X(fb_width);
ticker.idx = frame_count / RGUI_TERM_START_X(fb_width);
ticker.str = title;
ticker.selected = true;
@ -595,7 +595,7 @@ static void rgui_render(void *data)
ticker.s = entry_title_buf;
ticker.len = RGUI_TERM_WIDTH(fb_width) - (entry_spacing + 1 + 2);
ticker.idx = *frame_count / RGUI_TERM_START_X(fb_width);
ticker.idx = frame_count / RGUI_TERM_START_X(fb_width);
ticker.str = entry_path;
ticker.selected = entry_selected;

View File

@ -2073,10 +2073,10 @@ static void xmb_draw_items(
size_t i;
math_matrix_4x4 mymat;
menu_display_ctx_rotate_draw_t rotate_draw;
uint64_t *frame_count = NULL;
uint64_t frame_count = NULL;
xmb_node_t *core_node = NULL;
size_t end = 0;
frame_count = video_driver_get_frame_count_ptr();
frame_count = video_driver_get_frame_count();
if (!list || !list->size)
return;
@ -2230,7 +2230,7 @@ static void xmb_draw_items(
ticker.s = name;
ticker.len = ticker_limit;
ticker.idx = *frame_count / 20;
ticker.idx = frame_count / 20;
ticker.str = ticker_str;
ticker.selected = (i == current);
@ -2261,7 +2261,7 @@ static void xmb_draw_items(
ticker.s = value;
ticker.len = 35;
ticker.idx = *frame_count / 20;
ticker.idx = frame_count / 20;
ticker.str = entry_value;
ticker.selected = (i == current);

View File

@ -317,13 +317,13 @@ static bool zarch_zui_list_item(zui_t *zui, struct zui_tabbed *tab, int x1, int
menu_animation_ctx_ticker_t ticker;
unsigned ticker_size;
char title_buf[PATH_MAX_LENGTH];
uint64_t *frame_count = NULL;
uint64_t frame_count = NULL;
unsigned id = zarch_zui_hash(zui, label);
int x2 = x1 + zui->width - 290 - 40;
int y2 = y1 + 50;
bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
const float *bg = zui_bg_panel;
frame_count = video_driver_get_frame_count_ptr();
frame_count = video_driver_get_frame_count();
title_buf[0] = '\0';
@ -346,7 +346,7 @@ static bool zarch_zui_list_item(zui_t *zui, struct zui_tabbed *tab, int x1, int
ticker.s = title_buf;
ticker.len = ticker_size;
ticker.idx = *frame_count / 50;
ticker.idx = frame_count / 50;
ticker.str = label;
ticker.selected = (bg == zui_bg_hilite || bg == zui_bg_pad_hilite);

View File

@ -673,7 +673,7 @@ bool runloop_ctl(enum runloop_ctl_state state, void *data)
* d) Video driver no longer alive.
* e) End of BSV movie and BSV EOF exit is true. (TODO/FIXME - explain better)
*/
#define time_to_exit(quit_key_pressed) (runloop_shutdown_initiated || quit_key_pressed || !video_driver_is_alive() || bsv_movie_ctl(BSV_MOVIE_CTL_END_EOF, NULL) || (runloop_max_frames && (*(video_driver_get_frame_count_ptr()) >= runloop_max_frames)) || runloop_exec)
#define time_to_exit(quit_key_pressed) (runloop_shutdown_initiated || quit_key_pressed || !video_driver_is_alive() || bsv_movie_ctl(BSV_MOVIE_CTL_END_EOF, NULL) || (runloop_max_frames && (video_driver_get_frame_count() >= runloop_max_frames)) || runloop_exec)
#define runloop_check_cheevos() (settings->cheevos.enable && cheevos_loaded && (!cheats_are_enabled && !cheats_were_enabled))