diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-04-25 18:43:08 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-04-25 18:43:18 +0300 |
commit | 46bfdb48a19335d7db2114c697ccca05cb0011af (patch) | |
tree | 9ab7beb71732c0c01558f0b2a1101e260b5012b4 | |
parent | 56fbdd790899301b4baf290ae693ceb9a4d5d467 (diff) |
WM: Add GHOST lazy init for background mode.
This allows for background rendering with EEVEE and other opengl render
engine.
I've only tested it on Linux for the moment so I can't say about other
platforms.
We do lazy init because we cannot assume we will need Ghost for rendering
before having parsed all arguments and we cannot know if a script will
trigger rendering. This is also because it currently does not work without
any display server (blender will crash).
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 22 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_init_exit.c | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 1 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 53 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 13 |
5 files changed, 73 insertions, 24 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 0e66fff943f..6550fa19105 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1361,6 +1361,11 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) DrawEngineType *draw_engine_type = engine_type->draw_engine; RenderData *r = &scene->r; Render *render = engine->re; + + if (G.background && DST.ogl_context == NULL) { + WM_init_opengl(); + } + /* Changing Context */ DRW_opengl_context_enable(); /* IMPORTANT: We dont support immediate mode in render mode! @@ -2049,13 +2054,16 @@ void DRW_opengl_context_create(void) BLI_assert(DST.ogl_context == NULL); /* Ensure it's called once */ BLI_mutex_init(&DST.ogl_context_mutex); - - immDeactivate(); + if (!G.background) { + immDeactivate(); + } /* This changes the active context. */ DST.ogl_context = WM_opengl_context_create(); /* Be sure to create gawain.context too. */ DST.gwn_context = GWN_context_create(); - immActivate(); + if (!G.background) { + immActivate(); + } /* Set default Blender OpenGL state */ GPU_state_init(); /* So we activate the window's one afterwards. */ @@ -2082,12 +2090,16 @@ void DRW_opengl_context_enable(void) * multiple threads. */ BLI_mutex_lock(&DST.ogl_context_mutex); if (BLI_thread_is_main()) { - immDeactivate(); + if (!G.background) { + immDeactivate(); + } } WM_opengl_context_activate(DST.ogl_context); GWN_context_active_set(DST.gwn_context); if (BLI_thread_is_main()) { - immActivate(); + if (!G.background) { + immActivate(); + } BLF_batch_reset(); } } diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 5015d7c2372..c2f14687ff5 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -63,7 +63,9 @@ void GPU_init(void) gpu_batch_init(); - immInit(); + if (!G.background) { + immInit(); + } GPU_pbvh_fix_linking(); } @@ -72,7 +74,9 @@ void GPU_init(void) void GPU_exit(void) { - immDestroy(); + if (!G.background) { + immDestroy(); + } gpu_batch_exit(); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 652cdac6315..de5ce6d211d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -93,6 +93,7 @@ void WM_main (struct bContext *C) ATTR_NORETURN; void WM_init_splash (struct bContext *C); +void WM_init_opengl (void); void WM_check (struct bContext *C); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 3cf2575cfc7..d452c1638c8 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -154,6 +154,40 @@ static void wm_free_reports(bContext *C) bool wm_start_with_console = false; /* used in creator.c */ +/** + * Since we cannot know in advance if we will require the draw manager + * context when starting blender in background mode (specially true with + * scripts) we deferre the ghost initialization the most as possible + * so that it does not break anything that can run in headless mode (as in + * without display server attached). + **/ +static bool opengl_is_init = false; + +void WM_init_opengl(void) +{ + /* must be called only once */ + BLI_assert(opengl_is_init == false); + + if (G.background) { + /* Ghost is still not init elsewhere in background mode. */ + wm_ghost_init(NULL); + } + + /* Needs to be first to have an ogl context bound. */ + DRW_opengl_context_create(); + + GPU_init(); + GPU_set_mipmap(true); + GPU_set_linear_mipmap(true); + GPU_set_anisotropic(U.anisotropic_filter); + GPU_set_gpu_mipmapping(U.use_gpu_mipmap); + +#ifdef WITH_OPENSUBDIV + BKE_subsurf_osd_init(); +#endif + opengl_is_init = true; +} + /* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { @@ -162,6 +196,7 @@ void WM_init(bContext *C, int argc, const char **argv) wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); } + GHOST_CreateSystemPaths(); BKE_addon_pref_type_init(); @@ -200,7 +235,6 @@ void WM_init(bContext *C, int argc, const char **argv) /* get the default database, plus a wm */ wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL); - BLT_lang_set(NULL); @@ -210,18 +244,7 @@ void WM_init(bContext *C, int argc, const char **argv) /* sets 3D mouse deadzone */ WM_ndof_deadzone_set(U.ndof_deadzone); #endif - DRW_opengl_context_create(); - - GPU_init(); - - GPU_set_mipmap(true); - GPU_set_linear_mipmap(true); - GPU_set_anisotropic(U.anisotropic_filter); - GPU_set_gpu_mipmapping(U.use_gpu_mipmap); - -#ifdef WITH_OPENSUBDIV - BKE_subsurf_osd_init(); -#endif + WM_init_opengl(); UI_init(); } @@ -456,7 +479,7 @@ void WM_exit_ext(bContext *C, const bool do_python) COM_deinitialize(); #endif - if (!G.background) { + if (opengl_is_init) { #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_cleanup(); #endif @@ -483,7 +506,7 @@ void WM_exit_ext(bContext *C, const bool do_python) BLF_exit(); - if (!G.background) { + if (opengl_is_init) { GPU_pass_cache_free(); DRW_opengl_context_destroy(); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 85c2b5cdf7b..4efca37b921 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1735,13 +1735,22 @@ void wm_window_testbreak(void) /* **************** init ********************** */ +/* bContext can be null in background mode because we don't + * need to event handling. */ void wm_ghost_init(bContext *C) { if (!g_system) { - GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, C); + GHOST_EventConsumerHandle consumer; + + if (C != NULL) { + consumer = GHOST_CreateEventConsumer(ghost_event_proc, C); + } g_system = GHOST_CreateSystem(); - GHOST_AddEventConsumer(g_system, consumer); + + if (C != NULL) { + GHOST_AddEventConsumer(g_system, consumer); + } if (wm_init_state.native_pixels) { GHOST_UseNativePixels(); |