diff --git a/intern/gawain/src/gwn_immediate.c b/intern/gawain/src/gwn_immediate.c index c57564fce06..d43e52cc525 100644 --- a/intern/gawain/src/gwn_immediate.c +++ b/intern/gawain/src/gwn_immediate.c @@ -77,8 +77,6 @@ void immInit(void) glBindBuffer(GL_ARRAY_BUFFER, 0); initialized = true; - - immActivate(); } void immActivate(void) @@ -106,7 +104,6 @@ void immDeactivate(void) void immDestroy(void) { - immDeactivate(); GWN_buf_id_free(imm.vbo_id); initialized = false; } diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 9ac93efe347..f088ac9f442 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -143,17 +143,11 @@ static void rna_userdef_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe } /* also used by buffer swap switching */ -static void rna_userdef_dpi_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) +static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr)) { /* font's are stored at each DPI level, without this we can easy load 100's of fonts */ BLF_cache_clear(); - /* force setting drawable again */ - wmWindowManager *wm = bmain->wm.first; - if (wm) { - wm->windrawable = NULL; - } - WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */ } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 6b727a57370..0c3f4fb5181 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -186,13 +186,18 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) ED_editors_exit(C); } -static void wm_window_substitute_old(wmWindowManager *wm, wmWindow *oldwin, wmWindow *win) +static void wm_window_substitute_old(wmWindowManager *oldwm, wmWindowManager *wm, wmWindow *oldwin, wmWindow *win) { win->ghostwin = oldwin->ghostwin; win->gwnctx = oldwin->gwnctx; win->active = oldwin->active; - if (win->active) + if (win->active) { wm->winactive = win; + } + if (oldwm->windrawable == oldwin) { + oldwm->windrawable = NULL; + wm->windrawable = win; + } if (!G.background) /* file loading in background mode still calls this */ GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ @@ -281,13 +286,13 @@ static void wm_window_match_replace_by_file_wm( if (oldwin->winid == win->winid) { has_match = true; - wm_window_substitute_old(wm, oldwin, win); + wm_window_substitute_old(oldwm, wm, oldwin, win); } } } /* make sure at least one window is kept open so we don't lose the context, check T42303 */ if (!has_match) { - wm_window_substitute_old(wm, oldwm->windows.first, wm->windows.first); + wm_window_substitute_old(oldwm, wm, oldwm->windows.first, wm->windows.first); } wm_close_and_free_all(C, current_wm_list); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c1af7153b62..183e58e5a15 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -491,8 +491,6 @@ void WM_exit_ext(bContext *C, const bool do_python) #endif GPU_free_unused_buffers(G_MAIN); - - GPU_exit(); } BKE_blender_free(); /* blender.c, does entire library and spacetypes */ @@ -515,6 +513,7 @@ void WM_exit_ext(bContext *C, const bool do_python) if (opengl_is_init) { GPU_pass_cache_free(); DRW_opengl_context_destroy(); + GPU_exit(); } #ifdef WITH_INTERNATIONAL diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index ef7992dcb8c..003932930ed 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1283,6 +1283,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) /* initialize OpenGL immediate mode */ g_WS.gwn_context = GWN_context_create(); GPU_init(); + immActivate(); /* initialize the font */ BLF_init(); @@ -1551,8 +1552,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv) GPU_shader_free_builtin_shaders(); - GPU_exit(); - if (g_WS.gwn_context) { GWN_context_active_set(g_WS.gwn_context); GWN_context_discard(g_WS.gwn_context); @@ -1561,6 +1560,9 @@ static char *wm_main_playanim_intern(int argc, const char **argv) BLF_exit(); + immDeactivate(); + GPU_exit(); + GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window); /* early exit, IMB and BKE should be exited only in end */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index e4ccf074bab..4f86d05d515 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -122,6 +122,9 @@ static struct WMInitStruct { /* ******** win open & close ************ */ +static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate); +static void wm_window_clear_drawable(wmWindowManager *wm); + /* XXX this one should correctly check for apple top header... * done for Cocoa : returns window contents (and not frame) max size*/ void wm_get_screensize(int *r_width, int *r_height) @@ -176,10 +179,19 @@ static void wm_window_check_position(rcti *rect) if (rect->ymin < 0) rect->ymin = 0; } - static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win) { if (win->ghostwin) { + if (win == wm->windrawable) { + /* Prevents non-drawable state of main windows (bugs #22967, + * #25071 and possibly #22477 too). */ + wm_window_clear_drawable(wm); + } + + if (win == wm->winactive) { + wm->winactive = NULL; + } + /* We need this window's opengl context active to discard it. */ GHOST_ActivateWindowDrawingContext(win->ghostwin); GWN_context_active_set(win->gwnctx); @@ -191,9 +203,6 @@ static void wm_ghostwindow_destroy(wmWindowManager *wm, wmWindow *win) win->ghostwin = NULL; win->gwnctx = NULL; - /* prevents non-drawable state of main windows (bugs #22967 and #25071, possibly #22477 too) */ - wm->windrawable = NULL; - wm->winactive = NULL; } } @@ -513,21 +522,8 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) ED_screen_exit(C, win, screen); } - if (win_other) { - BLF_batch_reset(); - gpu_batch_presets_reset(); - immDeactivate(); - } - wm_window_free(C, wm, win); - /* keep imediatemode active before the next `wm_window_make_drawable` call */ - if (win_other) { - GHOST_ActivateWindowDrawingContext(win_other->ghostwin); - GWN_context_active_set(win_other->gwnctx); - immActivate(); - } - /* if temp screen, delete it after window free (it stops jobs that can access it) */ if (screen && screen->temp) { Main *bmain = CTX_data_main(C); @@ -646,19 +642,19 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm if (ghostwin) { GHOST_RectangleHandle bounds; - /* XXX Fix crash when a new window is created. - * However this should be move somewhere else. (fclem) */ - BLF_batch_reset(); - gpu_batch_presets_reset(); + /* Clear drawable so we can set the new window. */ + wm_window_clear_drawable(wm); win->gwnctx = GWN_context_create(); - /* the new window has already been made drawable upon creation */ - wm->windrawable = win; - /* needed so we can detect the graphics card below */ GPU_init(); + /* Set window as drawable upon creation. Note this has already been + * it has already been activated by GHOST_CreateWindow. */ + bool activate = false; + wm_window_set_drawable(wm, win, activate); + win->ghostwin = ghostwin; GHOST_SetWindowUserData(ghostwin, win); /* pointer back */ @@ -1095,24 +1091,41 @@ static int query_qual(modifierKeyType qual) return val; } +static void wm_window_set_drawable(wmWindowManager *wm, wmWindow *win, bool activate) +{ + BLI_assert(ELEM(wm->windrawable, NULL, win)); + + wm->windrawable = win; + if (activate) { + GHOST_ActivateWindowDrawingContext(win->ghostwin); + } + GWN_context_active_set(win->gwnctx); + immActivate(); +} + +static void wm_window_clear_drawable(wmWindowManager *wm) +{ + if (wm->windrawable) { + BLF_batch_reset(); + gpu_batch_presets_reset(); + immDeactivate(); + wm->windrawable = NULL; + } +} + void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win) { BLI_assert(GPU_framebuffer_current_get() == 0); if (win != wm->windrawable && win->ghostwin) { // win->lmbut = 0; /* keeps hanging when mousepressed while other window opened */ + wm_window_clear_drawable(wm); - wm->windrawable = win; if (G.debug & G_DEBUG_EVENTS) { printf("%s: set drawable %d\n", __func__, win->winid); } - BLF_batch_reset(); - gpu_batch_presets_reset(); - immDeactivate(); - GHOST_ActivateWindowDrawingContext(win->ghostwin); - GWN_context_active_set(win->gwnctx); - immActivate(); + wm_window_set_drawable(wm, win, true); /* this can change per window */ WM_window_set_dpi(win); @@ -1132,12 +1145,8 @@ void wm_window_reset_drawable(void) wmWindow *win = wm->windrawable; if (win && win->ghostwin) { - BLF_batch_reset(); - gpu_batch_presets_reset(); - immDeactivate(); - GHOST_ActivateWindowDrawingContext(win->ghostwin); - GWN_context_active_set(win->gwnctx); - immActivate(); + wm_window_clear_drawable(wm); + wm_window_set_drawable(wm, win, true); } }