From 8f825bd460d95e8daa79bbe06564964da7189352 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 4 Jul 2010 19:58:52 +0000 Subject: Fix #21062 and #22175: crash with node previews being calculated while editing nodes. Now preview jobs are killed before making any node edits. --- source/blender/editors/include/ED_render.h | 1 + .../editors/interface/interface_templates.c | 5 ++- source/blender/editors/render/render_preview.c | 6 ++++ source/blender/editors/space_file/filelist.c | 2 +- source/blender/editors/space_node/node_edit.c | 42 ++++++++++++++++++---- source/blender/windowmanager/WM_api.h | 4 +-- source/blender/windowmanager/intern/wm_jobs.c | 15 ++++---- 7 files changed, 54 insertions(+), 21 deletions(-) (limited to 'source') diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 6100ecd436f..f34670da471 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -78,6 +78,7 @@ void ED_preview_free_dbase(void); void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method); void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey); +void ED_preview_kill_jobs(const struct bContext *C); void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 865a4ec8af9..dbe64bedbc6 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -952,7 +952,6 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con, uiLayout *result= NULL, *col, *col1, *col2, *box, *row, *subrow, *split; PointerRNA ptr; char typestr[32]; - short width = 265; short proxy_protected, xco=0, yco=0; int rb_col; @@ -2444,13 +2443,13 @@ static void do_running_jobs(bContext *C, void *arg, int event) G.afbreek= 1; break; case B_STOPCAST: - WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C)); + WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C), NULL); break; case B_STOPANIM: WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL); break; case B_STOPCOMPO: - WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C)); + WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL); break; } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 898a8f527c3..ae2462b95f8 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -1153,4 +1153,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M WM_jobs_start(CTX_wm_manager(C), steve); } +void ED_preview_kill_jobs(const struct bContext *C) +{ + wmWindowManager *wm= CTX_wm_manager(C); + if(wm) + WM_jobs_kill(wm, NULL, common_preview_startjob); +} diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 5e4887827b6..37653d616c4 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1360,7 +1360,7 @@ void thumbnails_start(struct FileList* filelist, const struct bContext* C) void thumbnails_stop(struct FileList* filelist, const struct bContext* C) { - WM_jobs_kill(CTX_wm_manager(C), filelist); + WM_jobs_kill(CTX_wm_manager(C), filelist, NULL); } int thumbnails_running(struct FileList* filelist, const struct bContext* C) diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 222504179cb..cea88c33c5b 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -66,6 +66,7 @@ #include "ED_node.h" #include "ED_screen.h" +#include "ED_render.h" #include "RNA_access.h" #include "RNA_define.h" @@ -549,6 +550,8 @@ static int node_group_edit_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; + ED_preview_kill_jobs(C); + gnode= nodeGetActive(snode->edittree); snode_make_group_editable(snode, gnode); @@ -594,6 +597,8 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); bNode *gnode; + ED_preview_kill_jobs(C); + /* are we inside of a group? */ gnode= node_tree_get_editgroup(snode->nodetree); if(gnode) @@ -1099,13 +1104,16 @@ static int node_active_link_viewer(bContext *C, wmOperator *op) SpaceNode *snode= CTX_wm_space_node(C); bNode *node; - node= editnode_get_active(snode->edittree); - if(node) { - node_link_viewer(snode, node); - snode_notify(C, snode); - } + if(!node) + return OPERATOR_CANCELLED; + + ED_preview_kill_jobs(C); + + node_link_viewer(snode, node); + snode_notify(C, snode); + return OPERATOR_FINISHED; } @@ -1467,6 +1475,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) { SpaceNode *snode= CTX_wm_space_node(C); + ED_preview_kill_jobs(C); + ntreeCopyTree(snode->edittree, 1); /* 1 == internally selected nodes */ ntreeSolveOrder(snode->edittree); @@ -1625,7 +1635,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) static int node_link_init(SpaceNode *snode, NodeLinkDrag *nldrag) { bNodeLink *link; - + /* output indicated? */ if(find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_OUT)) { if(nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit) @@ -1679,6 +1689,8 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) UI_view2d_region_to_view(&ar->v2d, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin, &snode->mx, &snode->my); + ED_preview_kill_jobs(C); + nldrag->in_out= node_link_init(snode, nldrag); if(nldrag->in_out) { @@ -1725,6 +1737,8 @@ static int node_make_link_exec(bContext *C, wmOperator *op) SpaceNode *snode= CTX_wm_space_node(C); int replace = RNA_boolean_get(op->ptr, "replace"); + ED_preview_kill_jobs(C); + snode_autoconnect(snode, 0, replace); node_tree_verify_groups(snode->nodetree); @@ -1788,6 +1802,8 @@ static int cut_links_exec(bContext *C, wmOperator *op) if(i>1) { bNodeLink *link, *next; + + ED_preview_kill_jobs(C); for(link= snode->edittree->links.first; link; link= next) { next= link->next; @@ -1840,6 +1856,8 @@ static int node_read_renderlayers_exec(bContext *C, wmOperator *op) Scene *curscene= CTX_data_scene(C), *scene; bNode *node; + ED_preview_kill_jobs(C); + /* first tag scenes unread */ for(scene= G.main->scene.first; scene; scene= scene->id.next) scene->id.flag |= LIB_DOIT; @@ -1956,6 +1974,8 @@ static int node_group_make_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } } + + ED_preview_kill_jobs(C); gnode= nodeMakeGroupFromSelected(snode->nodetree); if(gnode==NULL) { @@ -2058,6 +2078,8 @@ static int node_preview_exec(bContext *C, wmOperator *op) if((snode == NULL) || (snode->edittree == NULL)) return OPERATOR_CANCELLED; + ED_preview_kill_jobs(C); + node_flag_toggle_exec(snode, NODE_PREVIEW); snode_notify(C, snode); @@ -2090,6 +2112,8 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *op) if((snode == NULL) || (snode->edittree == NULL)) return OPERATOR_CANCELLED; + ED_preview_kill_jobs(C); + for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { if(node_has_hidden_sockets(node)) { @@ -2138,6 +2162,8 @@ static int node_mute_exec(bContext *C, wmOperator *op) if(node_tree_get_editgroup(snode->nodetree)) return OPERATOR_CANCELLED; + ED_preview_kill_jobs(C); + for(node= snode->edittree->nodes.first; node; node= node->next) { if(node->flag & SELECT) { if(node->inputs.first && node->outputs.first) { @@ -2174,6 +2200,8 @@ static int node_delete_exec(bContext *C, wmOperator *op) SpaceNode *snode= CTX_wm_space_node(C); bNode *node, *next; + ED_preview_kill_jobs(C); + for(node= snode->edittree->nodes.first; node; node= next) { next= node->next; if(node->flag & SELECT) { @@ -2275,6 +2303,8 @@ static int node_add_file_exec(bContext *C, wmOperator *op) if (snode->nodetree->type==NTREE_COMPOSIT) ntype = CMP_NODE_IMAGE; + + ED_preview_kill_jobs(C); node = node_add_node(snode, scene, ntype, snode->mx, snode->my); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 235be838f63..78ea0350667 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -325,8 +325,8 @@ void WM_jobs_callbacks(struct wmJob *, void (*endjob)(void *)); void WM_jobs_start(struct wmWindowManager *wm, struct wmJob *); -void WM_jobs_stop(struct wmWindowManager *wm, void *owner); -void WM_jobs_kill(struct wmWindowManager *wm, void *owner); +void WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob); +void WM_jobs_kill(struct wmWindowManager *wm, void *owner, void *startjob); void WM_jobs_stop_all(struct wmWindowManager *wm); /* clipboard */ diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index c3ad8f96cb0..80f1c680931 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -339,28 +339,25 @@ void WM_jobs_stop_all(wmWindowManager *wm) } -/* signal job(s) from this owner to stop, timer is required to get handled */ -void WM_jobs_stop(wmWindowManager *wm, void *owner) +/* signal job(s) from this owner or callback to stop, timer is required to get handled */ +void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob) { wmJob *steve; for(steve= wm->jobs.first; steve; steve= steve->next) - if(steve->owner==owner) + if(steve->owner==owner || steve->startjob==startjob) if(steve->running) steve->stop= 1; } /* actually terminate thread and job timer */ -void WM_jobs_kill(wmWindowManager *wm, void *owner) +void WM_jobs_kill(wmWindowManager *wm, void *owner, void *startjob) { wmJob *steve; for(steve= wm->jobs.first; steve; steve= steve->next) - if(steve->owner==owner) - break; - - if (steve) - wm_jobs_kill_job(wm, steve); + if(steve->owner==owner || steve->startjob==startjob) + wm_jobs_kill_job(wm, steve); } -- cgit v1.2.3