Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Dietrich <kevin.dietrich@mailoo.org>2016-01-17 04:01:41 +0300
committerKévin Dietrich <kevin.dietrich@mailoo.org>2016-01-17 04:01:41 +0300
commit45b6893e7045f0f2ce02e2b97a877fd54c2078b9 (patch)
treed22e089c61f44e3a14647ad8e9a5b073db26b112
parent75cfc81ec39ac9953f25eb0ae5f9e70d3c24ee7e (diff)
Point Cache: use job system for bake operators.
Reviewers: brecht Differential Revision: https://developer.blender.org/D1731
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c168
-rw-r--r--source/blender/editors/physics/physics_pointcache.c222
-rw-r--r--source/blender/render/intern/source/pipeline.c5
-rw-r--r--source/blender/windowmanager/WM_api.h1
5 files changed, 203 insertions, 201 deletions
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index a3ffad1f66b..d1b8aa672c5 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -178,11 +178,9 @@ typedef struct PTCacheBaker {
int anim_init;
int quick_step;
struct PTCacheID *pid;
- int (*break_test)(void *data);
- void *break_data;
- void (*progressbar)(void *data, int num);
- void (*progressend)(void *data);
- void *progresscontext;
+
+ void (*update_progress)(void *data, float progress, int *cancel);
+ void *bake_job;
} PTCacheBaker;
/* PTCacheEditKey->flag */
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 */
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 71e5e23b5f1..406b5892234 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -31,12 +31,15 @@
#include <stdlib.h>
+#include "MEM_guardedalloc.h"
+
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "DNA_scene_types.h"
#include "BKE_context.h"
+#include "BKE_screen.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_particle.h"
@@ -52,10 +55,6 @@
#include "physics_intern.h"
-static int cache_break_test(void *UNUSED(cbd))
-{
- return (G.is_break == true);
-}
static int ptcache_bake_all_poll(bContext *C)
{
Scene *scene= CTX_data_scene(C);
@@ -72,15 +71,85 @@ static int ptcache_poll(bContext *C)
return (ptr.data && ptr.id.data);
}
-static void bake_console_progress(void *UNUSED(arg), int nr)
+typedef struct PointCacheJob {
+ void *owner;
+ short *stop, *do_update;
+ float *progress;
+
+ PTCacheBaker *baker;
+ Object *ob;
+ ListBase pidlist;
+} PointCacheJob;
+
+static void ptcache_job_free(void *customdata)
+{
+ PointCacheJob *job = customdata;
+ BLI_freelistN(&job->pidlist);
+ MEM_freeN(job->baker);
+ MEM_freeN(job);
+}
+
+static int ptcache_job_break(void *customdata)
+{
+ PointCacheJob *job = customdata;
+
+ if (G.is_break) {
+ return 1;
+ }
+
+ if (job->stop && *(job->stop)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void ptcache_job_update(void *customdata, float progress, int *cancel)
+{
+ PointCacheJob *job = customdata;
+
+ if (ptcache_job_break(job)) {
+ *cancel = 1;
+ }
+
+ *(job->do_update) = true;
+ *(job->progress) = progress;
+}
+
+static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- printf("\rbake: %3i%%", nr);
- fflush(stdout);
+ PointCacheJob *job = customdata;
+
+ job->stop = stop;
+ job->do_update = do_update;
+ job->progress = progress;
+
+ G.is_break = false;
+
+ /* XXX annoying hack: needed to prevent data corruption when changing
+ * scene frame in separate threads
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
+
+ BKE_ptcache_bake(job->baker);
+
+ *do_update = true;
+ *stop = 0;
}
-static void bake_console_progress_end(void *UNUSED(arg))
+static void ptcache_job_endjob(void *customdata)
{
- printf("\rbake: done!\n");
+ PointCacheJob *job = customdata;
+ Scene *scene = job->baker->scene;
+
+ G.is_rendering = false;
+ BKE_spacedata_draw_locks(false);
+
+ WM_set_locked_interface(G.main->wm.first, false);
+
+ WM_main_add_notifier(NC_SCENE | ND_FRAME, scene);
+ WM_main_add_notifier(NC_OBJECT | ND_POINTCACHE, job->ob);
}
static void ptcache_free_bake(PointCache *cache)
@@ -100,41 +169,41 @@ static void ptcache_free_bake(PointCache *cache)
static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
- Scene *scene= CTX_data_scene(C);
- wmWindow *win = G.background ? NULL : CTX_wm_window(C);
- PTCacheBaker baker;
-
- baker.main = bmain;
- baker.scene = scene;
- baker.pid = NULL;
- baker.bake = RNA_boolean_get(op->ptr, "bake");
- baker.render = 0;
- baker.anim_init = 0;
- baker.quick_step = 1;
- baker.break_test = cache_break_test;
- baker.break_data = NULL;
-
- /* Disabled for now as this doesn't work properly,
- * and pointcache baking will be reimplemented with
- * the job system soon anyways. */
- if (win) {
- baker.progressbar = (void (*)(void *, int))WM_cursor_time;
- baker.progressend = (void (*)(void *))WM_cursor_modal_restore;
- baker.progresscontext = win;
- }
- else {
- baker.progressbar = bake_console_progress;
- baker.progressend = bake_console_progress_end;
- baker.progresscontext = NULL;
- }
+ Scene *scene = CTX_data_scene(C);
- BKE_ptcache_bake(&baker);
+ PTCacheBaker *baker = MEM_mallocN(sizeof(PTCacheBaker), "PTCacheBaker");
- WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
- WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, NULL);
+ baker->main = bmain;
+ baker->scene = scene;
+ baker->pid = NULL;
+ baker->bake = RNA_boolean_get(op->ptr, "bake");
+ baker->render = 0;
+ baker->anim_init = 0;
+ baker->quick_step = 1;
+ baker->update_progress = ptcache_job_update;
+
+ PointCacheJob *job = MEM_mallocN(sizeof(PointCacheJob), "PointCacheJob");
+ job->baker = baker;
+ job->ob = NULL;
+ job->pidlist.first = NULL;
+ job->pidlist.last = NULL;
+
+ baker->bake_job = job;
+
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Point Cache",
+ WM_JOB_PROGRESS, WM_JOB_TYPE_POINTCACHE);
+
+ WM_jobs_customdata_set(wm_job, job, ptcache_job_free);
+ WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_POINTCACHE, NC_OBJECT | ND_POINTCACHE);
+ WM_jobs_callbacks(wm_job, ptcache_job_startjob, NULL, NULL, ptcache_job_endjob);
+
+ WM_set_locked_interface(CTX_wm_manager(C), true);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
return OPERATOR_FINISHED;
}
+
static int ptcache_free_bake_all_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene= CTX_data_scene(C);
@@ -189,59 +258,54 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
}
+
static int ptcache_bake_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
- wmWindow *win = G.background ? NULL : CTX_wm_window(C);
- PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
- Object *ob= ptr.id.data;
- PointCache *cache= ptr.data;
- PTCacheBaker baker;
- PTCacheID *pid;
- ListBase pidlist;
-
- BKE_ptcache_ids_from_object(&pidlist, ob, scene, MAX_DUPLI_RECUR);
-
- for (pid=pidlist.first; pid; pid=pid->next) {
- if (pid->cache == cache)
+ PointerRNA ptr = CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
+ Object *ob = ptr.id.data;
+ PointCache *cache = ptr.data;
+
+ PTCacheBaker *baker = MEM_mallocN(sizeof(PTCacheBaker), "PTCacheBaker");
+ baker->main = bmain;
+ baker->scene = scene;
+ baker->bake = RNA_boolean_get(op->ptr, "bake");
+ baker->render = 0;
+ baker->anim_init = 0;
+ baker->quick_step = 1;
+ baker->update_progress = ptcache_job_update;
+ baker->pid = NULL;
+
+ PointCacheJob *job = MEM_mallocN(sizeof(PointCacheJob), "PointCacheJob");
+ job->baker = baker;
+ job->ob = ob;
+
+ BKE_ptcache_ids_from_object(&job->pidlist, ob, scene, MAX_DUPLI_RECUR);
+
+ for (PTCacheID *pid = job->pidlist.first; pid; pid = pid->next) {
+ if (pid->cache == cache) {
+ baker->pid = pid;
break;
+ }
}
- baker.main = bmain;
- baker.scene = scene;
- baker.pid = pid;
- baker.bake = RNA_boolean_get(op->ptr, "bake");
- baker.render = 0;
- baker.anim_init = 0;
- baker.quick_step = 1;
- baker.break_test = cache_break_test;
- baker.break_data = NULL;
-
- /* Disabled for now as this doesn't work properly,
- * and pointcache baking will be reimplemented with
- * the job system soon anyways. */
- if (win) {
- baker.progressbar = (void (*)(void *, int))WM_cursor_time;
- baker.progressend = (void (*)(void *))WM_cursor_modal_restore;
- baker.progresscontext = win;
- }
- else {
- printf("\n"); /* empty first line before console reports */
- baker.progressbar = bake_console_progress;
- baker.progressend = bake_console_progress_end;
- baker.progresscontext = NULL;
- }
+ baker->bake_job = job;
- BKE_ptcache_bake(&baker);
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Point Cache",
+ WM_JOB_PROGRESS, WM_JOB_TYPE_POINTCACHE);
- BLI_freelistN(&pidlist);
+ WM_jobs_customdata_set(wm_job, job, ptcache_job_free);
+ WM_jobs_timer(wm_job, 0.1, NC_OBJECT | ND_POINTCACHE, NC_OBJECT | ND_POINTCACHE);
+ WM_jobs_callbacks(wm_job, ptcache_job_startjob, NULL, NULL, ptcache_job_endjob);
- WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
- WM_event_add_notifier(C, NC_OBJECT|ND_POINTCACHE, ob);
+ WM_set_locked_interface(CTX_wm_manager(C), true);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
return OPERATOR_FINISHED;
}
+
static int ptcache_free_bake_exec(bContext *C, wmOperator *UNUSED(op))
{
PointerRNA ptr= CTX_data_pointer_get_type(C, "point_cache", &RNA_PointCache);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 44337098970..3f7cfa8c690 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -3050,9 +3050,8 @@ static void update_physics_cache(Render *re, Scene *scene, int UNUSED(anim_init)
baker.render = 1;
baker.anim_init = 1;
baker.quick_step = 1;
- baker.break_test = re->test_break;
- baker.break_data = re->tbh;
- baker.progressbar = NULL;
+ baker.update_progress = NULL;
+ baker.bake_job = NULL;
BKE_ptcache_bake(&baker);
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 7100a46b622..fa7fde22611 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -442,6 +442,7 @@ enum {
WM_JOB_TYPE_CLIP_PREFETCH,
WM_JOB_TYPE_SEQ_BUILD_PROXY,
WM_JOB_TYPE_SEQ_BUILD_PREVIEW,
+ WM_JOB_TYPE_POINTCACHE,
/* add as needed, screencast, seq proxy build
* if having hard coded values is a problem */
};