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).
This commit is contained in:
@@ -1361,6 +1361,11 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph)
|
|||||||
DrawEngineType *draw_engine_type = engine_type->draw_engine;
|
DrawEngineType *draw_engine_type = engine_type->draw_engine;
|
||||||
RenderData *r = &scene->r;
|
RenderData *r = &scene->r;
|
||||||
Render *render = engine->re;
|
Render *render = engine->re;
|
||||||
|
|
||||||
|
if (G.background && DST.ogl_context == NULL) {
|
||||||
|
WM_init_opengl();
|
||||||
|
}
|
||||||
|
|
||||||
/* Changing Context */
|
/* Changing Context */
|
||||||
DRW_opengl_context_enable();
|
DRW_opengl_context_enable();
|
||||||
/* IMPORTANT: We dont support immediate mode in render mode!
|
/* 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_assert(DST.ogl_context == NULL); /* Ensure it's called once */
|
||||||
|
|
||||||
BLI_mutex_init(&DST.ogl_context_mutex);
|
BLI_mutex_init(&DST.ogl_context_mutex);
|
||||||
|
if (!G.background) {
|
||||||
immDeactivate();
|
immDeactivate();
|
||||||
|
}
|
||||||
/* This changes the active context. */
|
/* This changes the active context. */
|
||||||
DST.ogl_context = WM_opengl_context_create();
|
DST.ogl_context = WM_opengl_context_create();
|
||||||
/* Be sure to create gawain.context too. */
|
/* Be sure to create gawain.context too. */
|
||||||
DST.gwn_context = GWN_context_create();
|
DST.gwn_context = GWN_context_create();
|
||||||
immActivate();
|
if (!G.background) {
|
||||||
|
immActivate();
|
||||||
|
}
|
||||||
/* Set default Blender OpenGL state */
|
/* Set default Blender OpenGL state */
|
||||||
GPU_state_init();
|
GPU_state_init();
|
||||||
/* So we activate the window's one afterwards. */
|
/* So we activate the window's one afterwards. */
|
||||||
@@ -2082,12 +2090,16 @@ void DRW_opengl_context_enable(void)
|
|||||||
* multiple threads. */
|
* multiple threads. */
|
||||||
BLI_mutex_lock(&DST.ogl_context_mutex);
|
BLI_mutex_lock(&DST.ogl_context_mutex);
|
||||||
if (BLI_thread_is_main()) {
|
if (BLI_thread_is_main()) {
|
||||||
immDeactivate();
|
if (!G.background) {
|
||||||
|
immDeactivate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WM_opengl_context_activate(DST.ogl_context);
|
WM_opengl_context_activate(DST.ogl_context);
|
||||||
GWN_context_active_set(DST.gwn_context);
|
GWN_context_active_set(DST.gwn_context);
|
||||||
if (BLI_thread_is_main()) {
|
if (BLI_thread_is_main()) {
|
||||||
immActivate();
|
if (!G.background) {
|
||||||
|
immActivate();
|
||||||
|
}
|
||||||
BLF_batch_reset();
|
BLF_batch_reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ void GPU_init(void)
|
|||||||
|
|
||||||
gpu_batch_init();
|
gpu_batch_init();
|
||||||
|
|
||||||
immInit();
|
if (!G.background) {
|
||||||
|
immInit();
|
||||||
|
}
|
||||||
|
|
||||||
GPU_pbvh_fix_linking();
|
GPU_pbvh_fix_linking();
|
||||||
}
|
}
|
||||||
@@ -72,7 +74,9 @@ void GPU_init(void)
|
|||||||
|
|
||||||
void GPU_exit(void)
|
void GPU_exit(void)
|
||||||
{
|
{
|
||||||
immDestroy();
|
if (!G.background) {
|
||||||
|
immDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
gpu_batch_exit();
|
gpu_batch_exit();
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ void WM_main (struct bContext *C) ATTR_NORETURN;
|
|||||||
|
|
||||||
void WM_init_splash (struct bContext *C);
|
void WM_init_splash (struct bContext *C);
|
||||||
|
|
||||||
|
void WM_init_opengl (void);
|
||||||
|
|
||||||
void WM_check (struct bContext *C);
|
void WM_check (struct bContext *C);
|
||||||
|
|
||||||
|
|||||||
@@ -154,6 +154,40 @@ static void wm_free_reports(bContext *C)
|
|||||||
|
|
||||||
bool wm_start_with_console = false; /* used in creator.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 */
|
/* only called once, for startup */
|
||||||
void WM_init(bContext *C, int argc, const char **argv)
|
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_ghost_init(C); /* note: it assigns C to ghost! */
|
||||||
wm_init_cursor_data();
|
wm_init_cursor_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
GHOST_CreateSystemPaths();
|
GHOST_CreateSystemPaths();
|
||||||
|
|
||||||
BKE_addon_pref_type_init();
|
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 */
|
/* get the default database, plus a wm */
|
||||||
wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL);
|
wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL);
|
||||||
|
|
||||||
|
|
||||||
BLT_lang_set(NULL);
|
BLT_lang_set(NULL);
|
||||||
|
|
||||||
@@ -210,18 +244,7 @@ void WM_init(bContext *C, int argc, const char **argv)
|
|||||||
/* sets 3D mouse deadzone */
|
/* sets 3D mouse deadzone */
|
||||||
WM_ndof_deadzone_set(U.ndof_deadzone);
|
WM_ndof_deadzone_set(U.ndof_deadzone);
|
||||||
#endif
|
#endif
|
||||||
DRW_opengl_context_create();
|
WM_init_opengl();
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
UI_init();
|
UI_init();
|
||||||
}
|
}
|
||||||
@@ -456,7 +479,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
|
|||||||
COM_deinitialize();
|
COM_deinitialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!G.background) {
|
if (opengl_is_init) {
|
||||||
#ifdef WITH_OPENSUBDIV
|
#ifdef WITH_OPENSUBDIV
|
||||||
BKE_subsurf_osd_cleanup();
|
BKE_subsurf_osd_cleanup();
|
||||||
#endif
|
#endif
|
||||||
@@ -483,7 +506,7 @@ void WM_exit_ext(bContext *C, const bool do_python)
|
|||||||
|
|
||||||
BLF_exit();
|
BLF_exit();
|
||||||
|
|
||||||
if (!G.background) {
|
if (opengl_is_init) {
|
||||||
GPU_pass_cache_free();
|
GPU_pass_cache_free();
|
||||||
DRW_opengl_context_destroy();
|
DRW_opengl_context_destroy();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1735,13 +1735,22 @@ void wm_window_testbreak(void)
|
|||||||
|
|
||||||
/* **************** init ********************** */
|
/* **************** init ********************** */
|
||||||
|
|
||||||
|
/* bContext can be null in background mode because we don't
|
||||||
|
* need to event handling. */
|
||||||
void wm_ghost_init(bContext *C)
|
void wm_ghost_init(bContext *C)
|
||||||
{
|
{
|
||||||
if (!g_system) {
|
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();
|
g_system = GHOST_CreateSystem();
|
||||||
GHOST_AddEventConsumer(g_system, consumer);
|
|
||||||
|
if (C != NULL) {
|
||||||
|
GHOST_AddEventConsumer(g_system, consumer);
|
||||||
|
}
|
||||||
|
|
||||||
if (wm_init_state.native_pixels) {
|
if (wm_init_state.native_pixels) {
|
||||||
GHOST_UseNativePixels();
|
GHOST_UseNativePixels();
|
||||||
|
|||||||
Reference in New Issue
Block a user