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 | |
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')
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 22 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 6 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 20 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 70 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 1 |
7 files changed, 109 insertions, 27 deletions
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index c46263183a9..8eb12543b86 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -187,13 +187,17 @@ int WM_framebuffer_to_index(unsigned int col); struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner); +int WM_jobs_test(struct wmWindowManager *wm, void *owner); + void WM_jobs_customdata(struct wmJob *, void *customdata, void (*free)(void *)); -void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note); +void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote); void WM_jobs_callbacks(struct wmJob *, void (*startjob)(void *, short *, short *), + void (*initjob)(void *), void (*update)(void *)); void WM_jobs_start(struct wmJob *); +void WM_jobs_stop_all(struct wmWindowManager *wm); #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index f0747e6dad0..3b7def29236 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -140,18 +140,22 @@ typedef struct wmNotifier { /* category */ #define NOTE_CATEGORY 0xFF000000 -#define NC_WINDOW (1<<24) -#define NC_SCREEN (2<<24) -#define NC_SCENE (3<<24) -#define NC_OBJECT (4<<24) -#define NC_MATERIAL (5<<24) -#define NC_TEXTURE (6<<24) -#define NC_LAMP (7<<24) -#define NC_GROUP (8<<24) +#define NC_WM (1<<24) +#define NC_WINDOW (2<<24) +#define NC_SCREEN (3<<24) +#define NC_SCENE (4<<24) +#define NC_OBJECT (5<<24) +#define NC_MATERIAL (6<<24) +#define NC_TEXTURE (7<<24) +#define NC_LAMP (8<<24) +#define NC_GROUP (9<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 + /* windowmanager */ +#define ND_FILEREAD (1<<16) + /* Scene */ #define ND_MARKERS (2<<16) #define ND_FRAME (3<<16) @@ -161,6 +165,8 @@ typedef struct wmNotifier { #define ND_OB_ACTIVE (7<<16) #define ND_OB_SELECT (8<<16) #define ND_MODE (9<<16) +#define ND_RENDER_RESULT (10<<16) +#define ND_COMPO_RESULT (11<<16) /* Object */ #define ND_TRANSFORM (16<<16) diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index d264b096012..3aa177b1018 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -128,11 +128,13 @@ void wm_add_default(bContext *C) { wmWindowManager *wm= alloc_libblock(&CTX_data_main(C)->wm, ID_WM, "WinMan"); wmWindow *win; + bScreen *screen= CTX_wm_screen(C); /* XXX from file read hrmf */ CTX_wm_manager_set(C, wm); - win= wm_window_new(C); - win->screen= CTX_wm_screen(C); /* XXX from window? */ + win->screen= screen; + if(screen) + BLI_strncpy(win->screenname, screen->id.name+2, 21); wm->winactive= win; wm_window_make_drawable(C, win); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 4bd3cf3f39f..744113f3d3a 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -394,6 +394,9 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) /* first wrap up running stuff */ /* code copied from wm_init_exit.c */ for(wm= wmlist->first; wm; wm= wm->id.next) { + + WM_jobs_stop_all(wm); + for(win= wm->windows.first; win; win= win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ @@ -443,12 +446,14 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* match oldwm to new dbase, only old files */ for(wm= oldwmlist->first; wm; wm= wm->id.next) { + /* ensure making new keymaps and set space types */ + wm->initialized= 0; + for(win= wm->windows.first; win; win= win->next) { - win->screen= (bScreen *)find_id("SR", win->screenname); - - if(win->screen==NULL) - win->screen= ED_screen_duplicate(win, CTX_wm_screen(C)); /* active screen */ - + /* all windows get active screen from file */ + win->screen= CTX_wm_screen(C); + BLI_strncpy(win->screenname, win->screen->id.name+2, 21); + if(win->screen->winid==0) win->screen->winid= win->winid; } @@ -462,6 +467,10 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* this code could move to setup_appdata */ oldwm= oldwmlist->first; wm= G.main->wm.first; + + /* ensure making new keymaps and set space types */ + wm->initialized= 0; + /* only first wm in list has ghostwins */ for(win= wm->windows.first; win; win= win->next) { for(oldwin= oldwm->windows.first; oldwin; oldwin= oldwin->next) { @@ -518,6 +527,7 @@ void WM_read_file(bContext *C, char *name, ReportList *reports) BKE_reset_undo(); BKE_write_undo(C, "original"); /* save current state */ + WM_event_add_notifier(C, NC_WM|ND_FILEREAD, NULL); // refresh_interface_font(); } // else if(retval==1) diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 01e4cd10b3d..f702154735e 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -82,6 +82,7 @@ #include "wm_files.h" #include "wm_window.h" +#include "ED_node.h" #include "ED_previewrender.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -114,10 +115,11 @@ void WM_init(bContext *C) set_free_windowmanager_cb(wm_close_and_free); /* library.c */ set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ - ED_spacetypes_init(); /* editors/area/spacetype.c */ + ED_spacetypes_init(); /* editors/space_api/spacetype.c */ + + ED_file_init(); /* for fsmenu */ + ED_init_node_butfuncs(); - ED_file_init(); /* for fsmenu */ - /* get the default database, plus a wm */ WM_read_homefile(C, 0); @@ -175,6 +177,9 @@ void WM_exit(bContext *C) /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if(C && CTX_wm_manager(C)) { + + WM_jobs_stop_all(CTX_wm_manager(C)); + for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ 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); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index fc49deb8154..eebf89982c1 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -153,6 +153,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) win->sizey= winorig->sizey; win->screen= ED_screen_duplicate(win, winorig->screen); + BLI_strncpy(win->screenname, win->screen->id.name+2, 21); win->screen->do_refresh= 1; win->screen->do_draw= 1; |