Fix crash when changing space type to 3D space when having multiple windows
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Jan 2014 13:27:59 +0000 (19:27 +0600)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 23 Jan 2014 13:35:20 +0000 (19:35 +0600)
it is possible that different windows shares scene but displays different
layers. And it's also possible that different areas in the same window will
show different layers.

First case was violated in `dag_current_scene_layers()` which only checked
scene layers only once and if multiple windows shares the same scene only
one window was handled. Now made it so layers from all windows will be
squashed together into a single `DagSceneLayer`. This mainly solves issue
with `DAG_on_visible_update()` which didn't work reliable with multiple
open windows.

Second case required call of `DAG_on_visible_update()` when changing space
are type.

This commit slows things a bit actually because `dag_current_scene_layers()`
is actually called on every main WM loop iteration. It is possible to speed
some logic up perhaps. Not sure it's so much critical to do now because there
are unlikely to be more than few windows open anyway.

Will rather think of skipping all that flushing things if no objects are
tagged for update actually.

source/blender/blenkernel/intern/depsgraph.c
source/blender/makesrna/intern/rna_screen.c

index ed396fb32e32234f9c25e53fde1ba83d0634dd80..c6cfaaf2bcb05c0ca76e33aa8a9fefc8b7371e77 100644 (file)
@@ -2088,17 +2088,36 @@ static void dag_current_scene_layers(Main *bmain, ListBase *lb)
                for (win = wm->windows.first; win; win = win->next) {
                        if (win->screen && win->screen->scene->theDag) {
                                Scene *scene = win->screen->scene;
-                               
+                               DagSceneLayer *dsl;
+
                                if (scene->id.flag & LIB_DOIT) {
-                                       DagSceneLayer *dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
-                                       
+                                       dsl = MEM_mallocN(sizeof(DagSceneLayer), "dag scene layer");
+
                                        BLI_addtail(lb, dsl);
-                                       
+
                                        dsl->scene = scene;
                                        dsl->layer = BKE_screen_visible_layers(win->screen, scene);
-                                       
+
                                        scene->id.flag &= ~LIB_DOIT;
                                }
+                               else {
+                                       /* It is possible that multiple windows shares the same scene
+                                        * and have different layers visible.
+                                        *
+                                        * Here we deal with such cases by squashing layers bits from
+                                        * multiple windoew to the DagSceneLayer.
+                                        *
+                                        * TODO(sergey): Such a lookup could be optimized perhaps,
+                                        * however should be fine for now since we usually have only
+                                        * few open windows.
+                                        */
+                                       for (dsl = lb->first; dsl; dsl = dsl->next) {
+                                               if (dsl->scene == scene) {
+                                                       dsl->layer |= BKE_screen_visible_layers(win->screen, scene);
+                                                       break;
+                                               }
+                                       }
+                               }
                        }
                }
        }
index 85d5781118703799bb4396b629478a97dbae8d43..5f6526016376efd107aad87bbe055777d2bf5071 100644 (file)
@@ -56,6 +56,7 @@ EnumPropertyItem region_type_items[] = {
 #ifdef RNA_RUNTIME
 
 #include "BKE_global.h"
+#include "BKE_depsgraph.h"
 
 #include "UI_view2d.h"
 
@@ -141,6 +142,11 @@ static void rna_Area_type_update(bContext *C, PointerRNA *ptr)
                        ED_area_newspace(C, sa, sa->butspacetype);
                        ED_area_tag_redraw(sa);
 
+                       /* It is possible that new layers becomes visible. */
+                       if (sa->spacetype == SPACE_VIEW3D) {
+                               DAG_on_visible_update(CTX_data_main(C), FALSE);
+                       }
+
                        CTX_wm_window_set(C, prevwin);
                        CTX_wm_area_set(C, prevsa);
                        CTX_wm_region_set(C, prevar);