From e79f30604f4fe77cba65dc6094384f033cca1328 Mon Sep 17 00:00:00 2001 From: Gregor Richards Date: Sat, 17 Dec 2016 20:10:51 -0500 Subject: [PATCH] Better stall timing We now stall not until we've reached parity (which makes no sense since we expect latency), but only until we're not likely to stall again. --- network/netplay/netplay_frontend.c | 39 ++++++++++++++++++++---------- network/netplay/netplay_io.c | 18 +++----------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/network/netplay/netplay_frontend.c b/network/netplay/netplay_frontend.c index 8f5c0300cc..c5571b0493 100644 --- a/network/netplay/netplay_frontend.c +++ b/network/netplay/netplay_frontend.c @@ -152,6 +152,26 @@ static bool get_self_input_state(netplay_t *netplay) return true; } +static uint32_t netplay_max_ahead(netplay_t *netplay) +{ + uint32_t max_ahead; + + /* Figure out how many frames we're allowed to be ahead: Ideally we need to be + * able to run our entire stall worth of frames in one real frame. In + * practice, we'll allow a couple jitter frames. (FIXME: hard coded + * as three 60FPS frames) */ + if (netplay_data->frame_run_time_avg) + max_ahead = 50000 / netplay_data->frame_run_time_avg; + else + max_ahead = NETPLAY_MAX_STALL_FRAMES; + if (max_ahead > NETPLAY_MAX_STALL_FRAMES) + max_ahead = NETPLAY_MAX_STALL_FRAMES; + if (max_ahead < 2) + max_ahead = 2; + + return max_ahead; +} + /** * netplay_poll: * @netplay : pointer to netplay object @@ -198,8 +218,11 @@ static bool netplay_poll(void) switch (netplay_data->stall) { case NETPLAY_STALL_RUNNING_FAST: + { + uint32_t max_ahead = netplay_max_ahead(netplay_data); netplay_update_unread_ptr(netplay_data); - if (netplay_data->unread_frame_count >= netplay_data->self_frame_count) + if (netplay_data->unread_frame_count + max_ahead - 2 + > netplay_data->self_frame_count) { netplay_data->stall = NETPLAY_STALL_NONE; for (i = 0; i < netplay_data->connections_size; i++) @@ -210,6 +233,7 @@ static bool netplay_poll(void) } } break; + } case NETPLAY_STALL_NO_CONNECTION: /* We certainly haven't fixed this */ @@ -217,18 +241,7 @@ static bool netplay_poll(void) default: /* not stalling */ { - retro_time_t max_ahead; - - /* Figure out how many frames we're allowed to be ahead: Ideally we need to be - * able to run our entire stall worth of frames in one real frame. In - * practice, we'll allow a couple jitter frames. (FIXME: hard coded - * as three 60FPS frame) */ - if (netplay_data->frame_run_time_avg) - max_ahead = 50000 / netplay_data->frame_run_time_avg; - else - max_ahead = NETPLAY_MAX_STALL_FRAMES; - if (max_ahead > NETPLAY_MAX_STALL_FRAMES) - max_ahead = NETPLAY_MAX_STALL_FRAMES; + uint32_t max_ahead = netplay_max_ahead(netplay_data); /* Are we too far ahead? */ netplay_update_unread_ptr(netplay_data); diff --git a/network/netplay/netplay_io.c b/network/netplay/netplay_io.c index e710992866..76f2f3b56a 100644 --- a/network/netplay/netplay_io.c +++ b/network/netplay/netplay_io.c @@ -479,9 +479,8 @@ static bool netplay_get_cmd(netplay_t *netplay, dframe = &netplay->buffer[netplay->read_ptr[player]]; if (!netplay_delta_frame_ready(netplay, dframe, netplay->read_frame_count[player])) { - /* FIXME: Catastrophe! */ - RARCH_ERR("Netplay input from %u without a ready delta frame!\n", player); - return netplay_cmd_nak(netplay, connection); + /* Hopefully we'll be ready after another round of input */ + goto shrt; } memcpy(dframe->real_input_state[player], buffer + 2, WORDS_PER_INPUT*sizeof(uint32_t)); @@ -1078,8 +1077,8 @@ static bool netplay_get_cmd(netplay_t *netplay, if (!netplay_delta_frame_ready(netplay, &netplay->buffer[netplay->read_ptr[connection->player]], frame)) { - RARCH_ERR("CMD_LOAD_SAVESTATE with unready delta frame.\n"); - return netplay_cmd_nak(netplay, connection); + /* Hopefully it will be after another round of input */ + goto shrt; } RECV(&isize, sizeof(isize)) @@ -1236,15 +1235,6 @@ int netplay_poll_net_input(netplay_t *netplay, bool block) netplay->timeout_cnt++; - /* Make sure we're actually ready for data */ - if (netplay->self_mode >= NETPLAY_CONNECTION_CONNECTED) - { - netplay_update_unread_ptr(netplay); - if (!netplay_delta_frame_ready(netplay, - &netplay->buffer[netplay->unread_ptr], netplay->unread_frame_count)) - break; - } - /* Read input from each connection */ for (i = 0; i < netplay->connections_size; i++) {