Workspaces: reference count screens, otherwise they are never freed.

They are not directly accessible in the UI anymore, it's the workspaces
that we always keep until they are manually deleted now.
This commit is contained in:
Brecht Van Lommel 2018-09-12 12:31:31 +02:00
parent 80f083f993
commit e082fc7c77
Notes: blender-bot 2023-02-14 06:46:23 +01:00
Referenced by issue #56801, Enabling smoke crashes Blender.
Referenced by issue #56803, Indirect lightning bake crashes Blender.
5 changed files with 19 additions and 17 deletions

View File

@ -950,7 +950,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
/* CALLBACK_INVOKE expects an actual pointer, not a variable holding the pointer.
* However we can't acess layout->screen here since we are outside the workspace project. */
CALLBACK_INVOKE(screen, IDWALK_CB_NOP);
CALLBACK_INVOKE(screen, IDWALK_CB_USER);
/* allow callback to set a different screen */
BKE_workspace_layout_screen_set(layout, screen);
}

View File

@ -243,6 +243,7 @@ WorkSpaceLayout *BKE_workspace_layout_add(
UNUSED_VARS(bmain);
#endif
layout->screen = screen;
id_us_plus(&layout->screen->id);
workspace_layout_name_set(workspace, layout, name);
BLI_addtail(&workspace->layouts, layout);
@ -253,7 +254,8 @@ void BKE_workspace_layout_remove(
Main *bmain,
WorkSpace *workspace, WorkSpaceLayout *layout)
{
BKE_libblock_free(bmain, BKE_workspace_layout_screen_get(layout));
id_us_min(&layout->screen->id);
BKE_libblock_free(bmain, layout->screen);
BLI_freelinkN(&workspace->layouts, layout);
}

View File

@ -2949,15 +2949,13 @@ static void lib_link_workspaces(FileData *fd, Main *bmain)
id_us_ensure_real(id);
for (WorkSpaceLayout *layout = layouts->first, *layout_next; layout; layout = layout_next) {
bScreen *screen = newlibadr(fd, id->lib, BKE_workspace_layout_screen_get(layout));
layout->screen = newlibadr_us(fd, id->lib, layout->screen);
layout_next = layout->next;
if (screen) {
BKE_workspace_layout_screen_set(layout, screen);
if (layout->screen) {
if (ID_IS_LINKED(id)) {
screen->winid = 0;
if (screen->temp) {
layout->screen->winid = 0;
if (layout->screen->temp) {
/* delete temp layouts when appending */
BKE_workspace_layout_remove(bmain, workspace, layout);
}
@ -7251,7 +7249,6 @@ static void lib_link_screen(FileData *fd, Main *main)
for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
if (sc->id.tag & LIB_TAG_NEED_LINK) {
IDP_LibLinkProperty(sc->id.properties, fd);
id_us_ensure_real(&sc->id);
/* deprecated, but needed for versioning (will be NULL'ed then) */
sc->scene = newlibadr(fd, sc->id.lib, sc->scene);

View File

@ -3005,15 +3005,18 @@ static void write_windowmanager(WriteData *wd, wmWindowManager *wm)
static void write_screen(WriteData *wd, bScreen *sc)
{
/* write LibData */
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
writestruct(wd, ID_SCRN, bScreen, 1, sc);
write_iddata(wd, &sc->id);
/* Screens are reference counted, only saved if used by a workspace. */
if (sc->id.us > 0 || wd->use_memfile) {
/* write LibData */
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
writestruct(wd, ID_SCRN, bScreen, 1, sc);
write_iddata(wd, &sc->id);
write_previews(wd, sc->preview);
write_previews(wd, sc->preview);
/* direct data */
write_area_map(wd, AREAMAP_FROM_SCREEN(sc));
/* direct data */
write_area_map(wd, AREAMAP_FROM_SCREEN(sc));
}
}
static void write_bone(WriteData *wd, Bone *bone)

View File

@ -111,7 +111,7 @@ typedef struct bToolRef {
typedef struct WorkSpaceLayout {
struct WorkSpaceLayout *next, *prev;
struct bScreen *screen DNA_PRIVATE_WORKSPACE;
struct bScreen *screen;
/* The name of this layout, we override the RNA name of the screen with this (but not ID name itself) */
char name[64] DNA_PRIVATE_WORKSPACE; /* MAX_NAME */
} WorkSpaceLayout;