diff options
author | Ton Roosendaal <ton@blender.org> | 2009-01-27 20:12:40 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-01-27 20:12:40 +0300 |
commit | c0ee40ab1077de07741344b163ccd8de046db0fe (patch) | |
tree | 8469c10210578f650141ce0717212a4a608db806 /source/blender/windowmanager/intern/wm_jobs.c | |
parent | b602fd8b1c7c3f492ba91ff7dc85a0aafd5c3ee7 (diff) |
2.5
Compositor now uses threaded jobs.
- updates happen per preview node! Check this file for
fun: http://www.blender.org/bf/composite_image.blend
(any compo node could get preview!)
- had to ensure the composite data gets fully copied before
it executes thread, so editing is not frustrated.
- put back node buttons (missing init)
- added WM_jobs api call to check for running job,
illustrated with red light icon in 'use nodes' button.
- added another callback to WM_jobs, to initialize.
use this init to ensure you only do it when job really
starts.
- added an extra notifier option for WM_jobs, to signal
finished job (like redraw image view)
- fixed file read error, it copied the screen it read,
instead of using it.
- commented out annoying prints for missing ops in imagewin
Diffstat (limited to 'source/blender/windowmanager/intern/wm_jobs.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 422cc42e10b..40a72034d26 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -36,6 +36,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_idprop.h" +#include "BKE_global.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_report.h" @@ -87,18 +88,22 @@ struct wmJob { /* should store entire own context, for start, update, free */ void *customdata; + /* to prevent cpu overhead, use this one which only gets called when job really starts, not in thread */ + void (*initjob)(void *); + /* this runs inside thread, and does full job */ void (*startjob)(void *, short *stop, short *do_update); + /* update gets called if thread defines so, and max once per timerstep */ + /* it runs outside thread, blocking blender, no drawing! */ + void (*update)(void *); + /* free entire customdata, doesn't run in thread */ void (*free)(void *); /* running jobs each have own timer */ double timestep; wmTimer *wt; /* the notifier event timers should send */ - unsigned int note; + unsigned int note, endnote; - /* update gets called if thread defines so, and max once per timerstep */ - /* no drawing, send notifiers! */ - void (*update)(void *); /* internal */ void *owner; @@ -135,6 +140,18 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner) return steve; } +/* returns true if job runs, for UI (progress) indicators */ +int WM_jobs_test(wmWindowManager *wm, void *owner) +{ + wmJob *steve; + + for(steve= wm->jobs.first; steve; steve= steve->next) + if(steve->owner==owner) + if(steve->running) + return 1; + return 0; +} + void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *)) { /* pending job? just free */ @@ -150,17 +167,20 @@ void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *)) } } -void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note) +void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note, unsigned int endnote) { steve->timestep = timestep; steve->note = note; + steve->endnote = endnote; } void WM_jobs_callbacks(wmJob *steve, void (*startjob)(void *, short *, short *), + void (*initjob)(void *), void (*update)(void *)) { steve->startjob= startjob; + steve->initjob= initjob; steve->update= update; } @@ -191,9 +211,14 @@ void WM_jobs_start(wmJob *steve) steve->customdata= NULL; steve->running= 1; - BLI_init_threads(&steve->threads, do_job_thread, 1); + if(steve->initjob) + steve->initjob(steve->run_customdata); + + BLI_init_threads(&steve->threads, do_job_thread, 1); BLI_insert_thread(&steve->threads, steve); + // printf("job started\n"); + /* restarted job has timer already */ if(steve->wt==NULL) steve->wt= WM_event_add_window_timer(steve->win, TIMERJOBS, steve->timestep); @@ -202,6 +227,28 @@ void WM_jobs_start(wmJob *steve) } } +void WM_jobs_stop_all(wmWindowManager *wm) +{ + wmJob *steve= wm->jobs.first; + + for(; steve; steve= steve->next) { + if(steve->running) { + /* signal job to end */ + steve->stop= 1; + BLI_end_threads(&steve->threads); + } + + if(steve->wt) + WM_event_remove_window_timer(steve->win, steve->wt); + if(steve->customdata) + steve->free(steve->customdata); + if(steve->run_customdata) + steve->run_free(steve->run_customdata); + } + + BLI_freelistN(&wm->jobs); +} + /* hardcoded to event TIMERJOBS */ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) { @@ -214,9 +261,10 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) /* running threads */ if(steve->threads.first) { - if(steve->do_update) { + /* always call note and update when ready */ + if(steve->do_update || steve->ready) { if(steve->update) - steve->update(steve->customdata); + steve->update(steve->run_customdata); if(steve->note) WM_event_add_notifier(C, steve->note, NULL); steve->do_update= 0; @@ -228,9 +276,15 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt) steve->run_customdata= NULL; steve->run_free= NULL; + // if(steve->stop) printf("job stopped\n"); + // else printf("job finished\n"); + steve->running= 0; BLI_end_threads(&steve->threads); + if(steve->endnote) + WM_event_add_notifier(C, steve->endnote, NULL); + /* new job added for steve? */ if(steve->customdata) { WM_jobs_start(steve); |