From 75645910c8cdd9e35325cf696741e481383e6e1c Mon Sep 17 00:00:00 2001 From: Harry Jeffery Date: Sat, 28 Nov 2015 00:45:52 +0000 Subject: Implement background frame loading --- src/loader.c | 112 ++++++++++++++++++++++++++++++----------------------------- src/main.c | 2 +- 2 files changed, 58 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/loader.c b/src/loader.c index 404bbb5..cd52a0f 100644 --- a/src/loader.c +++ b/src/loader.c @@ -21,21 +21,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include +static void block_usr1_signal() +{ + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, SIGUSR1); + sigprocmask(SIG_SETMASK, &sigmask, NULL); +} + +static int is_thread_cancelled() +{ + sigset_t sigmask; + sigpending(&sigmask); + return sigismember(&sigmask, SIGUSR1); +} + void imv_init_loader(struct imv_loader *ldr) { + memset(ldr, 0, sizeof(struct imv_loader)); pthread_mutex_init(&ldr->lock, NULL); - ldr->bg_thread = 0; - ldr->path = NULL; - ldr->out_bmp = NULL; - ldr->out_err = NULL; - ldr->mbmp = NULL; - ldr->bmp = NULL; - ldr->width = 0; - ldr->height = 0; - ldr->cur_frame = 0; - ldr->next_frame = 0; - ldr->num_frames = 0; - ldr->frame_time = 0; + /* ignore this signal in case we accidentally receive it */ + block_usr1_signal(); } void imv_destroy_loader(struct imv_loader *ldr) @@ -68,6 +74,9 @@ void imv_loader_load_path(struct imv_loader *ldr, const char *path) /* kick off a new thread to load the image */ /* no need to lock as we're the only thread at this point */ + if(ldr->path) { + free(ldr->path); + } ldr->path = strdup(path); pthread_create(&ldr->bg_thread, NULL, &imv_loader_bg_new_img, ldr); } @@ -102,7 +111,13 @@ char *imv_loader_get_error(struct imv_loader *ldr) void imv_loader_load_next_frame(struct imv_loader *ldr) { - /* TODO kick off next frame thread */ + /* wait for existing thread to finish if already running */ + if(ldr->bg_thread) { + pthread_join(ldr->bg_thread, NULL); + } + + /* kick off a new thread */ + pthread_create(&ldr->bg_thread, NULL, &imv_loader_bg_next_frame, ldr); } void imv_loader_time_passed(struct imv_loader *ldr, double dt) @@ -118,7 +133,7 @@ void imv_loader_time_passed(struct imv_loader *ldr, double dt) pthread_mutex_unlock(&ldr->lock); if(get_frame) { - imv_loader_load_next_frame(); + imv_loader_load_next_frame(ldr); } } @@ -132,25 +147,10 @@ void imv_loader_error_occurred(struct imv_loader *ldr) pthread_mutex_unlock(&ldr->lock); } -static void setup_thread_cancellation() -{ - sigset_t sigmask; - sigemptyset(&sigmask); - sigaddset(&sigmask, SIGUSR1); - /* block USR1 delivery so we can poll for it */ - sigprocmask(SIG_SETMASK, &sigmask, NULL); -} - -static int is_thread_cancelled() -{ - sigset_t sigmask; - sigpending(&sigmask); - return sigismember(&sigmask, SIGUSR1); -} - static void *imv_loader_bg_new_img(void *data) { - setup_thread_cancellation(); + /* so we can poll for it */ + block_usr1_signal(); struct imv_loader *ldr = data; @@ -254,19 +254,15 @@ static void *imv_loader_bg_new_img(void *data) return 0; } -/* TODO - rewrite */ static void *imv_loader_bg_next_frame(void *data) { struct imv_loader *ldr = data; - return 0; -} -#if 0 pthread_mutex_lock(&ldr->lock); int num_frames = ldr->num_frames; - pthread_mutex_unlock(&ldr->lock); if(num_frames < 2) { - return; + pthread_mutex_unlock(&ldr->lock); + return 0; } FITAG *tag = NULL; @@ -322,40 +318,46 @@ static void *imv_loader_bg_next_frame(void *data) switch(disposal_method) { case 0: /* nothing specified, just use the raw frame */ - if(ldr->cur_bmp) { - FreeImage_Unload(ldr->cur_bmp); + if(ldr->bmp) { + FreeImage_Unload(ldr->bmp); } - ldr->cur_bmp = frame32; + ldr->bmp = frame32; break; case 1: /* composite over previous frame */ - if(ldr->cur_bmp && ldr->cur_frame > 0) { - FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->cur_bmp); - FreeImage_Unload(ldr->cur_bmp); + if(ldr->bmp && ldr->cur_frame > 0) { + FIBITMAP *bg_frame = FreeImage_ConvertTo24Bits(ldr->bmp); + FreeImage_Unload(ldr->bmp); FIBITMAP *comp = FreeImage_Composite(frame32, 1, NULL, bg_frame); FreeImage_Unload(bg_frame); FreeImage_Unload(frame32); - ldr->cur_bmp = comp; + ldr->bmp = comp; } else { /* No previous frame, just render directly */ - if(ldr->cur_bmp) { - FreeImage_Unload(ldr->cur_bmp); + if(ldr->bmp) { + FreeImage_Unload(ldr->bmp); } - ldr->cur_bmp = frame32; + ldr->bmp = frame32; } break; case 2: /* TODO - set to background, composite over that */ - if(ldr->cur_bmp) { - FreeImage_Unload(ldr->cur_bmp); + if(ldr->bmp) { + FreeImage_Unload(ldr->bmp); } - ldr->cur_bmp = frame32; + ldr->bmp = frame32; break; case 3: /* TODO - restore to previous content */ - if(ldr->cur_bmp) { - FreeImage_Unload(ldr->cur_bmp); + if(ldr->bmp) { + FreeImage_Unload(ldr->bmp); } - ldr->cur_bmp = frame32; + ldr->bmp = frame32; break; } - ldr->changed = 1; + + if(ldr->out_bmp) { + FreeImage_Unload(ldr->out_bmp); + } + ldr->out_bmp = FreeImage_Clone(ldr->bmp); + + pthread_mutex_unlock(&ldr->lock); + return 0; } -#endif diff --git a/src/main.c b/src/main.c index f8f537b..c41eaf8 100644 --- a/src/main.c +++ b/src/main.c @@ -394,7 +394,7 @@ int main(int argc, char** argv) double cur_time = SDL_GetTicks() / 1000.0; double dt = cur_time - last_time; last_time = SDL_GetTicks() / 1000.0; - imv_loader_time_passed(tex, dt); + imv_loader_time_passed(&ldr, dt); } if(view.redraw) { -- cgit v1.2.3