From 45b6893e7045f0f2ce02e2b97a877fd54c2078b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dietrich?= Date: Sun, 17 Jan 2016 02:01:41 +0100 Subject: Point Cache: use job system for bake operators. Reviewers: brecht Differential Revision: https://developer.blender.org/D1731 --- source/blender/blenkernel/intern/pointcache.c | 168 +++++++++----------------- 1 file changed, 54 insertions(+), 114 deletions(-) (limited to 'source/blender/blenkernel/intern/pointcache.c') diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 4eb3af6bbcf..7009b4b0ce2 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -3111,33 +3111,18 @@ void BKE_ptcache_quick_cache_all(Main *bmain, Scene *scene) PTCacheBaker baker; baker.bake=0; - baker.break_data=NULL; - baker.break_test=NULL; baker.pid=NULL; - baker.progressbar=NULL; - baker.progressend=NULL; - baker.progresscontext=NULL; baker.render=0; baker.anim_init = 0; baker.main=bmain; baker.scene=scene; baker.quick_step=scene->physics_settings.quick_cache_step; + baker.update_progress = NULL; + baker.bake_job = NULL; BKE_ptcache_bake(&baker); } -/* Simulation thread, no need for interlocks as data written in both threads - * are only unitary integers (I/O assumed to be atomic for them) */ -typedef struct { - int break_operation; - int thread_ended; - int endframe; - int step; - int *cfra_ptr; - Main *main; - Scene *scene; -} ptcache_bake_data; - static void ptcache_dt_to_str(char *str, double dtime) { if (dtime > 60.0) { @@ -3150,52 +3135,6 @@ static void ptcache_dt_to_str(char *str, double dtime) sprintf(str, "%is", ((int)dtime) % 60); } -static void *ptcache_bake_thread(void *ptr) -{ - bool use_timer = false; - int sfra, efra; - double stime, ptime, ctime, fetd; - char run[32], cur[32], etd[32]; - - ptcache_bake_data *data = (ptcache_bake_data*)ptr; - - stime = ptime = PIL_check_seconds_timer(); - sfra = *data->cfra_ptr; - efra = data->endframe; - - for (; (*data->cfra_ptr <= data->endframe) && !data->break_operation; *data->cfra_ptr+=data->step) { - BKE_scene_update_for_newframe(G.main->eval_ctx, data->main, data->scene, data->scene->lay); - if (G.background) { - printf("bake: frame %d :: %d\n", (int)*data->cfra_ptr, data->endframe); - } - else { - ctime = PIL_check_seconds_timer(); - - fetd = (ctime-ptime)*(efra-*data->cfra_ptr)/data->step; - - if (use_timer || fetd > 60.0) { - use_timer = true; - - ptcache_dt_to_str(cur, ctime-ptime); - ptcache_dt_to_str(run, ctime-stime); - ptcache_dt_to_str(etd, fetd); - - printf("Baked for %s, current frame: %i/%i (%.3fs), ETC: %s\r", run, *data->cfra_ptr-sfra+1, efra-sfra+1, ctime-ptime, etd); - } - ptime = ctime; - } - } - - if (use_timer) { - /* start with newline because of \r above */ - ptcache_dt_to_str(run, PIL_check_seconds_timer()-stime); - printf("\nBake %s %s (%i frames simulated).\n", (data->break_operation ? "canceled after" : "finished in"), run, *data->cfra_ptr-sfra); - } - - data->thread_ended = true; - return NULL; -} - /* if bake is not given run simulations to current frame */ void BKE_ptcache_bake(PTCacheBaker *baker) { @@ -3208,19 +3147,10 @@ void BKE_ptcache_bake(PTCacheBaker *baker) PointCache *cache = NULL; float frameleno = scene->r.framelen; int cfrao = CFRA; - int startframe = MAXFRAME; + int startframe = MAXFRAME, endframe = MAXFRAME; int bake = baker->bake; int render = baker->render; - ListBase threads; - ptcache_bake_data thread_data; - int progress, old_progress; - thread_data.endframe = baker->anim_init ? scene->r.sfra : CFRA; - thread_data.step = baker->quick_step; - thread_data.cfra_ptr = &CFRA; - thread_data.scene = baker->scene; - thread_data.main = baker->main; - G.is_break = false; /* set caches to baking mode and figure out start frame */ @@ -3261,11 +3191,11 @@ void BKE_ptcache_bake(PTCacheBaker *baker) startframe = MAX2(cache->last_exact, cache->startframe); if (bake) { - thread_data.endframe = cache->endframe; + endframe = cache->endframe; cache->flag |= PTCACHE_BAKING; } else { - thread_data.endframe = MIN2(thread_data.endframe, cache->endframe); + endframe = MIN2(endframe, cache->endframe); } cache->flag &= ~PTCACHE_BAKED; @@ -3300,7 +3230,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) cache->flag |= PTCACHE_BAKING; if (bake) - thread_data.endframe = MAX2(thread_data.endframe, cache->endframe); + endframe = MAX2(endframe, cache->endframe); } cache->flag &= ~PTCACHE_BAKED; @@ -3313,46 +3243,63 @@ void BKE_ptcache_bake(PTCacheBaker *baker) CFRA = startframe; scene->r.framelen = 1.0; - thread_data.break_operation = false; - thread_data.thread_ended = false; - old_progress = -1; - WM_cursor_wait(1); - - if (G.background) { - ptcache_bake_thread((void*)&thread_data); - } - else { - BLI_init_threads(&threads, ptcache_bake_thread, 1); - BLI_insert_thread(&threads, (void*)&thread_data); + /* bake */ - while (thread_data.thread_ended == false) { + bool use_timer = false; + double stime, ptime, ctime, fetd; + char run[32], cur[32], etd[32]; + int cancel = 0; - if (bake) - progress = (int)(100.0f * (float)(CFRA - startframe)/(float)(thread_data.endframe-startframe)); - else - progress = CFRA; + stime = ptime = PIL_check_seconds_timer(); - /* NOTE: baking should not redraw whole ui as this slows things down */ - if ((baker->progressbar) && (progress != old_progress)) { - baker->progressbar(baker->progresscontext, progress); - old_progress = progress; - } + for (int fr = CFRA; fr <= endframe; fr += baker->quick_step, CFRA = fr) { + BKE_scene_update_for_newframe(G.main->eval_ctx, bmain, scene, scene->lay); + + if (baker->update_progress) { + float progress = ((float)(CFRA - startframe)/(float)(endframe - startframe)); + baker->update_progress(baker->bake_job, progress, &cancel); + } + + if (G.background) { + printf("bake: frame %d :: %d\n", CFRA, endframe); + } + else { + ctime = PIL_check_seconds_timer(); + + fetd = (ctime - ptime) * (endframe - CFRA) / baker->quick_step; + + if (use_timer || fetd > 60.0) { + use_timer = true; - /* Delay to lessen CPU load from UI thread */ - PIL_sleep_ms(200); + ptcache_dt_to_str(cur, ctime - ptime); + ptcache_dt_to_str(run, ctime - stime); + ptcache_dt_to_str(etd, fetd); - /* NOTE: breaking baking should leave calculated frames in cache, not clear it */ - if (blender_test_break() && !thread_data.break_operation) { - thread_data.break_operation = true; - if (baker->progressend) - baker->progressend(baker->progresscontext); - WM_cursor_wait(1); + printf("Baked for %s, current frame: %i/%i (%.3fs), ETC: %s\r", + run, CFRA - startframe + 1, endframe - startframe + 1, ctime - ptime, etd); } + + ptime = ctime; + } + + /* Delay to lessen CPU load from UI thread */ + PIL_sleep_ms(200); + + /* NOTE: breaking baking should leave calculated frames in cache, not clear it */ + if ((cancel || G.is_break)) { + break; } - BLI_end_threads(&threads); + CFRA += 1; } + + if (use_timer) { + /* start with newline because of \r above */ + ptcache_dt_to_str(run, PIL_check_seconds_timer()-stime); + printf("\nBake %s %s (%i frames simulated).\n", (cancel ? "canceled after" : "finished in"), run, CFRA - startframe); + } + /* clear baking flag */ if (pid) { cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED); @@ -3375,7 +3322,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker) cache = pid->cache; - if (thread_data.step > 1) + if (baker->quick_step > 1) cache->flag &= ~(PTCACHE_BAKING|PTCACHE_OUTDATED); else cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED); @@ -3399,13 +3346,6 @@ void BKE_ptcache_bake(PTCacheBaker *baker) BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay); } - if (thread_data.break_operation) - WM_cursor_wait(0); - else if (baker->progressend) - baker->progressend(baker->progresscontext); - - WM_cursor_wait(0); - /* TODO: call redraw all windows somehow */ } /* Helpers */ -- cgit v1.2.3