From a5338c572975a82b9efbf95755103176ebbb67a8 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 8 Sep 2019 01:52:45 +0200 Subject: alarm(1) before SEM_WAIT(...) in worker_(sdl|gl) to avoid edge cases --- src/main.c | 81 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 27 deletions(-) (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c index 0bb2307..7dd18ee 100644 --- a/src/main.c +++ b/src/main.c @@ -31,12 +31,7 @@ #include // errno #include // uint32_t #include // printf() - -#ifdef DEBUG -#define TRACE(hint) printf("%s(): %s\n", __func__, hint) -#else -#define TRACE(hint) -#endif +#include // sigaction() #ifdef DEBUG_SEM #define TRACE_SEM(sem,op,hint) printf("%s(): %s(%s) %s\n", __func__, op, #sem, hint) @@ -86,6 +81,7 @@ int parent(); int worker_sdl(); int worker_gl(); +static int skip = 0; shm_t *shm; int main() { @@ -227,14 +223,28 @@ int parent() { return 0; } +static void worker_sdl_sighandler(int sig) { + TRACE("call"); + if ( sig == SIGALRM ) { + skip = 1; + sem_post(&shm->worker_sdl_can_render); + } +} + int worker_sdl() { int lastscene=-1, res; + struct sigaction sa; Uint32 sdl_win_flags = 0; //XXX for final version, consider adding SDL_WINDOW_HIDDEN SDL_RendererInfo renderer_info; SDL_Event sdl_ev; TRACE("call"); + sa.sa_handler = worker_sdl_sighandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) return 2; + // Initialize SDL (http://wiki.libsdl.org/SDL_CreateWindowAndRenderer) // Useful snippet : https://gist.github.com/koute/7391344 res = SDL_Init(SDL_INIT_VIDEO); @@ -251,11 +261,13 @@ int worker_sdl() { shm->ge.sdl_target = SDL_CreateTexture(shm->ge.sdl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FBUF_W, FBUF_H); if (shm->ge.sdl_target == NULL) return 9; + while (!shm->done) { - //FIXME change for TRYWAIT for event handling (+delay) + alarm(1); SEM_WAIT(&shm->worker_sdl_can_render,20); + alarm(0); - if (!shm->paused) { + if (!shm->paused && !skip) { // init / free if scene transition if (lastscene != shm->scene) { switch(lastscene) { @@ -275,15 +287,15 @@ int worker_sdl() { // If scene init fail, skip to the next one if (res) SCENE_NEXT; else lastscene = shm->scene; } + // Compute current scene frame (sdl part) + switch(shm->scene) { + case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break; + case 1: res = scene01_next_sdl(&shm->ge, &shm->s01e); break; + case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break; + } + if (res) SCENE_NEXT; } - - // Compute current scene frame (sdl part) - switch(shm->scene) { - case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_next_sdl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break; - } - if (res) SCENE_NEXT; + if (skip) skip = 0; // Event handling for the SDL window (debug purposes) while(SDL_PollEvent(&sdl_ev)) { @@ -313,16 +325,29 @@ int worker_sdl() { return 0; } +static void worker_gl_sighandler(int sig) { + TRACE("call"); + if ( sig == SIGALRM ) { + skip = 1; + sem_post(&shm->worker_gl_can_render); + } +} + int worker_gl() { int lastscene=-1, res; + struct sigaction sa; Uint32 sdl_win_flags = SDL_WINDOW_OPENGL; //XXX for final version, consider adding SDL_WINDOW_HIDDEN SDL_RendererInfo renderer_info; SDL_Event gl_ev; TRACE("call"); - // Initialize SDL (http://wiki.libsdl.org/SDL_CreateWindowAndRenderer) - // Useful snippet : https://gist.github.com/koute/7391344 + sa.sa_handler = worker_gl_sighandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) return 2; + + // Initialize SDL for GL. Useful snippet : https://gist.github.com/koute/7391344 res = SDL_Init(SDL_INIT_VIDEO); if (res == -1) return 3; atexit(SDL_Quit); @@ -353,10 +378,11 @@ int worker_gl() { if (shm->ge.gl_ctx == NULL) return 11; while (!shm->done) { - //FIXME change for TRYWAIT for event handling (+delay) + alarm(1); SEM_WAIT(&shm->worker_gl_can_render,10); + alarm(0); - if (!shm->paused) { + if (!shm->paused && !skip) { // init / free if scene transition if (lastscene != shm->scene) { switch(lastscene) { @@ -376,15 +402,16 @@ int worker_gl() { // If scene init fail, skip to the next one if (res) SCENE_NEXT; else lastscene = shm->scene; } - } - // Compute current scene frame (gl part) - switch(shm->scene) { - case 0: res = scene00_next_gl(&shm->ge, &shm->s00e); break; - case 1: res = scene01_next_gl(&shm->ge, &shm->s01e); break; - case 2: res = scene02_next_gl(&shm->ge, &shm->s02e); break; + // Compute current scene frame (gl part) + switch(shm->scene) { + case 0: res = scene00_next_gl(&shm->ge, &shm->s00e); break; + case 1: res = scene01_next_gl(&shm->ge, &shm->s01e); break; + case 2: res = scene02_next_gl(&shm->ge, &shm->s02e); break; + } + if (res) SCENE_NEXT; } - if (res) SCENE_NEXT; + if (skip) skip = 0; // Event handling for the GL window (debug purposes) while(SDL_PollEvent(&gl_ev)) { -- cgit v1.2.3