diff --git a/CMakeLists.txt b/CMakeLists.txt index f72521266aa..f59a849cbf8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -536,10 +536,6 @@ mark_as_advanced( WITH_GPU_BUILDTIME_SHADER_BUILDER ) -if(WITH_HEADLESS) - set(WITH_OPENGL OFF) -endif() - # Metal if(APPLE) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 84b68014e91..099785bafa8 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -103,42 +103,39 @@ if(WITH_INPUT_NDOF) ) endif() -if(WITH_HEADLESS OR WITH_GHOST_SDL) - if(WITH_HEADLESS) - list(APPEND SRC - intern/GHOST_DisplayManagerNULL.h - intern/GHOST_SystemNULL.h - intern/GHOST_WindowNULL.h +list(APPEND SRC + intern/GHOST_DisplayManagerNULL.h + intern/GHOST_SystemHeadless.h + intern/GHOST_WindowNULL.h +) + +if(WITH_HEADLESS) + add_definitions(-DWITH_HEADLESS) +elseif (WITH_GHOST_SDL) + list(APPEND SRC + intern/GHOST_ContextSDL.cpp + intern/GHOST_DisplayManagerSDL.cpp + intern/GHOST_SystemSDL.cpp + intern/GHOST_WindowSDL.cpp + + intern/GHOST_ContextSDL.h + intern/GHOST_DisplayManagerSDL.h + intern/GHOST_SystemSDL.h + intern/GHOST_WindowSDL.h + ) + add_definitions(-DWITH_GHOST_SDL) + + list(APPEND INC_SYS + ${SDL_INCLUDE_DIR} + ) + if(WITH_SDL_DYNLOAD) + list(APPEND LIB + extern_sdlew ) - add_definitions(-DWITH_HEADLESS) else() - list(APPEND SRC - intern/GHOST_ContextSDL.cpp - intern/GHOST_DisplayManagerSDL.cpp - intern/GHOST_SystemSDL.cpp - intern/GHOST_WindowSDL.cpp - - intern/GHOST_ContextSDL.h - intern/GHOST_DisplayManagerSDL.h - intern/GHOST_SystemSDL.h - intern/GHOST_WindowSDL.h + list(APPEND LIB + ${SDL_LIBRARY} ) - add_definitions(-DWITH_GHOST_SDL) - endif() - - if(NOT WITH_HEADLESS) - list(APPEND INC_SYS - ${SDL_INCLUDE_DIR} - ) - if(WITH_SDL_DYNLOAD) - list(APPEND LIB - extern_sdlew - ) - else() - list(APPEND LIB - ${SDL_LIBRARY} - ) - endif() endif() elseif(APPLE AND NOT WITH_GHOST_X11) @@ -449,7 +446,7 @@ elseif(WIN32) endif() endif() -if(NOT (WITH_HEADLESS OR WITH_GHOST_SDL)) +if(UNIX AND NOT APPLE) list(APPEND SRC intern/GHOST_ContextEGL.cpp diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 4cbc0d65b11..f01f439718f 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -27,6 +27,7 @@ typedef bool (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserD * \return a handle to the system. */ extern GHOST_SystemHandle GHOST_CreateSystem(void); +extern GHOST_SystemHandle GHOST_CreateSystemBackground(void); /** * Specifies whether debug messages are to be enabled for the specific system handle. diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 89878a6d6a1..0dd855bb513 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -120,6 +120,7 @@ class GHOST_ISystem { * \return An indication of success. */ static GHOST_TSuccess createSystem(); + static GHOST_TSuccess createSystemBackground(); /** * Disposes the one and only system. diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 65e7de707ec..62e1e470010 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -30,6 +30,14 @@ GHOST_SystemHandle GHOST_CreateSystem(void) return (GHOST_SystemHandle)system; } +GHOST_SystemHandle GHOST_CreateSystemBackground(void) +{ + GHOST_ISystem::createSystemBackground(); + GHOST_ISystem *system = GHOST_ISystem::getSystem(); + + return (GHOST_SystemHandle)system; +} + void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, GHOST_Debug debug) { GHOST_ISystem *system = (GHOST_ISystem *)systemhandle; diff --git a/intern/ghost/intern/GHOST_ContextEGL.cpp b/intern/ghost/intern/GHOST_ContextEGL.cpp index 75c2655531f..6de161fda2a 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.cpp +++ b/intern/ghost/intern/GHOST_ContextEGL.cpp @@ -334,14 +334,35 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext() EGLSurface prev_read = eglGetCurrentSurface(EGL_READ); EGLContext prev_context = eglGetCurrentContext(); - EGLint egl_major, egl_minor; + EGLint egl_major = 0, egl_minor = 0; if (!EGL_CHK((m_display = ::eglGetDisplay(m_nativeDisplay)) != EGL_NO_DISPLAY)) { goto error; } - if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) { - goto error; + if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor)) || + (egl_major == 0 && egl_minor == 0)) { + /* We failed to create a regular render window, retry and see if we can create a headless + * render context. */ + ::eglTerminate(m_display); + + const char *egl_extension_st = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + assert(egl_extension_st != nullptr); + assert(strstr(egl_extension_st, "EGL_MESA_platform_surfaceless") != nullptr); + if (egl_extension_st == nullptr || + strstr(egl_extension_st, "EGL_MESA_platform_surfaceless") == nullptr) { + goto error; + } + + m_display = eglGetPlatformDisplayEXT( + EGL_PLATFORM_SURFACELESS_MESA, EGL_DEFAULT_DISPLAY, nullptr); + + if (!EGL_CHK(::eglInitialize(m_display, &egl_major, &egl_minor))) { + goto error; + } + /* Because the first eglInitialize will print an error to the terminal, print a "success" + * message here to let the user know that we successfully recovered from the error. */ + fprintf(stderr, "\nManaged to successfully fallback to surfaceless EGL rendering!\n\n"); } #ifdef WITH_GHOST_DEBUG fprintf(stderr, "EGL Version %d.%d\n", egl_major, egl_minor); diff --git a/intern/ghost/intern/GHOST_DisplayManagerNULL.h b/intern/ghost/intern/GHOST_DisplayManagerNULL.h index ba72dcbe8dd..9adbe17c532 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerNULL.h +++ b/intern/ghost/intern/GHOST_DisplayManagerNULL.h @@ -8,38 +8,41 @@ #pragma once #include "GHOST_DisplayManager.h" -#include "GHOST_SystemNULL.h" +#include "GHOST_SystemHeadless.h" -class GHOST_SystemNULL; +class GHOST_SystemHeadless; class GHOST_DisplayManagerNULL : public GHOST_DisplayManager { public: - GHOST_DisplayManagerNULL(GHOST_SystemNULL *system) : GHOST_DisplayManager(), m_system(system) + GHOST_DisplayManagerNULL(GHOST_SystemHeadless *system) : GHOST_DisplayManager(), m_system(system) { /* nop */ } - GHOST_TSuccess getNumDisplays(uint8_t &numDisplays) const + GHOST_TSuccess getNumDisplays(uint8_t & /*numDisplays*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getNumDisplaySettings(uint8_t display, int32_t &numSettings) const + GHOST_TSuccess getNumDisplaySettings(uint8_t /*display*/, + int32_t & /*numSettings*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getDisplaySetting(uint8_t display, - int32_t index, - GHOST_DisplaySetting &setting) const + GHOST_TSuccess getDisplaySetting(uint8_t /*display*/, + int32_t /*index*/, + GHOST_DisplaySetting & /*setting*/) const override { return GHOST_kFailure; } - GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, GHOST_DisplaySetting &setting) const + GHOST_TSuccess getCurrentDisplaySetting(uint8_t display, + GHOST_DisplaySetting &setting) const override { return getDisplaySetting(display, int32_t(0), setting); } - GHOST_TSuccess setCurrentDisplaySetting(uint8_t display, const GHOST_DisplaySetting &setting) + GHOST_TSuccess setCurrentDisplaySetting(uint8_t /*display*/, + const GHOST_DisplaySetting & /*setting*/) override { return GHOST_kSuccess; } private: - GHOST_SystemNULL *m_system; + GHOST_SystemHeadless *m_system; }; diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp index 4f6a9531077..03bdcd2fc82 100644 --- a/intern/ghost/intern/GHOST_ISystem.cpp +++ b/intern/ghost/intern/GHOST_ISystem.cpp @@ -9,14 +9,14 @@ * Copyright (C) 2001 NaN Technologies B.V. */ -#include "GHOST_ISystem.h" +#include -#if defined(WITH_HEADLESS) -# include "GHOST_SystemNULL.h" -#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) +#include "GHOST_ISystem.h" +#include "GHOST_SystemHeadless.h" + +#if defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) # include "GHOST_SystemWayland.h" # include "GHOST_SystemX11.h" -# include #elif defined(WITH_GHOST_X11) # include "GHOST_SystemX11.h" #elif defined(WITH_GHOST_WAYLAND) @@ -49,26 +49,50 @@ GHOST_TSuccess GHOST_ISystem::createSystem() #endif #if defined(WITH_HEADLESS) - m_system = new GHOST_SystemNULL(); + /* Pass. */ #elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND) /* Special case, try Wayland, fall back to X11. */ try { m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; } catch (const std::runtime_error &) { - /* fallback to X11. */ delete m_system; m_system = nullptr; } if (!m_system) { - m_system = new GHOST_SystemX11(); + /* Try to fallback to X11. */ + try { + m_system = new GHOST_SystemX11(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } } #elif defined(WITH_GHOST_X11) - m_system = new GHOST_SystemX11(); + try { + m_system = new GHOST_SystemX11(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WITH_GHOST_WAYLAND) - m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; + try { + m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr; + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WITH_GHOST_SDL) - m_system = new GHOST_SystemSDL(); + try { + m_system = new GHOST_SystemSDL(); + } + catch (const std::runtime_error &) { + delete m_system; + m_system = nullptr; + } #elif defined(WIN32) m_system = new GHOST_SystemWin32(); #elif defined(__APPLE__) @@ -85,6 +109,30 @@ GHOST_TSuccess GHOST_ISystem::createSystem() return success; } +GHOST_TSuccess GHOST_ISystem::createSystemBackground() +{ + GHOST_TSuccess success; + if (!m_system) { +#if !defined(WITH_HEADLESS) + /* Try to create a offscreen render surface with the graphical systems. */ + success = createSystem(); + if (success) { + return success; + } + /* Try to fallback to headless mode if all else fails. */ +#endif + m_system = new GHOST_SystemHeadless(); + success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure; + } + else { + success = GHOST_kFailure; + } + if (success) { + success = m_system->init(); + } + return success; +} + GHOST_TSuccess GHOST_ISystem::disposeSystem() { GHOST_TSuccess success = GHOST_kSuccess; diff --git a/intern/ghost/intern/GHOST_SystemHeadless.h b/intern/ghost/intern/GHOST_SystemHeadless.h new file mode 100644 index 00000000000..5c5382d6a23 --- /dev/null +++ b/intern/ghost/intern/GHOST_SystemHeadless.h @@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup GHOST + * Declaration of GHOST_SystemHeadless class. + */ + +#pragma once + +#include "../GHOST_Types.h" +#include "GHOST_DisplayManagerNULL.h" +#include "GHOST_System.h" +#include "GHOST_WindowNULL.h" + +#ifdef __linux__ +# include "GHOST_ContextEGL.h" +#endif +#include "GHOST_ContextNone.h" + +class GHOST_WindowNULL; + +class GHOST_SystemHeadless : public GHOST_System { + public: + GHOST_SystemHeadless() : GHOST_System() + { /* nop */ + } + ~GHOST_SystemHeadless() override = default; + + bool processEvents(bool /*waitForEvent*/) override + { + return false; + } + int setConsoleWindowState(GHOST_TConsoleWindowState /*action*/) override + { + return 0; + } + GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys & /*keys*/) const override + { + return GHOST_kSuccess; + } + GHOST_TSuccess getButtons(GHOST_Buttons & /*buttons*/) const override + { + return GHOST_kSuccess; + } + char *getClipboard(bool /*selection*/) const override + { + return nullptr; + } + void putClipboard(const char * /*buffer*/, bool /*selection*/) const override + { /* nop */ + } + uint64_t getMilliSeconds() const override + { + return 0; + } + uint8_t getNumDisplays() const override + { + return uint8_t(1); + } + GHOST_TSuccess getCursorPosition(int32_t & /*x*/, int32_t & /*y*/) const override + { + return GHOST_kFailure; + } + GHOST_TSuccess setCursorPosition(int32_t /*x*/, int32_t /*y*/) override + { + return GHOST_kFailure; + } + void getMainDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override + { /* nop */ + } + void getAllDisplayDimensions(uint32_t & /*width*/, uint32_t & /*height*/) const override + { /* nop */ + } + GHOST_IContext *createOffscreenContext(GHOST_GLSettings /*glSettings*/) override + { +#ifdef __linux__ + GHOST_Context *context; + for (int minor = 6; minor >= 0; --minor) { + context = new GHOST_ContextEGL((GHOST_System *)this, + false, + EGLNativeWindowType(0), + EGLNativeDisplayType(EGL_DEFAULT_DISPLAY), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + 4, + minor, + GHOST_OPENGL_EGL_CONTEXT_FLAGS, + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext()) { + return context; + } + delete context; + context = nullptr; + } + + context = new GHOST_ContextEGL((GHOST_System *)this, + false, + EGLNativeWindowType(0), + EGLNativeDisplayType(EGL_DEFAULT_DISPLAY), + EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + 3, + 3, + GHOST_OPENGL_EGL_CONTEXT_FLAGS, + GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY, + EGL_OPENGL_API); + + if (context->initializeDrawingContext() != GHOST_kSuccess) { + delete context; + context = nullptr; + } + return context; +#else + return nullptr; +#endif + } + GHOST_TSuccess disposeContext(GHOST_IContext *context) override + { + delete context; + + return GHOST_kSuccess; + } + + GHOST_TSuccess init() override + { + GHOST_TSuccess success = GHOST_System::init(); + + if (success) { + m_displayManager = new GHOST_DisplayManagerNULL(this); + + if (m_displayManager) { + return GHOST_kSuccess; + } + } + + return GHOST_kFailure; + } + + GHOST_IWindow *createWindow(const char *title, + int32_t left, + int32_t top, + uint32_t width, + uint32_t height, + GHOST_TWindowState state, + GHOST_TDrawingContextType type, + GHOST_GLSettings glSettings, + const bool /*exclusive*/, + const bool /*is_dialog*/, + const GHOST_IWindow *parentWindow) override + { + return new GHOST_WindowNULL(this, + title, + left, + top, + width, + height, + state, + parentWindow, + type, + ((glSettings.flags & GHOST_glStereoVisual) != 0)); + } + + GHOST_IWindow *getWindowUnderCursor(int32_t /*x*/, int32_t /*y*/) override + { + return nullptr; + } +}; diff --git a/intern/ghost/intern/GHOST_SystemNULL.h b/intern/ghost/intern/GHOST_SystemNULL.h deleted file mode 100644 index 644eb1ba0a5..00000000000 --- a/intern/ghost/intern/GHOST_SystemNULL.h +++ /dev/null @@ -1,122 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup GHOST - * Declaration of GHOST_SystemNULL class. - */ - -#pragma once - -#include "../GHOST_Types.h" -#include "GHOST_DisplayManagerNULL.h" -#include "GHOST_System.h" -#include "GHOST_WindowNULL.h" - -class GHOST_WindowNULL; - -class GHOST_SystemNULL : public GHOST_System { - public: - GHOST_SystemNULL() : GHOST_System() - { /* nop */ - } - ~GHOST_SystemNULL() - { /* nop */ - } - bool processEvents(bool waitForEvent) - { - return false; - } - int setConsoleWindowState(GHOST_TConsoleWindowState action) - { - return 0; - } - GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const - { - return GHOST_kSuccess; - } - GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const - { - return GHOST_kSuccess; - } - char *getClipboard(bool selection) const - { - return nullptr; - } - void putClipboard(const char *buffer, bool selection) const - { /* nop */ - } - uint64_t getMilliSeconds() const - { - return 0; - } - uint8_t getNumDisplays() const - { - return uint8_t(1); - } - GHOST_TSuccess getCursorPosition(int32_t &x, int32_t &y) const - { - return GHOST_kFailure; - } - GHOST_TSuccess setCursorPosition(int32_t x, int32_t y) - { - return GHOST_kFailure; - } - void getMainDisplayDimensions(uint32_t &width, uint32_t &height) const - { /* nop */ - } - void getAllDisplayDimensions(uint32_t &width, uint32_t &height) const - { /* nop */ - } - GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) - { - return nullptr; - } - GHOST_TSuccess disposeContext(GHOST_IContext *context) - { - return GHOST_kFailure; - } - - GHOST_TSuccess init() - { - GHOST_TSuccess success = GHOST_System::init(); - - if (success) { - m_displayManager = new GHOST_DisplayManagerNULL(this); - - if (m_displayManager) { - return GHOST_kSuccess; - } - } - - return GHOST_kFailure; - } - - GHOST_IWindow *createWindow(const char *title, - int32_t left, - int32_t top, - uint32_t width, - uint32_t height, - GHOST_TWindowState state, - GHOST_TDrawingContextType type, - GHOST_GLSettings glSettings, - const bool exclusive, - const bool is_dialog, - const GHOST_IWindow *parentWindow) - { - return new GHOST_WindowNULL(this, - title, - left, - top, - width, - height, - state, - parentWindow, - type, - ((glSettings.flags & GHOST_glStereoVisual) != 0)); - } - - GHOST_IWindow *getWindowUnderCursor(int32_t x, int32_t y) - { - return nullptr; - } -}; diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp index d912b57f049..6d0b2b8aa55 100644 --- a/intern/ghost/intern/GHOST_SystemSDL.cpp +++ b/intern/ghost/intern/GHOST_SystemSDL.cpp @@ -5,6 +5,7 @@ */ #include +#include #include "GHOST_ContextSDL.h" #include "GHOST_SystemSDL.h" @@ -20,7 +21,7 @@ GHOST_SystemSDL::GHOST_SystemSDL() : GHOST_System() { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) != 0) { - printf("Error initializing SDL: %s\n", SDL_GetError()); + throw std::runtime_error("Error initializing SDL: " + std::string(SDL_GetError())); } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 18660b3346a..bb98c0de19b 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -101,8 +101,7 @@ GHOST_SystemX11::GHOST_SystemX11() : GHOST_System(), m_xkb_descr(nullptr), m_sta m_display = XOpenDisplay(nullptr); if (!m_display) { - std::cerr << "Unable to open a display" << std::endl; - abort(); /* was return before, but this would just mean it will crash later */ + throw std::runtime_error("X11: Unable to open a display"); } #ifdef USE_X11_ERROR_HANDLERS diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index 01b50251d69..cfc73d4e783 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -11,24 +11,24 @@ #include -class GHOST_SystemNULL; +class GHOST_SystemHeadless; class GHOST_WindowNULL : public GHOST_Window { public: - GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor) + GHOST_TSuccess hasCursorShape(GHOST_TStandardCursor /*cursorShape*/) override { return GHOST_kSuccess; } - GHOST_WindowNULL(GHOST_SystemNULL *system, + GHOST_WindowNULL(GHOST_SystemHeadless *system, const char *title, - int32_t left, - int32_t top, + int32_t /*left*/, + int32_t /*top*/, uint32_t width, uint32_t height, GHOST_TWindowState state, - const GHOST_IWindow *parentWindow, - GHOST_TDrawingContextType type, + const GHOST_IWindow * /*parentWindow*/, + GHOST_TDrawingContextType /*type*/, const bool stereoVisual) : GHOST_Window(width, height, state, stereoVisual, false), m_system(system) { @@ -36,7 +36,7 @@ class GHOST_WindowNULL : public GHOST_Window { } protected: - GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type) + GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType /*type*/) { return GHOST_kSuccess; } @@ -44,114 +44,113 @@ class GHOST_WindowNULL : public GHOST_Window { { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode) + GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode /*mode*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape) + GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor /*shape*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setWindowCustomCursorShape(uint8_t *bitmap, - uint8_t *mask, - int sizex, - int sizey, - int hotX, - int hotY, - bool canInvertColor) + GHOST_TSuccess setWindowCustomCursorShape(uint8_t * /*bitmap*/, + uint8_t * /*mask*/, + int /*sizex*/, + int /*sizey*/, + int /*hotX*/, + int /*hotY*/, + bool /*canInvertColor*/) override { return GHOST_kSuccess; } - bool getValid() const + bool getValid() const override { return true; } - void setTitle(const char *title) + void setTitle(const char * /*title*/) override { /* nothing */ } - std::string getTitle() const + std::string getTitle() const override { return "untitled"; } - void getWindowBounds(GHOST_Rect &bounds) const + void getWindowBounds(GHOST_Rect &bounds) const override { getClientBounds(bounds); } - void getClientBounds(GHOST_Rect &bounds) const + void getClientBounds(GHOST_Rect & /*bounds*/) const override { /* nothing */ } - GHOST_TSuccess setClientWidth(uint32_t width) + GHOST_TSuccess setClientWidth(uint32_t /*width*/) override { return GHOST_kFailure; } - GHOST_TSuccess setClientHeight(uint32_t height) + GHOST_TSuccess setClientHeight(uint32_t /*height*/) override { return GHOST_kFailure; } - GHOST_TSuccess setClientSize(uint32_t width, uint32_t height) + GHOST_TSuccess setClientSize(uint32_t /*width*/, uint32_t /*height*/) override { return GHOST_kFailure; } - void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const + void screenToClient(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override { outX = inX; outY = inY; } - void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const + void clientToScreen(int32_t inX, int32_t inY, int32_t &outX, int32_t &outY) const override { outX = inX; outY = inY; } - GHOST_TSuccess swapBuffers() + GHOST_TSuccess swapBuffers() override { return GHOST_kFailure; } - GHOST_TSuccess activateDrawingContext() + GHOST_TSuccess activateDrawingContext() override { return GHOST_kFailure; } - ~GHOST_WindowNULL() - { /* nothing */ - } - GHOST_TSuccess setWindowCursorVisibility(bool visible) + ~GHOST_WindowNULL() override = default; + + GHOST_TSuccess setWindowCursorVisibility(bool /*visible*/) override { return GHOST_kSuccess; } - GHOST_TSuccess setState(GHOST_TWindowState state) + GHOST_TSuccess setState(GHOST_TWindowState /*state*/) override { return GHOST_kSuccess; } - GHOST_TWindowState getState() const + GHOST_TWindowState getState() const override { return GHOST_kWindowStateNormal; } - GHOST_TSuccess invalidate() + GHOST_TSuccess invalidate() override { return GHOST_kSuccess; } - GHOST_TSuccess setOrder(GHOST_TWindowOrder order) + GHOST_TSuccess setOrder(GHOST_TWindowOrder /*order*/) override { return GHOST_kSuccess; } - GHOST_TSuccess beginFullScreen() const + GHOST_TSuccess beginFullScreen() const override { return GHOST_kSuccess; } - GHOST_TSuccess endFullScreen() const + GHOST_TSuccess endFullScreen() const override { return GHOST_kSuccess; } private: - GHOST_SystemNULL *m_system; + GHOST_SystemHeadless *m_system; /** * \param type: The type of rendering context create. * \return Indication of success. */ - GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) + GHOST_Context *newDrawingContext(GHOST_TDrawingContextType /*type*/) override { return nullptr; } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 624e434e784..8163b39b3dd 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -166,7 +166,7 @@ void WM_init_opengl(void) if (G.background) { /* Ghost is still not initialized elsewhere in background mode. */ - wm_ghost_init(NULL); + wm_ghost_init_background(); } if (!GPU_backend_supported()) { diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 0c31ff87fdd..a4dba7145bd 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1558,36 +1558,55 @@ void wm_window_process_events(const bContext *C) void wm_ghost_init(bContext *C) { - if (!g_system) { - GHOST_EventConsumerHandle consumer; - - if (C != NULL) { - consumer = GHOST_CreateEventConsumer(ghost_event_proc, C); - } - - GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace); - - g_system = GHOST_CreateSystem(); - - GHOST_Debug debug = {0}; - if (G.debug & G_DEBUG_GHOST) { - debug.flags |= GHOST_kDebugDefault; - } - if (G.debug & G_DEBUG_WINTAB) { - debug.flags |= GHOST_kDebugWintab; - } - GHOST_SystemInitDebug(g_system, debug); - - if (C != NULL) { - GHOST_AddEventConsumer(g_system, consumer); - } - - if (wm_init_state.native_pixels) { - GHOST_UseNativePixels(); - } - - GHOST_UseWindowFocus(wm_init_state.window_focus); + if (g_system) { + return; } + + BLI_assert(C != NULL); + BLI_assert_msg(!G.background, "Use wm_ghost_init_background instead"); + + GHOST_EventConsumerHandle consumer; + + consumer = GHOST_CreateEventConsumer(ghost_event_proc, C); + + GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace); + + g_system = GHOST_CreateSystem(); + + GHOST_Debug debug = {0}; + if (G.debug & G_DEBUG_GHOST) { + debug.flags |= GHOST_kDebugDefault; + } + if (G.debug & G_DEBUG_WINTAB) { + debug.flags |= GHOST_kDebugWintab; + } + GHOST_SystemInitDebug(g_system, debug); + + GHOST_AddEventConsumer(g_system, consumer); + + if (wm_init_state.native_pixels) { + GHOST_UseNativePixels(); + } + + GHOST_UseWindowFocus(wm_init_state.window_focus); +} + +/* TODO move this to wm_init_exit.c. */ +void wm_ghost_init_background(void) +{ + if (g_system) { + return; + } + + GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace); + + g_system = GHOST_CreateSystemBackground(); + + GHOST_Debug debug = {0}; + if (G.debug & G_DEBUG_GHOST) { + debug.flags |= GHOST_kDebugDefault; + } + GHOST_SystemInitDebug(g_system, debug); } void wm_ghost_exit(void) diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index 3644aa085f7..036a34a5140 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -20,6 +20,7 @@ extern "C" { * need to event handling. */ void wm_ghost_init(bContext *C); +void wm_ghost_init_background(void); void wm_ghost_exit(void); /**