From 852309464f46b1ad4b732e93c982869ad58bdbea Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Thu, 7 Dec 2017 04:51:54 +1100 Subject: [PATCH] [client] more polling improvements --- client/ivshmem/ivshmem.c | 4 ++-- client/main.c | 52 +++++++++++++++++++++++----------------- 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/client/ivshmem/ivshmem.c b/client/ivshmem/ivshmem.c index 70090bea..19575407 100644 --- a/client/ivshmem/ivshmem.c +++ b/client/ivshmem/ivshmem.c @@ -489,8 +489,8 @@ enum IVSHMEMWaitResult ivshmem_wait_irq(uint16_t vector, unsigned int timeout) FD_SET(fd, &fds); struct timeval tv; - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout - tv.tv_sec * 1000) * 1000; + tv.tv_sec = timeout / 1000000L; + tv.tv_usec = timeout % 1000000L; while(true) { diff --git a/client/main.c b/client/main.c index 5d389ad7..4cce02a5 100644 --- a/client/main.c +++ b/client/main.c @@ -43,8 +43,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "lg-renderers.h" -#define VBO_BUFFERS 2 - struct AppState { bool hasBufferStorage; @@ -194,37 +192,47 @@ int renderThread(void * unused) const uint64_t presentTime = detectPresentTime(); uint64_t pollDelay = 0; - uint64_t pollStep = 0; uint64_t drawStart = 0; uint64_t drawTime = 0; uint64_t fpsStart = 0; uint64_t fpsTime = 0; + #define SYNC_WINDOW 2000 + while(state.running) { - usleep(pollDelay); - if(header.dataPos == state.shm->dataPos) - { - pollStep = 0; - do - { - ++pollStep; - if (pollDelay + pollStep < 30000) - pollDelay += pollStep; - usleep(1); - } - while(header.dataPos == state.shm->dataPos && state.running); + // wait for a frame + if (pollDelay > SYNC_WINDOW) + usleep(pollDelay - SYNC_WINDOW); + else + usleep(pollDelay); - if (!state.running) - break; + // we shouldn't have a frame yet, retard the timing a bit + if (header.dataPos != state.shm->dataPos) + { + if (pollDelay >= SYNC_WINDOW / 2) + pollDelay -= SYNC_WINDOW / 2; + else + pollDelay = 0; } else { - // we were late, step back a chunk - pollStep += 100; - if (pollDelay > pollStep) - pollDelay -= pollStep; + const uint64_t loopStart = microtime(); + while(header.dataPos == state.shm->dataPos && state.running) + { + // if we timed out, wait for an interrupt or a timeout + if (microtime() - loopStart > SYNC_WINDOW) + { + ivshmem_wait_irq(0, 1000000/30); + break; + } + } + + pollDelay += microtime() - loopStart; + pollDelay -= SYNC_WINDOW / 2; + if (pollDelay > (1000000/30)) + pollDelay = presentTime; } if (!state.running) @@ -386,7 +394,7 @@ int renderThread(void * unused) char str[32]; const float avgFPS = 1000.0f / (((float)fpsTime / frameCount) / 1000.0f); - snprintf(str, sizeof(str), "FPS: %8.4f", avgFPS); + snprintf(str, sizeof(str), "FPS: %8.4f, Sync: %5lu", avgFPS, pollDelay); SDL_Color color = {0xff, 0xff, 0xff}; if (!(textSurface = TTF_RenderText_Blended(state.font, str, color))) {