[client] use atomics to track frame counts and avoid extra signals

This commit is contained in:
Geoffrey McRae 2020-08-09 15:14:17 +10:00
parent 19c2fe9b5e
commit 302b988524
3 changed files with 24 additions and 11 deletions

View File

@ -1 +1 @@
B2-rc2-25-g3511fb8d59+1 B2-rc2-28-g19c2fe9b5e+1

View File

@ -34,6 +34,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h> #include <assert.h>
#include <stdatomic.h>
#if SDL_VIDEO_DRIVER_X11_XINPUT2 #if SDL_VIDEO_DRIVER_X11_XINPUT2
// because SDL2 sucks and we need to turn it off // because SDL2 sucks and we need to turn it off
@ -69,6 +70,8 @@ static LGThread *t_cursor = NULL;
static LGThread *t_frame = NULL; static LGThread *t_frame = NULL;
static SDL_Cursor *cursor = NULL; static SDL_Cursor *cursor = NULL;
static atomic_uint a_framesPending = 0;
struct AppState state; struct AppState state;
// this structure is initialized in config.c // this structure is initialized in config.c
@ -193,12 +196,12 @@ static int renderThread(void * unused)
if (state.renderTime > 1e9) if (state.renderTime > 1e9)
{ {
const float avgUPS = 1000.0f / (((float)state.renderTime / state.frameCount ) / 1e6f); const float avgUPS = 1000.0f / (((float)state.renderTime / atomic_load_explicit(&state.frameCount, memory_order_acquire)) / 1e6f);
const float avgFPS = 1000.0f / (((float)state.renderTime / state.renderCount) / 1e6f); const float avgFPS = 1000.0f / (((float)state.renderTime / state.renderCount) / 1e6f);
state.lgr->update_fps(state.lgrData, avgUPS, avgFPS); state.lgr->update_fps(state.lgrData, avgUPS, avgFPS);
atomic_store_explicit(&state.frameCount, 0, memory_order_release);
state.renderTime = 0; state.renderTime = 0;
state.frameCount = 0;
state.renderCount = 0; state.renderCount = 0;
} }
} }
@ -214,8 +217,15 @@ static int renderThread(void * unused)
} }
if (state.frameTime > 0) if (state.frameTime > 0)
{
/* if there are frames pending already, don't wait on the event */
if (atomic_load_explicit(&a_framesPending, memory_order_acquire) > 0)
if (atomic_fetch_sub_explicit(&a_framesPending, 1, memory_order_release) > 1)
continue;
lgWaitEventAbs(e_frame, &time); lgWaitEventAbs(e_frame, &time);
} }
}
state.running = false; state.running = false;
@ -447,10 +457,12 @@ static int frameThread(void * unused)
DEBUG_ERROR("renderer on frame event returned failure"); DEBUG_ERROR("renderer on frame event returned failure");
break; break;
} }
lgmpClientMessageDone(queue);
++state.frameCount;
atomic_fetch_add_explicit(&state.frameCount, 1, memory_order_relaxed);
if (atomic_fetch_add_explicit(&a_framesPending, 1, memory_order_relaxed) == 0)
lgSignalEvent(e_frame); lgSignalEvent(e_frame);
lgmpClientMessageDone(queue);
} }
lgmpClientUnsubscribe(&queue); lgmpClientUnsubscribe(&queue);

View File

@ -18,6 +18,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stdatomic.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "interface/app.h" #include "interface/app.h"
@ -75,7 +76,7 @@ struct AppState
PLGMPClientQueue frameQueue; PLGMPClientQueue frameQueue;
PLGMPClientQueue pointerQueue; PLGMPClientQueue pointerQueue;
uint64_t frameTime; atomic_uint_least64_t frameTime;
uint64_t lastFrameTime; uint64_t lastFrameTime;
uint64_t renderTime; uint64_t renderTime;
uint64_t frameCount; uint64_t frameCount;