From 25effd17ef1a1a05d671382b9a51be29734226a0 Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sat, 7 Sep 2019 10:49:21 +0200 Subject: Multi-process done. GL has to be done cleanly now. --- Makefile | 2 +- src/main.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- src/main.h | 2 ++ src/scene00.c | 18 ++++++------ src/scene01.c | 34 ++++++++-------------- 5 files changed, 102 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 5b0297c..b655db0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-Wall -Werror -g +CFLAGS=-Wall -Werror -g -DDEBUG PKGLIBS=caca sdl2 glu all: demoscene-eo diff --git a/src/main.c b/src/main.c index 9b151b1..d519034 100644 --- a/src/main.c +++ b/src/main.c @@ -32,8 +32,18 @@ #include // uint32_t #include // printf() - +#ifdef DEBUG #define TRACE(hint) printf("%s(): %s\n", __func__, hint) +#else +#define TRACE(hint) +#endif + +#ifdef DEBUG_SEM +#define TRACE_SEM(sem,op,hint) printf("%s(): %s(%s) %s\n", __func__, op, #sem, hint) +#else +#define TRACE_SEM(sem,op,hint) +#endif + #define SCENE_COUNT 3 #define SCENE_NEXT do { shm->scene = (shm->scene+1)%SCENE_COUNT; } while(0) @@ -42,13 +52,13 @@ #define SEM_POST(sem,errcode) \ do { \ - /* printf("%s(): sem_post(%s,%i)\n", __func__, #sem, errcode); */ \ + TRACE_SEM(sem,"sem_post",""); \ if ( sem_post(sem) == -1 ) { return errcode; } \ } while(0) #define SEM_WAIT(sem,errcode) \ do { \ - /* printf("%s(): sem_wait(%s,%i) call\n", __func__, #sem, errcode); */\ + TRACE_SEM(sem,"sem_wait","call"); \ while ( sem_wait(sem) == -1 ) { \ switch(errno) { \ case EINTR: \ @@ -58,7 +68,7 @@ return errcode; \ } \ } \ - /* printf("%s(): sem_wait(%s,%i) done\n", __func__, #sem, errcode); */\ + TRACE_SEM(sem,"sem_wait","done"); \ } while(0) typedef struct { @@ -140,7 +150,6 @@ int parent() { // init / free if scene transition if ( lastscene != shm->scene ) { switch(lastscene) { - //FIXME call free_gl and free_sdl in respective processes too case 0: scene00_free_caca(&shm->ge, &shm->s00e); break; case 1: scene01_free_caca(&shm->ge, &shm->s01e); break; case 2: scene02_free_caca(&shm->ge, &shm->s02e); break; @@ -150,7 +159,6 @@ int parent() { shm->ge.sdl_ticks = SDL_GetTicks(); shm->ge.sc_framecount = 0; switch(shm->scene) { - //FIXME call init_gl and init_sdl in respective processes too case 0: res = scene00_init_caca(&shm->ge, &shm->s00e); break; case 1: res = scene01_init_caca(&shm->ge, &shm->s01e); break; case 2: res = scene02_init_caca(&shm->ge, &shm->s02e); break; @@ -220,8 +228,8 @@ int parent() { } int worker_sdl() { - int res; - Uint32 sdl_win_flags = 0; //XXX for final version, consider sdl_win_flags = SDL_WINDOW_HIDDEN; + int lastscene=-1, res; + Uint32 sdl_win_flags = 0; //XXX for final version, consider adding SDL_WINDOW_HIDDEN SDL_RendererInfo renderer_info; SDL_Event sdl_ev; @@ -247,6 +255,30 @@ int worker_sdl() { //FIXME change for TRYWAIT for event handling (+delay) SEM_WAIT(&shm->worker_sdl_can_render,20); + if (!shm->paused) { + // init / free if scene transition + if ( lastscene != shm->scene ) { + switch(lastscene) { + case 0: scene00_free_sdl(&shm->ge, &shm->s00e); break; + case 1: scene01_free_sdl(&shm->ge, &shm->s01e); break; + case 2: scene02_free_sdl(&shm->ge, &shm->s02e); break; + } + } + while ( lastscene != shm->scene ) { + shm->ge.sdl_ticks = SDL_GetTicks(); + shm->ge.sc_framecount = 0; + switch(shm->scene) { + case 0: res = scene00_init_sdl(&shm->ge, &shm->s00e); break; + case 1: res = scene01_init_sdl(&shm->ge, &shm->s01e); break; + case 2: res = scene02_init_sdl(&shm->ge, &shm->s02e); break; + } + // If scene init fail, skip to the next one + if (res) SCENE_NEXT; else lastscene = shm->scene; + } + } + + TRACE("before next_sdl"); + printf("DEBUG shm->scene : %i\n", shm->scene); // Compute current scene frame (sdl part) switch(shm->scene) { case 0: res = scene00_next_sdl(&shm->ge, &shm->s00e); break; @@ -254,6 +286,7 @@ int worker_sdl() { case 2: res = scene02_next_sdl(&shm->ge, &shm->s02e); break; } if (res) SCENE_NEXT; + TRACE("after next_sdl"); // Event handling for the SDL window (debug purposes) while(SDL_PollEvent(&sdl_ev)) { @@ -272,8 +305,10 @@ int worker_sdl() { break; } } + TRACE("after SDL_PollEvent loop"); SEM_POST(&shm->parent_can_read_result, 21); + TRACE("after sem_post"); } SDL_DestroyRenderer(shm->ge.sdl_rndr); @@ -284,8 +319,9 @@ int worker_sdl() { } int worker_gl() { - int res; - //Uint32 sdl_win_flags = SDL_WINDOW_OPENGL; + int lastscene=-1, res; + 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"); @@ -307,7 +343,17 @@ int worker_gl() { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); // Initialize OpenGL - shm->ge.gl_win = SDL_CreateWindow("GL Debug", SDL_WINDOWPOS_CENTERED, 0, FBUF_W, FBUF_H, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN ); + //shm->ge.gl_win = SDL_CreateWindow("GL Debug", SDL_WINDOWPOS_CENTERED, 0, FBUF_W, FBUF_H, sdl_win_flags); + + res = SDL_CreateWindowAndRenderer(FBUF_W, FBUF_H, sdl_win_flags, &shm->ge.gl_win, &shm->ge.gl_rndr); + if ( res == -1) return 4; + SDL_SetWindowTitle(shm->ge.gl_win, "GL debug"); + res = SDL_GetRendererInfo(shm->ge.gl_rndr, &renderer_info); + if ( res < 0 ) return 5; + if ( !(renderer_info.flags & SDL_RENDERER_ACCELERATED)) return 6; + if ( !(renderer_info.flags & SDL_RENDERER_TARGETTEXTURE)) return 7; + shm->ge.gl_target = SDL_CreateTexture(shm->ge.gl_rndr, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, FBUF_W, FBUF_H); + if ( shm->ge.gl_target == NULL ) return 9; shm->ge.gl_ctx = SDL_GL_CreateContext(shm->ge.gl_win); if ( shm->ge.gl_ctx == NULL ) return 11; @@ -315,6 +361,28 @@ int worker_gl() { //FIXME change for TRYWAIT for event handling (+delay) SEM_WAIT(&shm->worker_gl_can_render,10); + if (!shm->paused) { + // init / free if scene transition + if ( lastscene != shm->scene ) { + switch(lastscene) { + case 0: scene00_free_gl(&shm->ge, &shm->s00e); break; + case 1: scene01_free_gl(&shm->ge, &shm->s01e); break; + case 2: scene02_free_gl(&shm->ge, &shm->s02e); break; + } + } + while ( lastscene != shm->scene ) { + shm->ge.sdl_ticks = SDL_GetTicks(); + shm->ge.sc_framecount = 0; + switch(shm->scene) { + case 0: res = scene00_init_gl(&shm->ge, &shm->s00e); break; + case 1: res = scene01_init_gl(&shm->ge, &shm->s01e); break; + case 2: res = scene02_init_gl(&shm->ge, &shm->s02e); break; + } + // 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; diff --git a/src/main.h b/src/main.h index 4510b19..363a614 100644 --- a/src/main.h +++ b/src/main.h @@ -24,6 +24,8 @@ typedef struct { // OpenGL worker SDL_Window* gl_win; SDL_GLContext gl_ctx; + SDL_Renderer *gl_rndr; + SDL_Texture *gl_target; // framebuffer to inject OpenGL or SDL result in caca canvas uint32_t raw_target[FBUF_W*FBUF_H]; // Timing diff --git a/src/scene00.c b/src/scene00.c index b1e4e57..f8df185 100644 --- a/src/scene00.c +++ b/src/scene00.c @@ -51,11 +51,7 @@ int scene00_next_gl(graphical_env_t *ge, scene00_env_t *se) { int scene00_next_sdl(graphical_env_t *ge, scene00_env_t *se) { // Shorthands - caca_canvas_t *cv = ge->cv; - int w = ge->w, h = ge->h; SDL_Renderer *r = ge->sdl_rndr; - // Local vars - int res; // https://gist.github.com/Twinklebear/8265888 // https://forums.libsdl.org/viewtopic.php?p=51634 @@ -65,17 +61,16 @@ int scene00_next_sdl(graphical_env_t *ge, scene00_env_t *se) { SDL_RenderCopy(r, se->eo1, NULL, NULL); // [...] - // Copy the SDL screen to SDL debug window (and display it, not mandatory) +#ifdef DEBUG + // Copy the target texture to SDL debug window (and display it, not mandatory) SDL_SetRenderTarget(r, NULL); SDL_RenderCopy(r, ge->sdl_target, NULL, NULL); SDL_RenderPresent(r); + SDL_SetRenderTarget(r, ge->sdl_target); +#endif // Download the rendered texture from videocard to main memory - SDL_SetRenderTarget(r, ge->sdl_target); - res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4); - - // "convert" the raw pixel stream to ASCII art on caca canevas - if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); + SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, FBUF_W*4); return 0; } @@ -86,6 +81,9 @@ int scene00_next_caca(graphical_env_t *ge, scene00_env_t *se) { int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + // "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); + // Add things on top of caca canvas caca_set_color_ansi(cv, CACA_BLACK, CACA_WHITE); caca_put_str(cv, (w-17)/2, h/2, "This is a message"); diff --git a/src/scene01.c b/src/scene01.c index 527e81a..7a6aed1 100644 --- a/src/scene01.c +++ b/src/scene01.c @@ -169,35 +169,20 @@ void scene01_free_caca(graphical_env_t *ge, scene01_env_t *se) { } int scene01_next_gl(graphical_env_t *ge, scene01_env_t *se) { - // Shorthands - caca_canvas_t *cv = ge->cv; - int w = ge->w, h = ge->h; - SDL_Renderer *r = ge->sdl_rndr; - // Local vars - int res; + SDL_Renderer *r = ge->gl_rndr; // https://gist.github.com/Twinklebear/8265888 // https://forums.libsdl.org/viewtopic.php?p=51634 - // Render all the stuff on target texture - SDL_SetRenderTarget(r, ge->sdl_target); - - glClear( GL_COLOR_BUFFER_BIT ); - glBindVertexArray( se->vao ); - glDrawArrays( GL_TRIANGLES, 0, 6 ); + glClear(GL_COLOR_BUFFER_BIT); + glBindVertexArray(se->vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + // [...] - // Copy the SDL screen to SDL debug window (and display it, not mandatory) - SDL_SetRenderTarget(r, NULL); - SDL_RenderCopy(r, ge->sdl_target, NULL, NULL); - SDL_RenderPresent(r); + SDL_GL_SwapWindow(ge->gl_win); // Download the rendered texture from videocard to main memory - SDL_SetRenderTarget(r, ge->sdl_target); - res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4); - - // "convert" the raw pixel stream to ASCII art on caca canevas - caca_set_dither_gamma(ge->d, 1.0); - if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); + SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, FBUF_W*4); return 0; } @@ -212,6 +197,11 @@ int scene01_next_caca(graphical_env_t *ge, scene01_env_t *se) { int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + // "convert" the raw pixel stream from SDL to ASCII art on caca canevas + caca_set_dither_gamma(ge->d, 1.0); + caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); + + // Add things on top of caca canvas caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK); caca_put_str(cv, (w-17)/2, h/2, "This is a message"); -- cgit v1.2.3