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 +++++++++++++++++++++++++++++++++++++++-------------------- src/main.h | 8 ++++++ src/scene00.c | 11 ++++++++ src/scene01.c | 9 +++++++ src/scene02.c | 10 ++++++++ 5 files changed, 92 insertions(+), 27 deletions(-) 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)) { diff --git a/src/main.h b/src/main.h index 363a614..313dabf 100644 --- a/src/main.h +++ b/src/main.h @@ -11,6 +11,14 @@ #define FBUF_W 256 #define FBUF_H 256 +#ifdef DEBUG +#define TRACE(hint) do { printf("%s(): %s\n", __func__, hint); fflush(stdout); } while(0) +#define TRACE_ONCE(hint) if (firsttime) { printf("%s(): %s\n", __func__, hint); fflush(stdout); firsttime=0; } +#else +#define TRACE(hint) +#define TRACE_ONCE(hint) +#endif + typedef struct { // libcaca caca_display_t *dp; diff --git a/src/scene00.c b/src/scene00.c index 0d6a02e..f418146 100644 --- a/src/scene00.c +++ b/src/scene00.c @@ -20,10 +20,12 @@ #include "scene00.h" int scene00_init_gl(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); return 0; } int scene00_init_sdl(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); SDL_Surface *bmpSurf = SDL_LoadBMP("./res/eo1.bmp"); se->eo1 = SDL_CreateTextureFromSurface(ge->sdl_rndr, bmpSurf); SDL_FreeSurface(bmpSurf); @@ -32,20 +34,25 @@ int scene00_init_sdl(graphical_env_t *ge, scene00_env_t *se) { } int scene00_init_caca(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); return 0; } void scene00_free_gl(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); } void scene00_free_sdl(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); SDL_DestroyTexture(se->eo1); se->eo1=NULL; } void scene00_free_caca(graphical_env_t *ge, scene00_env_t *se) { + TRACE("call"); } int scene00_next_gl(graphical_env_t *ge, scene00_env_t *se) { + static int firsttime=1; TRACE_ONCE("call"); return 0; } @@ -53,6 +60,8 @@ int scene00_next_sdl(graphical_env_t *ge, scene00_env_t *se) { // Shorthands SDL_Renderer *r = ge->sdl_rndr; + static int firsttime=1; TRACE_ONCE("call"); + // https://gist.github.com/Twinklebear/8265888 // https://forums.libsdl.org/viewtopic.php?p=51634 @@ -81,6 +90,8 @@ int scene00_next_caca(graphical_env_t *ge, scene00_env_t *se) { int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + static int firsttime=1; TRACE_ONCE("call"); + // "convert" the raw pixel stream from SDL to ASCII art on caca canevas caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); diff --git a/src/scene01.c b/src/scene01.c index f8027c4..a2f1345 100644 --- a/src/scene01.c +++ b/src/scene01.c @@ -77,6 +77,7 @@ typedef enum t_attrib_id int scene01_init_gl(graphical_env_t *ge, scene01_env_t *se) { GLuint vs, fs, program; + TRACE("call"); vs = glCreateShader(GL_VERTEX_SHADER); fs = glCreateShader(GL_FRAGMENT_SHADER); @@ -142,25 +143,31 @@ int scene01_init_gl(graphical_env_t *ge, scene01_env_t *se) { } int scene01_init_sdl(graphical_env_t *ge, scene01_env_t *se) { + TRACE("call"); return 0; } int scene01_init_caca(graphical_env_t *ge, scene01_env_t *se) { + TRACE("call"); return 0; } void scene01_free_gl(graphical_env_t *ge, scene01_env_t *se) { + TRACE("call"); //TODO } void scene01_free_sdl(graphical_env_t *ge, scene01_env_t *se) { + TRACE("call"); } void scene01_free_caca(graphical_env_t *ge, scene01_env_t *se) { + TRACE("call"); } int scene01_next_gl(graphical_env_t *ge, scene01_env_t *se) { SDL_Renderer *r = ge->gl_rndr; + static int firsttime=1; TRACE_ONCE("call"); // https://gist.github.com/Twinklebear/8265888 // https://forums.libsdl.org/viewtopic.php?p=51634 @@ -179,6 +186,7 @@ int scene01_next_gl(graphical_env_t *ge, scene01_env_t *se) { } int scene01_next_sdl(graphical_env_t *ge, scene01_env_t *se) { + static int firsttime=1; TRACE_ONCE("call"); return 0; } @@ -187,6 +195,7 @@ int scene01_next_caca(graphical_env_t *ge, scene01_env_t *se) { caca_canvas_t *cv = ge->cv; int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + static int firsttime=1; TRACE_ONCE("call"); // "convert" the raw pixel stream from SDL to ASCII art on caca canevas caca_set_dither_gamma(ge->d, 1.0); diff --git a/src/scene02.c b/src/scene02.c index 03f02a4..f268f1f 100644 --- a/src/scene02.c +++ b/src/scene02.c @@ -20,32 +20,40 @@ #include "scene02.h" int scene02_init_gl(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); return 0; } int scene02_init_sdl(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); return 0; } int scene02_init_caca(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); return 0; } void scene02_free_gl(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); } void scene02_free_sdl(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); } void scene02_free_caca(graphical_env_t *ge, scene02_env_t *se) { + TRACE("call"); } int scene02_next_gl(graphical_env_t *ge, scene02_env_t *se) { + static int firsttime=1; TRACE_ONCE("call"); return 0; } int scene02_next_sdl(graphical_env_t *ge, scene02_env_t *se) { + static int firsttime=1; TRACE_ONCE("call"); return 0; } @@ -55,6 +63,8 @@ int scene02_next_caca(graphical_env_t *ge, scene02_env_t *se) { //int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + static int firsttime=1; TRACE_ONCE("call"); + caca_clear_canvas(cv); if (frame >= 100) { -- cgit v1.2.3