This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/intern/ghost/intern/GHOST_ISystem.cpp
Campbell Barton ca0f4f8c5c Fix crash on exit when background rendering in wayland
Disable libdecor Wayland requirement which would use an X11 fallback.

While the crash could be investigated, using libdecor at all makes
no sense in background mode.
2022-10-23 14:07:22 +11:00

213 lines
5.2 KiB
C++

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2001-2002 NaN Holding BV. All rights reserved. */
/** \file
* \ingroup GHOST
*/
/**
* Copyright (C) 2001 NaN Technologies B.V.
*/
#include <stdexcept>
#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"
#elif defined(WITH_GHOST_X11)
# include "GHOST_SystemX11.h"
#elif defined(WITH_GHOST_WAYLAND)
# include "GHOST_SystemWayland.h"
#elif defined(WITH_GHOST_SDL)
# include "GHOST_SystemSDL.h"
#elif defined(WIN32)
# include "GHOST_SystemWin32.h"
#elif defined(__APPLE__)
# include "GHOST_SystemCocoa.h"
#endif
GHOST_ISystem *GHOST_ISystem::m_system = nullptr;
const char *GHOST_ISystem::m_system_backend_id = nullptr;
GHOST_TBacktraceFn GHOST_ISystem::m_backtrace_fn = nullptr;
GHOST_TSuccess GHOST_ISystem::createSystem(bool verbose, [[maybe_unused]] bool background)
{
/* 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) {
#if defined(WITH_HEADLESS)
/* Pass. */
#elif defined(WITH_GHOST_WAYLAND)
# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
const bool has_wayland_libraries = ghost_wl_dynload_libraries_init();
# else
const bool has_wayland_libraries = true;
# endif
#endif
#if defined(WITH_HEADLESS)
/* Pass. */
#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
/* Special case, try Wayland, fall back to X11. */
if (has_wayland_libraries) {
backends_attempted[backends_attempted_num++] = "WAYLAND";
try {
m_system = new GHOST_SystemWayland(background);
}
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
ghost_wl_dynload_libraries_exit();
# endif
}
}
else {
m_system = nullptr;
}
if (!m_system) {
/* Try to fallback to X11. */
backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
}
}
#elif defined(WITH_GHOST_X11)
backends_attempted[backends_attempted_num++] = "X11";
try {
m_system = new GHOST_SystemX11();
}
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
}
#elif defined(WITH_GHOST_WAYLAND)
if (has_wayland_libraries) {
backends_attempted[backends_attempted_num++] = "WAYLAND";
try {
m_system = new GHOST_SystemWayland(background);
}
catch (const std::runtime_error &) {
delete m_system;
m_system = nullptr;
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
ghost_wl_dynload_libraries_exit();
# endif
}
}
else {
m_system = nullptr;
}
#elif defined(WITH_GHOST_SDL)
backends_attempted[backends_attempted_num++] = "SDL";
try {
m_system = new GHOST_SystemSDL();
}
catch (const std::runtime_error &) {
delete m_system;
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) {
m_system_backend_id = backends_attempted[backends_attempted_num - 1];
}
else if (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 {
success = GHOST_kFailure;
}
if (success) {
success = m_system->init();
}
return success;
}
GHOST_TSuccess GHOST_ISystem::createSystemBackground()
{
GHOST_TSuccess success;
if (!m_system) {
#if !defined(WITH_HEADLESS)
/* Try to create a off-screen render surface with the graphical systems. */
success = createSystem(false, true);
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;
if (m_system) {
delete m_system;
m_system = nullptr;
}
else {
success = GHOST_kFailure;
}
return success;
}
GHOST_ISystem *GHOST_ISystem::getSystem()
{
return m_system;
}
const char *GHOST_ISystem::getSystemBackend()
{
return m_system_backend_id;
}
GHOST_TBacktraceFn GHOST_ISystem::getBacktraceFn()
{
return GHOST_ISystem::m_backtrace_fn;
}
void GHOST_ISystem::setBacktraceFn(GHOST_TBacktraceFn backtrace_fn)
{
GHOST_ISystem::m_backtrace_fn = backtrace_fn;
}