Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <campbell@blender.org>2022-09-27 10:05:08 +0300
committerCampbell Barton <campbell@blender.org>2022-09-27 10:14:32 +0300
commitb6a7541f87c5ed07634eb829af3abdb8239aca18 (patch)
treefc8fae83946c733b9fcecbc0509191fbe0a4a325
parent78952518e7c8fbb4a7866004d03f8004703f6934 (diff)
GHOST: exit with an error when GHOST cannot be initialized
When the GHOST back-end Blender was built with isn't supported, Blender would crash on startup without any useful information. This could happen when building X11 only, then running on Wayland. Now show a list of the GHOST back-ends that were attempted and exit with an error code instead of crashing.
-rw-r--r--intern/ghost/GHOST_ISystem.h3
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp2
-rw-r--r--intern/ghost/intern/GHOST_ISystem.cpp55
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c8
-rw-r--r--source/blender/windowmanager/intern/wm_window.c7
5 files changed, 63 insertions, 12 deletions
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index da6233456c3..05ed089809a 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -117,9 +117,10 @@ class GHOST_ISystem {
public:
/**
* Creates the one and only system.
+ * \param verbose: report back-ends that were attempted no back-end could be loaded.
* \return An indication of success.
*/
- static GHOST_TSuccess createSystem();
+ static GHOST_TSuccess createSystem(bool verbose);
static GHOST_TSuccess createSystemBackground();
/**
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 0026a33bfc2..69fc6b5f2d0 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -24,7 +24,7 @@
GHOST_SystemHandle GHOST_CreateSystem(void)
{
- GHOST_ISystem::createSystem();
+ GHOST_ISystem::createSystem(true);
GHOST_ISystem *system = GHOST_ISystem::getSystem();
return (GHOST_SystemHandle)system;
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 13eccf661f5..304d7f0abe6 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -33,8 +33,13 @@ GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
-GHOST_TSuccess GHOST_ISystem::createSystem()
+GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose)
{
+ /* When GHOST fails to start, report the back-ends that were attempted.
+ * A Verbose argument could be supported in printing isn't always desired. */
+ const char *backends_attempted[8] = {nullptr};
+ int backends_attempted_num = 0;
+
GHOST_TSuccess success;
if (!m_system) {
@@ -52,15 +57,23 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
/* 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;
+ if (has_wayland_libraries) {
+ backends_attempted[backends_attempted_num++] = "WAYLAND";
+ try {
+ m_system = new GHOST_SystemWayland();
+ }
+ catch (const std::runtime_error &) {
+ delete m_system;
+ m_system = nullptr;
+ }
}
- catch (const std::runtime_error &) {
- delete m_system;
+ else {
m_system = nullptr;
}
+
if (!m_system) {
/* Try to fallback to X11. */
+ backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
@@ -70,6 +83,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
}
}
#elif defined(WITH_GHOST_X11)
+ backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
@@ -78,14 +92,21 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = nullptr;
}
#elif defined(WITH_GHOST_WAYLAND)
- try {
- m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
+ if (has_wayland_libraries) {
+ backends_attempted[backends_attempted_num++] = "WAYLAND";
+ try {
+ m_system = new GHOST_SystemWayland();
+ }
+ catch (const std::runtime_error &) {
+ delete m_system;
+ m_system = nullptr;
+ }
}
- catch (const std::runtime_error &) {
- delete m_system;
+ else {
m_system = nullptr;
}
#elif defined(WITH_GHOST_SDL)
+ backends_attempted[backends_attempted_num++] = "SDL";
try {
m_system = new GHOST_SystemSDL();
}
@@ -94,10 +115,24 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
m_system = nullptr;
}
#elif defined(WIN32)
+ backends_attempted[backends_attempted_num++] = "WIN32";
m_system = new GHOST_SystemWin32();
#elif defined(__APPLE__)
+ backends_attempted[backends_attempted_num++] = "COCOA";
m_system = new GHOST_SystemCocoa();
#endif
+
+ if ((m_system == nullptr) && verbose) {
+ fprintf(stderr, "GHOST: failed to initialize display for back-end(s): [");
+ for (int i = 0; i < backends_attempted_num; i++) {
+ if (i != 0) {
+ fprintf(stderr, ", ");
+ }
+ fprintf(stderr, "'%s'", backends_attempted[i]);
+ }
+ fprintf(stderr, "]\n");
+ }
+
success = m_system != nullptr ? GHOST_kSuccess : GHOST_kFailure;
}
else {
@@ -115,7 +150,7 @@ GHOST_TSuccess GHOST_ISystem::createSystemBackground()
if (!m_system) {
#if !defined(WITH_HEADLESS)
/* Try to create a off-screen render surface with the graphical systems. */
- success = createSystem();
+ success = createSystem(false);
if (success) {
return success;
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index bb19ba4748f..bf793ee41a0 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1539,6 +1539,14 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
GHOST_SetBacktraceHandler((GHOST_TBacktraceFn)BLI_system_backtrace);
g_WS.ghost_system = GHOST_CreateSystem();
+
+ if (UNLIKELY(g_WS.ghost_system == NULL)) {
+ /* GHOST will have reported the back-ends that failed to load. */
+ fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+ /* This will leak memory, it's preferable to crashing. */
+ exit(1);
+ }
+
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
playanim_window_open("Blender Animation Player", start_x, start_y, ibuf->x, ibuf->y);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 89bf2b82426..a4f92da2774 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1546,6 +1546,13 @@ void wm_ghost_init(bContext *C)
g_system = GHOST_CreateSystem();
+ if (UNLIKELY(g_system == NULL)) {
+ /* GHOST will have reported the back-ends that failed to load. */
+ fprintf(stderr, "GHOST: unable to initialize, exiting!\n");
+ /* This will leak memory, it's preferable to crashing. */
+ exit(1);
+ }
+
GHOST_Debug debug = {0};
if (G.debug & G_DEBUG_GHOST) {
debug.flags |= GHOST_kDebugDefault;