summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-08 01:52:45 +0200
committerLudovic Pouzenc <ludovic@pouzenc.fr>2019-09-08 01:52:45 +0200
commita5338c572975a82b9efbf95755103176ebbb67a8 (patch)
tree21726695e4fcdc5ecfdc05e9c380700563342567
parent90c206b75fa027150759160e89ac3e65d6003ea7 (diff)
downloaddemoscene-eo-a5338c572975a82b9efbf95755103176ebbb67a8.tar.gz
demoscene-eo-a5338c572975a82b9efbf95755103176ebbb67a8.tar.bz2
demoscene-eo-a5338c572975a82b9efbf95755103176ebbb67a8.zip
alarm(1) before SEM_WAIT(...) in worker_(sdl|gl) to avoid edge cases
-rw-r--r--src/main.c81
-rw-r--r--src/main.h8
-rw-r--r--src/scene00.c11
-rw-r--r--src/scene01.c9
-rw-r--r--src/scene02.c10
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.h> // errno
#include <stdint.h> // uint32_t
#include <stdio.h> // printf()
-
-#ifdef DEBUG
-#define TRACE(hint) printf("%s(): %s\n", __func__, hint)
-#else
-#define TRACE(hint)
-#endif
+#include <signal.h> // 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) {