Tool System: avoid redundant refresh
authorCampbell Barton <ideasman42@gmail.com>
Tue, 14 May 2019 22:43:02 +0000 (08:43 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 14 May 2019 22:48:20 +0000 (08:48 +1000)
Workspaces refreshes tools multiple times when used by multiple windows.

Also improve comments.

source/blender/blenkernel/BKE_workspace.h
source/blender/blenkernel/intern/workspace.c
source/blender/windowmanager/intern/wm_toolsystem.c

index 0a4ad4c..133cf2d 100644 (file)
@@ -110,6 +110,8 @@ void BKE_workspace_hook_layout_for_workspace_set(struct WorkSpaceInstanceHook *h
 bool BKE_workspace_owner_id_check(const struct WorkSpace *workspace, const char *owner_id)
     ATTR_NONNULL();
 
+void BKE_workspace_id_tag_all_visible(struct Main *bmain, int tag) ATTR_NONNULL();
+
 #undef GETTER_ATTRS
 #undef SETTER_ATTRS
 
index 909aa73..669eb5c 100644 (file)
@@ -36,6 +36,7 @@
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
 #include "DNA_workspace_types.h"
 
 #include "DEG_depsgraph.h"
@@ -367,11 +368,21 @@ bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_
     return true;
   }
   else {
-    /* we could use hash lookup, for now this list is highly under < ~16 items. */
+    /* We could use hash lookup, for now this list is highly likely under < ~16 items. */
     return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
   }
 }
 
+void BKE_workspace_id_tag_all_visible(Main *bmain, int tag)
+{
+  BKE_main_id_tag_listbase(&bmain->workspaces, tag, false);
+  wmWindowManager *wm = bmain->wm.first;
+  for (wmWindow *win = wm->windows.first; win; win = win->next) {
+    WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+    workspace->id.tag |= tag;
+  }
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
index 773f02e..92ef235 100644 (file)
@@ -549,7 +549,6 @@ bool WM_toolsystem_key_from_context(ViewLayer *view_layer, ScrArea *sa, bToolKey
 void WM_toolsystem_refresh_active(bContext *C)
 {
   Main *bmain = CTX_data_main(C);
-  BKE_main_id_tag_idcode(bmain, ID_WS, LIB_TAG_DOIT, false);
   for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) {
     for (wmWindow *win = wm->windows.first; win; win = win->next) {
       WorkSpace *workspace = WM_window_get_active_workspace(win);
@@ -573,13 +572,19 @@ void WM_toolsystem_refresh_active(bContext *C)
           }
         }
       }
+    }
+  }
 
-      if ((workspace->id.tag & LIB_TAG_DOIT) == 0) {
-        workspace->id.tag |= LIB_TAG_DOIT;
-        /* Refresh to ensure data is initialized, see: T64339. */
-        for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
-          toolsystem_refresh_ref(C, workspace, tref);
-        }
+  BKE_workspace_id_tag_all_visible(bmain, LIB_TAG_DOIT);
+
+  LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) {
+    if (workspace->id.tag & LIB_TAG_DOIT) {
+      workspace->id.tag &= ~LIB_TAG_DOIT;
+      /* Refresh to ensure data is initialized.
+       * This is needed because undo can load a state which no longer has the underlying DNA data
+       * needed for the tool (un-initialized paint-slots for eg), see: T64339. */
+      for (bToolRef *tref = workspace->tools.first; tref; tref = tref->next) {
+        toolsystem_refresh_ref(C, workspace, tref);
       }
     }
   }