Fix: Blender crashes opening a file with compositor
Blender crashes when opening a file that has an interactive compositor active, while also having a script that invokes the compositor upon file load. This is caused by the same system GPU context being active in two threads at the same time, which happens when the GPU context for the compositor is created in the main thread, it is made current during creation, but it is not reset to the main GPU context of the drawable because it is null. So when the GPU compositor actually executes, it makes the GPU context current again but in its own thread, causing a BadAccess error in X11 and potentially other window systems. The reason why the drawable is nullptr is because it is reset in the existing window manager when opening a new file while Blender is open, but it is never initialized for the new window manager. The drawable info should be moved from the old window manager to the new window manager in wm_file_read_setup_wm_use_new, but it is preemptively reset by the wm_window_clear_drawable call before it it is moved. This is done in wm_file_read_setup_wm_substitute_old_window. So to fix this, we move wm_window_clear_drawable after the code block where wm_file_read_setup_wm_substitute_old_window gets called.
This commit is contained in:
@@ -386,9 +386,6 @@ static void wm_file_read_setup_wm_use_new(bContext *C,
|
||||
wm->init_flag = 0;
|
||||
wm->winactive = nullptr;
|
||||
|
||||
/* Clearing drawable of old WM before deleting any context to avoid clearing the wrong wm. */
|
||||
wm_window_clear_drawable(old_wm);
|
||||
|
||||
bool has_match = false;
|
||||
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
|
||||
LISTBASE_FOREACH (wmWindow *, old_win, &old_wm->windows) {
|
||||
@@ -407,6 +404,9 @@ static void wm_file_read_setup_wm_use_new(bContext *C,
|
||||
static_cast<wmWindow *>(wm->windows.first));
|
||||
}
|
||||
|
||||
/* Clearing drawable of old WM before deleting any context to avoid clearing the wrong wm. */
|
||||
wm_window_clear_drawable(old_wm);
|
||||
|
||||
wm_setup_data->old_wm = nullptr;
|
||||
wm_close_and_free(C, old_wm);
|
||||
/* Don't handle user counts as this is only ever called once #G_MAIN has already been freed via
|
||||
|
||||
Reference in New Issue
Block a user