[Bf-blender-cvs] [3f20105622a] blender2.8: Fix random crashes in the outliner, especially with bigger scenes.

Brecht Van Lommel noreply at git.blender.org
Tue May 15 13:03:08 CEST 2018


Commit: 3f20105622a9871e6b71e8a29b25e24a97202e38
Author: Brecht Van Lommel
Date:   Tue May 15 12:49:38 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB3f20105622a9871e6b71e8a29b25e24a97202e38

Fix random crashes in the outliner, especially with bigger scenes.

The outliner can redraw quicker without rebuilding the tree, for example when
just moving the mouse and highlighting different items. The way this worked is
that the outliner would be tagged to avoid rebuilding, however if another
operation that does require rebuilding happens in the meantime we could go out
of sync and crash.

===================================================================

M	source/blender/editors/include/ED_screen.h
M	source/blender/editors/interface/view2d_ops.c
M	source/blender/editors/screen/area.c
M	source/blender/editors/space_outliner/outliner_collections.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_outliner/outliner_ops.c
M	source/blender/editors/space_outliner/outliner_select.c
M	source/blender/editors/space_outliner/outliner_tools.c
M	source/blender/editors/space_outliner/outliner_tree.c
M	source/blender/makesdna/DNA_screen_types.h
M	source/blender/makesdna/DNA_space_types.h

===================================================================

diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 5bfa73f6271..4b22e691885 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -74,6 +74,7 @@ void    ED_region_init(struct bContext *C, struct ARegion *ar);
 void    ED_region_tag_redraw(struct ARegion *ar);
 void    ED_region_tag_redraw_partial(struct ARegion *ar, const struct rcti *rct);
 void    ED_region_tag_redraw_overlay(struct ARegion *ar);
+void    ED_region_tag_redraw_no_rebuild(struct ARegion *ar);
 void    ED_region_tag_refresh_ui(struct ARegion *ar);
 void    ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *ar);
 void    ED_region_panels(
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 90ef47aa712..4101230c1ab 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -169,18 +169,19 @@ static void view_pan_apply_ex(bContext *C, v2dViewPanData *vpd, float dx, float
 	/* validate that view is in valid configuration after this operation */
 	UI_view2d_curRect_validate(v2d);
 	
-	/* request updates to be done... */
-	ED_region_tag_redraw(vpd->ar);
-	WM_event_add_mousemove(C);
-	
-	UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
-	
 	/* exceptions */
 	if (vpd->sa->spacetype == SPACE_OUTLINER) {
 		/* don't rebuild full tree, since we're just changing our view */
-		SpaceOops *soops = vpd->sa->spacedata.first;
-		soops->storeflag |= SO_TREESTORE_REDRAW;
+		ED_region_tag_redraw_no_rebuild(vpd->ar);
+	}
+	else {
+		ED_region_tag_redraw(vpd->ar);
 	}
+
+	/* request updates to be done... */
+	WM_event_add_mousemove(C);
+
+	UI_view2d_sync(vpd->sc, vpd->sa, v2d, V2D_LOCK_COPY);
 }
 
 static void view_pan_apply(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index ad4f6b0179d..8be89a6361e 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -550,7 +550,7 @@ void ED_region_tag_redraw(ARegion *ar)
 	 * but python scripts can cause this to happen indirectly */
 	if (ar && !(ar->do_draw & RGN_DRAWING)) {
 		/* zero region means full region redraw */
-		ar->do_draw &= ~RGN_DRAW_PARTIAL;
+		ar->do_draw &= ~(RGN_DRAW_PARTIAL | RGN_DRAW_NO_REBUILD);
 		ar->do_draw |= RGN_DRAW;
 		memset(&ar->drawrct, 0, sizeof(ar->drawrct));
 	}
@@ -562,6 +562,15 @@ void ED_region_tag_redraw_overlay(ARegion *ar)
 		ar->do_draw_overlay = RGN_DRAW;
 }
 
+void ED_region_tag_redraw_no_rebuild(ARegion *ar)
+{
+	if (ar && !(ar->do_draw & (RGN_DRAWING | RGN_DRAW))) {
+		ar->do_draw &= ~RGN_DRAW_PARTIAL;
+		ar->do_draw |= RGN_DRAW_NO_REBUILD;
+		memset(&ar->drawrct, 0, sizeof(ar->drawrct));
+	}
+}
+
 void ED_region_tag_refresh_ui(ARegion *ar)
 {
 	if (ar) {
@@ -572,7 +581,7 @@ void ED_region_tag_refresh_ui(ARegion *ar)
 void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
 {
 	if (ar && !(ar->do_draw & RGN_DRAWING)) {
-		if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_PARTIAL))) {
+		if (!(ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD | RGN_DRAW_PARTIAL))) {
 			/* no redraw set yet, set partial region */
 			ar->do_draw |= RGN_DRAW_PARTIAL;
 			ar->drawrct = *rct;
@@ -583,7 +592,7 @@ void ED_region_tag_redraw_partial(ARegion *ar, const rcti *rct)
 			BLI_rcti_union(&ar->drawrct, rct);
 		}
 		else {
-			BLI_assert((ar->do_draw & RGN_DRAW) != 0);
+			BLI_assert((ar->do_draw & (RGN_DRAW | RGN_DRAW_NO_REBUILD)) != 0);
 			/* Else, full redraw is already requested, nothing to do here. */
 		}
 	}
diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c
index 1cfe5b16fe1..4ea2c243365 100644
--- a/source/blender/editors/space_outliner/outliner_collections.c
+++ b/source/blender/editors/space_outliner/outliner_collections.c
@@ -782,7 +782,6 @@ static int collection_delete_exec(bContext *C, wmOperator *UNUSED(op))
 	/* TODO(sergey): Use proper flag for tagging here. */
 	DEG_id_tag_update(&scene->id, 0);
 
-	soops->storeflag |= SO_TREESTORE_REDRAW;
 	WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL);
 
 	return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 5d981bdad0d..c8765c5016e 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -1987,7 +1987,4 @@ void draw_outliner(const bContext *C)
 
 	UI_block_end(C, block);
 	UI_block_draw(C, block);
-
-	/* clear flag that allows quick redraws */
-	soops->storeflag &= ~SO_TREESTORE_REDRAW;
 } 
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 9207ee5ae15..4733b09da2f 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -172,8 +172,7 @@ static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const
 	}
 
 	if (changed) {
-		soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
-		ED_region_tag_redraw(ar);
+		ED_region_tag_redraw_no_rebuild(ar);
 	}
 
 	return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
@@ -903,10 +902,8 @@ static int outliner_toggle_selected_exec(bContext *C, wmOperator *UNUSED(op))
 	else 
 		outliner_set_flag(&soops->tree, TSE_SELECTED, 1);
 	
-	soops->storeflag |= SO_TREESTORE_REDRAW;
-	
 	WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
-	ED_region_tag_redraw(ar);
+	ED_region_tag_redraw_no_rebuild(ar);
 	
 	return OPERATOR_FINISHED;
 }
@@ -1027,11 +1024,9 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
 		xdelta = (int)(te->xs - v2d->cur.xmin);
 		v2d->cur.xmin += xdelta;
 		v2d->cur.xmax += xdelta;
-		
-		so->storeflag |= SO_TREESTORE_REDRAW;
 	}
 	
-	ED_region_tag_redraw(ar);
+	ED_region_tag_redraw_no_rebuild(ar);
 	
 	return OPERATOR_FINISHED;
 }
@@ -1187,7 +1182,7 @@ static void outliner_find_panel(Scene *UNUSED(scene), ARegion *ar, SpaceOops *so
 			soops->search_flags = flags;
 			
 			/* redraw */
-			soops->storeflag |= SO_TREESTORE_REDRAW;
+			ED_region_tag_redraw_no_rebuild(ar);
 		}
 	}
 	else {
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 2c4670d9ea3..9f466d331f3 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -271,11 +271,13 @@ static int outliner_item_drag_drop_modal(bContext *C, wmOperator *op, const wmEv
 			break;
 	}
 
-	if (skip_rebuild) {
-		soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
-	}
 	if (redraw) {
-		ED_region_tag_redraw(ar);
+		if (skip_rebuild) {
+			ED_region_tag_redraw_no_rebuild(ar);
+		}
+		else {
+			ED_region_tag_redraw(ar);
+		}
 	}
 
 	return retval;
@@ -389,8 +391,7 @@ static int outliner_item_drag_drop_invoke(bContext *C, wmOperator *op, const wmE
 	/* unset highlighted tree element, dragged one will be highlighted instead */
 	outliner_set_flag(&soops->tree, TSE_HIGHLIGHTED, false);
 
-	soops->storeflag |= SO_TREESTORE_REDRAW; /* only needs to redraw, no rebuild */
-	ED_region_tag_redraw(ar);
+	ED_region_tag_redraw_no_rebuild(ar);
 
 	WM_event_add_modal_handler(C, op);
 
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index b966b0f3dfa..4bde67d9662 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -995,12 +995,13 @@ int outliner_item_do_activate_from_cursor(
 	}
 
 	if (changed) {
-		if (!rebuild_tree) {
-			/* only needs to redraw, no rebuild */
-			soops->storeflag |= SO_TREESTORE_REDRAW;
+		if (rebuild_tree) {
+			ED_region_tag_redraw(ar);
+		}
+		else {
+			ED_region_tag_redraw_no_rebuild(ar);
 		}
 		ED_undo_push(C, "Outliner selection change");
-		ED_region_tag_redraw(ar);
 	}
 
 	return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index fff1bafdfff..fd5f29aec39 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -2034,9 +2034,10 @@ static int do_outliner_operation_event(bContext *C, ARegion *ar, SpaceOops *soop
 				outliner_set_flag(&soops->tree, TSE_SELECTED, 0);
 			
 			tselem->flag |= TSE_SELECTED;
-			/* redraw, same as outliner_select function */
-			soops->storeflag |= SO_TREESTORE_REDRAW;
-			ED_region_tag_redraw(ar);
+
+			/* Only redraw, don't rebuild here because TreeElement pointers will
+			 * become invalid and operations will crash. */
+			ED_region_tag_redraw_no_rebuild(ar);
 		}
 		
 		set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index d1195621138..f8158c9ce7b 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1705,8 +1705,6 @@ static void outliner_restore_scrolling_position(SpaceOops *soops, ARegion *ar, O
 		else {
 			return;
 		}
-
-		soops->storeflag |= SO_TREESTORE_REDRAW;
 	}
 }
 
@@ -2070,8 +2068,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, ViewLayer *view_layer, Spa
 		BKE_outliner_treehash_rebuild_from_treestore(soops->treehash, soops->treestore);
 	}
 
-	if (soops->tree.first && (soops->storeflag & SO_TREESTORE_REDRAW))
+	if (ar->flag & RGN_DRAW_NO_REBUILD) {
 		return;
+	}
 
 	OutlinerTreeElementFocus focus;
 	outliner_store_scrolling_position(soops, ar, &focus);
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 7392a56722e..395fcddb861 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -468,5 +468,6 @@ enum {
 #define RGN_DRAW_PARTIAL	2
 #define 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list