[Bf-blender-cvs] [46bfdb48a19] blender2.8: WM: Add GHOST lazy init for background mode.

Clément Foucault noreply at git.blender.org
Wed Apr 25 17:43:26 CEST 2018


Commit: 46bfdb48a19335d7db2114c697ccca05cb0011af
Author: Clément Foucault
Date:   Wed Apr 25 17:43:08 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB46bfdb48a19335d7db2114c697ccca05cb0011af

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).

===================================================================

M	source/blender/draw/intern/draw_manager.c
M	source/blender/gpu/intern/gpu_init_exit.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_init_exit.c
M	source/blender/windowmanager/intern/wm_window.c

===================================================================

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();



More information about the Bf-blender-cvs mailing list