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

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to