2
0
Эх сурвалжийг харах

Merge pull request #49074 from Faless/headless/ds

Rémi Verschelde 4 жил өмнө
parent
commit
0aabfb341a

+ 14 - 14
SConstruct

@@ -123,6 +123,7 @@ opts.Add(BoolVariable("use_lto", "Use link-time optimization", False))
 opts.Add(BoolVariable("deprecated", "Enable deprecated features", True))
 opts.Add(BoolVariable("minizip", "Enable ZIP archive support using minizip", True))
 opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False))
+opts.Add(BoolVariable("vulkan", "Enable the vulkan video driver", True))
 opts.Add("custom_modules", "A list of comma-separated directory paths containing custom modules to build.", "")
 opts.Add(BoolVariable("custom_modules_recursive", "Detect custom modules recursively for each specified path.", True))
 
@@ -665,20 +666,19 @@ if selected_platform in platform_list:
     if not env["verbose"]:
         methods.no_verbose(sys, env)
 
-    if not env["platform"] == "server":
-        GLSL_BUILDERS = {
-            "RD_GLSL": env.Builder(
-                action=env.Run(glsl_builders.build_rd_headers, 'Building RD_GLSL header: "$TARGET"'),
-                suffix="glsl.gen.h",
-                src_suffix=".glsl",
-            ),
-            "GLSL_HEADER": env.Builder(
-                action=env.Run(glsl_builders.build_raw_headers, 'Building GLSL header: "$TARGET"'),
-                suffix="glsl.gen.h",
-                src_suffix=".glsl",
-            ),
-        }
-        env.Append(BUILDERS=GLSL_BUILDERS)
+    GLSL_BUILDERS = {
+        "RD_GLSL": env.Builder(
+            action=env.Run(glsl_builders.build_rd_headers, 'Building RD_GLSL header: "$TARGET"'),
+            suffix="glsl.gen.h",
+            src_suffix=".glsl",
+        ),
+        "GLSL_HEADER": env.Builder(
+            action=env.Run(glsl_builders.build_raw_headers, 'Building GLSL header: "$TARGET"'),
+            suffix="glsl.gen.h",
+            src_suffix=".glsl",
+        ),
+    }
+    env.Append(BUILDERS=GLSL_BUILDERS)
 
     scons_cache_path = os.environ.get("SCONS_CACHE")
     if scons_cache_path != None:

+ 1 - 3
drivers/SCsub

@@ -23,10 +23,8 @@ SConscript("coremidi/SCsub")
 SConscript("winmidi/SCsub")
 
 # Graphics drivers
-if env["platform"] != "server" and env["platform"] != "javascript":
+if env["vulkan"]:
     SConscript("vulkan/SCsub")
-else:
-    SConscript("dummy/SCsub")
 
 # Core dependencies
 SConscript("png/SCsub")

+ 0 - 5
drivers/dummy/SCsub

@@ -1,5 +0,0 @@
-#!/usr/bin/env python
-
-Import("env")
-
-env.add_source_files(env.drivers_sources, "*.cpp")

+ 0 - 109
drivers/dummy/texture_loader_dummy.cpp

@@ -1,109 +0,0 @@
-/*************************************************************************/
-/*  texture_loader_dummy.cpp                                             */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "texture_loader_dummy.h"
-
-#include "core/os/file_access.h"
-#include "core/string/print_string.h"
-
-#include <string.h>
-
-RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
-	unsigned int width = 8;
-	unsigned int height = 8;
-
-	//We just use some format
-	Image::Format fmt = Image::FORMAT_RGB8;
-	int rowsize = 3 * width;
-
-	Vector<uint8_t> dstbuff;
-
-	dstbuff.resize(rowsize * height);
-
-	uint8_t **row_p = memnew_arr(uint8_t *, height);
-
-	for (unsigned int i = 0; i < height; i++) {
-		row_p[i] = 0; //No colors any more, I want them to turn black
-	}
-
-	memdelete_arr(row_p);
-
-	Ref<Image> img = memnew(Image(width, height, 0, fmt, dstbuff));
-
-	Ref<ImageTexture> texture = memnew(ImageTexture);
-	texture->create_from_image(img);
-
-	if (r_error)
-		*r_error = OK;
-
-	return texture;
-}
-
-void ResourceFormatDummyTexture::get_recognized_extensions(List<String> *p_extensions) const {
-	p_extensions->push_back("bmp");
-	p_extensions->push_back("dds");
-	p_extensions->push_back("exr");
-	p_extensions->push_back("jpeg");
-	p_extensions->push_back("jpg");
-	p_extensions->push_back("hdr");
-	p_extensions->push_back("pkm");
-	p_extensions->push_back("png");
-	p_extensions->push_back("pvr");
-	p_extensions->push_back("svg");
-	p_extensions->push_back("svgz");
-	p_extensions->push_back("tga");
-	p_extensions->push_back("webp");
-}
-
-bool ResourceFormatDummyTexture::handles_type(const String &p_type) const {
-	return ClassDB::is_parent_class(p_type, "Texture2D");
-}
-
-String ResourceFormatDummyTexture::get_resource_type(const String &p_path) const {
-	String extension = p_path.get_extension().to_lower();
-	if (
-			extension == "bmp" ||
-			extension == "dds" ||
-			extension == "exr" ||
-			extension == "jpeg" ||
-			extension == "jpg" ||
-			extension == "hdr" ||
-			extension == "pkm" ||
-			extension == "png" ||
-			extension == "pvr" ||
-			extension == "svg" ||
-			extension == "svgz" ||
-			extension == "tga" ||
-			extension == "webp") {
-		return "ImageTexture";
-	}
-
-	return "";
-}

+ 0 - 47
drivers/dummy/texture_loader_dummy.h

@@ -1,47 +0,0 @@
-/*************************************************************************/
-/*  texture_loader_dummy.h                                               */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef TEXTURE_LOADER_DUMMY_H
-#define TEXTURE_LOADER_DUMMY_H
-
-#include "core/io/resource_loader.h"
-#include "scene/resources/texture.h"
-
-class ResourceFormatDummyTexture : public ResourceFormatLoader {
-public:
-	virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
-	virtual void get_recognized_extensions(List<String> *p_extensions) const;
-	virtual bool handles_type(const String &p_type) const;
-	virtual String get_resource_type(const String &p_path) const;
-
-	virtual ~ResourceFormatDummyTexture() {}
-};
-
-#endif // TEXTURE_LOADER_DUMMY_H

+ 1 - 1
modules/text_server_adv/SCsub

@@ -131,7 +131,7 @@ if env["builtin_harfbuzz"]:
             ]
         )
 
-    if env["platform"] == "android" or env["platform"] == "linuxbsd" or env["platform"] == "server":
+    if env["platform"] == "android" or env["platform"] == "linuxbsd":
         env_harfbuzz.Append(CCFLAGS=["-DHAVE_PTHREAD"])
 
     if env["platform"] == "javascript":

+ 2 - 7
modules/webm/libvpx/SCsub

@@ -235,7 +235,7 @@ if env["platform"] == "uwp":
 else:
     import platform
 
-    is_x11_or_server_arm = (env["platform"] == "linuxbsd" or env["platform"] == "server") and (
+    is_x11_or_server_arm = env["platform"] == "linuxbsd" and (
         platform.machine().startswith("arm") or platform.machine().startswith("aarch")
     )
     is_macos_x86 = env["platform"] == "osx" and ("arch" in env and (env["arch"] != "arm64"))
@@ -314,12 +314,7 @@ if webm_cpu_x86:
 if webm_cpu_arm:
     if env["platform"] == "iphone":
         env_libvpx["ASFLAGS"] = "-arch armv7"
-    elif (
-        env["platform"] == "android"
-        and env["android_arch"] == "armv7"
-        or env["platform"] == "linuxbsd"
-        or env["platform"] == "server"
-    ):
+    elif env["platform"] == "android" and env["android_arch"] == "armv7" or env["platform"] == "linuxbsd":
         env_libvpx["ASFLAGS"] = "-mfpu=neon"
     elif env["platform"] == "uwp":
         env_libvpx["AS"] = "armasm"

+ 1 - 0
platform/javascript/detect.py

@@ -53,6 +53,7 @@ def get_flags():
         # in this platform. For the available networking methods, the browser
         # manages TLS.
         ("module_mbedtls_enabled", False),
+        ("vulkan", False),
     ]
 
 

+ 1 - 1
platform/javascript/display_server_javascript.cpp

@@ -30,8 +30,8 @@
 
 #include "platform/javascript/display_server_javascript.h"
 
-#include "drivers/dummy/rasterizer_dummy.h"
 #include "platform/javascript/os_javascript.h"
+#include "servers/rendering/rasterizer_dummy.h"
 
 #include <emscripten.h>
 #include <png.h>

+ 14 - 8
platform/linuxbsd/SCsub

@@ -5,21 +5,27 @@ Import("env")
 from platform_methods import run_in_subprocess
 import platform_linuxbsd_builders
 
-common_x11 = [
+common_linuxbsd = [
     "crash_handler_linuxbsd.cpp",
     "os_linuxbsd.cpp",
     "joypad_linux.cpp",
-    "context_gl_x11.cpp",
-    "detect_prime_x11.cpp",
-    "display_server_x11.cpp",
-    "vulkan_context_x11.cpp",
-    "key_mapping_x11.cpp",
 ]
 
+if "x11" in env and env["x11"]:
+    common_linuxbsd += [
+        "context_gl_x11.cpp",
+        "detect_prime_x11.cpp",
+        "display_server_x11.cpp",
+        "key_mapping_x11.cpp",
+    ]
+
+if "vulkan" in env and env["vulkan"]:
+    common_linuxbsd.append("vulkan_context_x11.cpp")
+
 if "udev" in env and env["udev"]:
-    common_x11.append("libudev-so_wrap.c")
+    common_linuxbsd.append("libudev-so_wrap.c")
 
-prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_x11)
+prog = env.add_program("#bin/godot", ["godot_linuxbsd.cpp"] + common_linuxbsd)
 
 if env["debug_symbols"] and env["separate_debug_symbols"]:
     env.AddPostAction(prog, run_in_subprocess(platform_linuxbsd_builders.make_debug_linuxbsd))

+ 18 - 9
platform/linuxbsd/detect.py

@@ -73,6 +73,7 @@ def get_opts():
         BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
         BoolVariable("pulseaudio", "Detect and use PulseAudio", True),
         BoolVariable("udev", "Use udev for gamepad connection callbacks", True),
+        BoolVariable("x11", "Enable X11 display", True),
         BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
         BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
         BoolVariable("touch", "Enable touch events", True),
@@ -362,18 +363,26 @@ def configure(env):
         env.ParseConfig("pkg-config zlib --cflags --libs")
 
     env.Prepend(CPPPATH=["#platform/linuxbsd"])
-    env.Append(CPPDEFINES=["X11_ENABLED", "UNIX_ENABLED"])
+
+    if env["x11"]:
+        if not env["vulkan"]:
+            print("Error: X11 support requires vulkan=yes")
+            env.Exit(255)
+        env.Append(CPPDEFINES=["X11_ENABLED"])
+
+    env.Append(CPPDEFINES=["UNIX_ENABLED"])
     env.Append(CPPDEFINES=[("_FILE_OFFSET_BITS", 64)])
 
-    env.Append(CPPDEFINES=["VULKAN_ENABLED"])
-    if not env["builtin_vulkan"]:
-        env.ParseConfig("pkg-config vulkan --cflags --libs")
-    if not env["builtin_glslang"]:
-        # No pkgconfig file for glslang so far
-        env.Append(LIBS=["glslang", "SPIRV"])
+    if env["vulkan"]:
+        env.Append(CPPDEFINES=["VULKAN_ENABLED"])
+        if not env["builtin_vulkan"]:
+            env.ParseConfig("pkg-config vulkan --cflags --libs")
+        if not env["builtin_glslang"]:
+            # No pkgconfig file for glslang so far
+            env.Append(LIBS=["glslang", "SPIRV"])
 
-    # env.Append(CPPDEFINES=['OPENGL_ENABLED'])
-    env.Append(LIBS=["GL"])
+        # env.Append(CPPDEFINES=['OPENGL_ENABLED'])
+        env.Append(LIBS=["GL"])
 
     env.Append(LIBS=["pthread"])
 

+ 0 - 16
platform/server/SCsub

@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-
-Import("env")
-
-common_server = [
-    "os_server.cpp",
-]
-
-if sys.platform == "darwin":
-    common_server.append("#platform/osx/crash_handler_osx.mm")
-else:
-    common_server.append("#platform/x11/crash_handler_x11.cpp")
-
-prog = env.add_program("#bin/godot_server", ["godot_server.cpp"] + common_server)

+ 0 - 296
platform/server/detect.py

@@ -1,296 +0,0 @@
-import os
-import platform
-import sys
-
-# This file is mostly based on platform/x11/detect.py.
-# If editing this file, make sure to apply relevant changes here too.
-
-
-def is_active():
-    return True
-
-
-def get_name():
-    return "Server"
-
-
-def get_program_suffix():
-    if sys.platform == "darwin":
-        return "osx"
-    return "linuxbsd"
-
-
-def can_build():
-    if os.name != "posix":
-        return False
-
-    return True
-
-
-def get_opts():
-    from SCons.Variables import BoolVariable, EnumVariable
-
-    return [
-        BoolVariable("use_llvm", "Use the LLVM compiler", False),
-        BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
-        BoolVariable("use_coverage", "Test Godot coverage", False),
-        BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
-        BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN)", False),
-        BoolVariable("use_lsan", "Use LLVM/GCC compiler leak sanitizer (LSAN)", False),
-        BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
-        BoolVariable("use_msan", "Use LLVM compiler memory sanitizer (MSAN)", False),
-        BoolVariable("debug_symbols", "Add debugging symbols to release/release_debug builds", True),
-        BoolVariable("separate_debug_symbols", "Create a separate file containing debugging symbols", False),
-        BoolVariable("execinfo", "Use libexecinfo on systems where glibc is not available", False),
-    ]
-
-
-def get_flags():
-    return []
-
-
-def configure(env):
-
-    ## Build type
-
-    if env["target"] == "release":
-        if env["optimize"] == "speed":  # optimize for speed (default)
-            env.Prepend(CCFLAGS=["-O3"])
-        elif env["optimize"] == "size":  # optimize for size
-            env.Prepend(CCFLAGS=["-Os"])
-
-        if env["debug_symbols"]:
-            env.Prepend(CCFLAGS=["-g2"])
-
-    elif env["target"] == "release_debug":
-        if env["optimize"] == "speed":  # optimize for speed (default)
-            env.Prepend(CCFLAGS=["-O2"])
-        elif env["optimize"] == "size":  # optimize for size
-            env.Prepend(CCFLAGS=["-Os"])
-        env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
-
-        if env["debug_symbols"]:
-            env.Prepend(CCFLAGS=["-g2"])
-
-    elif env["target"] == "debug":
-        env.Prepend(CCFLAGS=["-g3"])
-        env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
-        env.Append(LINKFLAGS=["-rdynamic"])
-
-    ## Architecture
-
-    is64 = sys.maxsize > 2 ** 32
-    if env["bits"] == "default":
-        env["bits"] = "64" if is64 else "32"
-
-    ## Compiler configuration
-
-    if "CXX" in env and "clang" in os.path.basename(env["CXX"]):
-        # Convenience check to enforce the use_llvm overrides when CXX is clang(++)
-        env["use_llvm"] = True
-
-    if env["use_llvm"]:
-        if "clang++" not in os.path.basename(env["CXX"]):
-            env["CC"] = "clang"
-            env["CXX"] = "clang++"
-        env.extra_suffix = ".llvm" + env.extra_suffix
-        env.Append(LIBS=["atomic"])
-
-    if env["use_coverage"]:
-        env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
-        env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"])
-
-    if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"] or env["use_msan"]:
-        env.extra_suffix += "s"
-
-        if env["use_ubsan"]:
-            env.Append(
-                CCFLAGS=[
-                    "-fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin"
-                ]
-            )
-            env.Append(LINKFLAGS=["-fsanitize=undefined"])
-            if env["use_llvm"]:
-                env.Append(
-                    CCFLAGS=[
-                        "-fsanitize=nullability-return,nullability-arg,function,nullability-assign,implicit-integer-sign-change"
-                    ]
-                )
-            else:
-                env.Append(CCFLAGS=["-fsanitize=bounds-strict"])
-
-        if env["use_asan"]:
-            env.Append(CCFLAGS=["-fsanitize=address,pointer-subtract,pointer-compare"])
-            env.Append(LINKFLAGS=["-fsanitize=address"])
-
-        if env["use_lsan"]:
-            env.Append(CCFLAGS=["-fsanitize=leak"])
-            env.Append(LINKFLAGS=["-fsanitize=leak"])
-
-        if env["use_tsan"]:
-            env.Append(CCFLAGS=["-fsanitize=thread"])
-            env.Append(LINKFLAGS=["-fsanitize=thread"])
-
-        if env["use_msan"] and env["use_llvm"]:
-            env.Append(CCFLAGS=["-fsanitize=memory"])
-            env.Append(CCFLAGS=["-fsanitize-memory-track-origins"])
-            env.Append(CCFLAGS=["-fsanitize-recover=memory"])
-            env.Append(LINKFLAGS=["-fsanitize=memory"])
-
-    if env["use_lto"]:
-        env.Append(CCFLAGS=["-flto"])
-        if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
-            env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))])
-        else:
-            env.Append(LINKFLAGS=["-flto"])
-        if not env["use_llvm"]:
-            env["RANLIB"] = "gcc-ranlib"
-            env["AR"] = "gcc-ar"
-
-    env.Append(CCFLAGS=["-pipe"])
-    env.Append(LINKFLAGS=["-pipe"])
-
-    ## Dependencies
-
-    # FIXME: Check for existence of the libs before parsing their flags with pkg-config
-
-    # freetype depends on libpng and zlib, so bundling one of them while keeping others
-    # as shared libraries leads to weird issues
-    if (
-        env["builtin_freetype"]
-        or env["builtin_libpng"]
-        or env["builtin_zlib"]
-        or env["builtin_graphite"]
-        or env["builtin_harfbuzz"]
-    ):
-        env["builtin_freetype"] = True
-        env["builtin_libpng"] = True
-        env["builtin_zlib"] = True
-        env["builtin_graphite"] = True
-        env["builtin_harfbuzz"] = True
-
-    if not env["builtin_freetype"]:
-        env.ParseConfig("pkg-config freetype2 --cflags --libs")
-
-    if not env["builtin_graphite"]:
-        env.ParseConfig("pkg-config graphite2 --cflags --libs")
-
-    if not env["builtin_icu"]:
-        env.ParseConfig("pkg-config icu-uc --cflags --libs")
-
-    if not env["builtin_harfbuzz"]:
-        env.ParseConfig("pkg-config harfbuzz harfbuzz-icu --cflags --libs")
-
-    if not env["builtin_libpng"]:
-        env.ParseConfig("pkg-config libpng16 --cflags --libs")
-
-    if not env["builtin_bullet"]:
-        # We need at least version 2.89
-        import subprocess
-
-        bullet_version = subprocess.check_output(["pkg-config", "bullet", "--modversion"]).strip()
-        if str(bullet_version) < "2.89":
-            # Abort as system bullet was requested but too old
-            print(
-                "Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(
-                    bullet_version, "2.89"
-                )
-            )
-            sys.exit(255)
-        env.ParseConfig("pkg-config bullet --cflags --libs")
-
-    if False:  # not env['builtin_assimp']:
-        # FIXME: Add min version check
-        env.ParseConfig("pkg-config assimp --cflags --libs")
-
-    if not env["builtin_enet"]:
-        env.ParseConfig("pkg-config libenet --cflags --libs")
-
-    if not env["builtin_squish"]:
-        env.ParseConfig("pkg-config libsquish --cflags --libs")
-
-    if not env["builtin_zstd"]:
-        env.ParseConfig("pkg-config libzstd --cflags --libs")
-
-    # Sound and video libraries
-    # Keep the order as it triggers chained dependencies (ogg needed by others, etc.)
-
-    if not env["builtin_libtheora"]:
-        env["builtin_libogg"] = False  # Needed to link against system libtheora
-        env["builtin_libvorbis"] = False  # Needed to link against system libtheora
-        env.ParseConfig("pkg-config theora theoradec --cflags --libs")
-    else:
-        list_of_x86 = ["x86_64", "x86", "i386", "i586"]
-        if any(platform.machine() in s for s in list_of_x86):
-            env["x86_libtheora_opt_gcc"] = True
-
-    if not env["builtin_libvpx"]:
-        env.ParseConfig("pkg-config vpx --cflags --libs")
-
-    if not env["builtin_libvorbis"]:
-        env["builtin_libogg"] = False  # Needed to link against system libvorbis
-        env.ParseConfig("pkg-config vorbis vorbisfile --cflags --libs")
-
-    if not env["builtin_opus"]:
-        env["builtin_libogg"] = False  # Needed to link against system opus
-        env.ParseConfig("pkg-config opus opusfile --cflags --libs")
-
-    if not env["builtin_libogg"]:
-        env.ParseConfig("pkg-config ogg --cflags --libs")
-
-    if not env["builtin_libwebp"]:
-        env.ParseConfig("pkg-config libwebp --cflags --libs")
-
-    if not env["builtin_mbedtls"]:
-        # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228
-        env.Append(LIBS=["mbedtls", "mbedcrypto", "mbedx509"])
-
-    if not env["builtin_wslay"]:
-        env.ParseConfig("pkg-config libwslay --cflags --libs")
-
-    if not env["builtin_miniupnpc"]:
-        # No pkgconfig file so far, hardcode default paths.
-        env.Prepend(CPPPATH=["/usr/include/miniupnpc"])
-        env.Append(LIBS=["miniupnpc"])
-
-    # On Linux wchar_t should be 32-bits
-    # 16-bit library shouldn't be required due to compiler optimisations
-    if not env["builtin_pcre2"]:
-        env.ParseConfig("pkg-config libpcre2-32 --cflags --libs")
-
-    ## Flags
-
-    # Linkflags below this line should typically stay the last ones
-    if not env["builtin_zlib"]:
-        env.ParseConfig("pkg-config zlib --cflags --libs")
-
-    env.Prepend(CPPPATH=["#platform/server"])
-    env.Append(CPPDEFINES=["SERVER_ENABLED", "UNIX_ENABLED"])
-
-    if platform.system() == "Darwin":
-        env.Append(
-            LINKFLAGS=[
-                "-framework",
-                "Cocoa",
-                "-framework",
-                "Carbon",
-                "-lz",
-                "-framework",
-                "IOKit",
-            ]
-        )
-
-    env.Append(LIBS=["pthread"])
-
-    if platform.system() == "Linux":
-        env.Append(LIBS=["dl"])
-
-    if platform.system().find("BSD") >= 0:
-        env["execinfo"] = True
-
-    if env["execinfo"]:
-        env.Append(LIBS=["execinfo"])
-
-    # Link those statically for portability
-    if env["use_static_cpp"]:
-        env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"])

+ 0 - 49
platform/server/godot_server.cpp

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/*  godot_server.cpp                                                     */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "main/main.h"
-#include "os_server.h"
-
-int main(int argc, char *argv[]) {
-	OS_Server os;
-
-	// We must override main when testing is enabled
-	TEST_MAIN_OVERRIDE
-
-	Error err = Main::setup(argv[0], argc - 1, &argv[1]);
-	if (err != OK)
-		return 255;
-
-	if (Main::start())
-		os.run(); // it is actually the OS that decides how to run
-	Main::cleanup();
-
-	return os.get_exit_code();
-}

BIN
platform/server/logo.png


+ 0 - 267
platform/server/os_server.cpp

@@ -1,267 +0,0 @@
-/*************************************************************************/
-/*  os_server.cpp                                                        */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#include "os_server.h"
-
-#include "core/string/print_string.h"
-#include "drivers/dummy/rasterizer_dummy.h"
-#include "drivers/dummy/texture_loader_dummy.h"
-#include "servers/rendering/rendering_server_default.h"
-
-#include "main/main.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int OS_Server::get_video_driver_count() const {
-	return 1;
-}
-
-const char *OS_Server::get_video_driver_name(int p_driver) const {
-	return "Dummy";
-}
-
-int OS_Server::get_current_video_driver() const {
-	return video_driver_index;
-}
-
-void OS_Server::initialize_core() {
-	crash_handler.initialize();
-
-	OS_Unix::initialize_core();
-}
-
-Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-	args = OS::get_singleton()->get_cmdline_args();
-	current_videomode = p_desired;
-	main_loop = nullptr;
-
-	RasterizerDummy::make_current();
-
-	video_driver_index = p_video_driver; // unused in server platform, but should still be initialized
-
-	rendering_server = memnew(RenderingServerDefault);
-	rendering_server->init();
-
-	AudioDriverManager::initialize(p_audio_driver);
-
-	input = memnew(InputDefault);
-
-	_ensure_user_data_dir();
-
-	resource_loader_dummy.instance();
-	ResourceLoader::add_resource_format_loader(resource_loader_dummy);
-
-	return OK;
-}
-
-void OS_Server::finalize() {
-	if (main_loop)
-		memdelete(main_loop);
-	main_loop = nullptr;
-
-	rendering_server->finish();
-	memdelete(rendering_server);
-
-	memdelete(input);
-
-	ResourceLoader::remove_resource_format_loader(resource_loader_dummy);
-	resource_loader_dummy.unref();
-
-	args.clear();
-}
-
-void OS_Server::set_mouse_show(bool p_show) {
-}
-
-void OS_Server::set_mouse_grab(bool p_grab) {
-	grab = p_grab;
-}
-
-bool OS_Server::is_mouse_grab_enabled() const {
-	return grab;
-}
-
-int OS_Server::get_mouse_button_state() const {
-	return 0;
-}
-
-Point2 OS_Server::get_mouse_position() const {
-	return Point2();
-}
-
-void OS_Server::set_window_title(const String &p_title) {
-}
-
-void OS_Server::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-}
-
-OS::VideoMode OS_Server::get_video_mode(int p_screen) const {
-	return current_videomode;
-}
-
-Size2 OS_Server::get_window_size() const {
-	return Vector2(current_videomode.width, current_videomode.height);
-}
-
-void OS_Server::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-}
-
-MainLoop *OS_Server::get_main_loop() const {
-	return main_loop;
-}
-
-void OS_Server::delete_main_loop() {
-	if (main_loop)
-		memdelete(main_loop);
-	main_loop = nullptr;
-}
-
-void OS_Server::set_main_loop(MainLoop *p_main_loop) {
-	main_loop = p_main_loop;
-	input->set_main_loop(p_main_loop);
-}
-
-String OS_Server::get_name() const {
-	return "Server";
-}
-
-void OS_Server::move_window_to_foreground() {
-}
-
-bool OS_Server::_check_internal_feature_support(const String &p_feature) {
-	return p_feature == "pc";
-}
-
-void OS_Server::run() {
-	force_quit = false;
-
-	if (!main_loop)
-		return;
-
-	main_loop->init();
-
-	while (!force_quit) {
-		if (Main::iteration())
-			break;
-	};
-
-	main_loop->finish();
-}
-
-String OS_Server::get_config_path() const {
-	if (has_environment("XDG_CONFIG_HOME")) {
-		return get_environment("XDG_CONFIG_HOME");
-	} else if (has_environment("HOME")) {
-		return get_environment("HOME").plus_file(".config");
-	} else {
-		return ".";
-	}
-}
-
-String OS_Server::get_data_path() const {
-	if (has_environment("XDG_DATA_HOME")) {
-		return get_environment("XDG_DATA_HOME");
-	} else if (has_environment("HOME")) {
-		return get_environment("HOME").plus_file(".local/share");
-	} else {
-		return get_config_path();
-	}
-}
-
-String OS_Server::get_cache_path() const {
-	if (has_environment("XDG_CACHE_HOME")) {
-		return get_environment("XDG_CACHE_HOME");
-	} else if (has_environment("HOME")) {
-		return get_environment("HOME").plus_file(".cache");
-	} else {
-		return get_config_path();
-	}
-}
-
-String OS_Server::get_system_dir(SystemDir p_dir) const {
-	String xdgparam;
-
-	switch (p_dir) {
-		case SYSTEM_DIR_DESKTOP: {
-			xdgparam = "DESKTOP";
-		} break;
-		case SYSTEM_DIR_DCIM: {
-			xdgparam = "PICTURES";
-
-		} break;
-		case SYSTEM_DIR_DOCUMENTS: {
-			xdgparam = "DOCUMENTS";
-
-		} break;
-		case SYSTEM_DIR_DOWNLOADS: {
-			xdgparam = "DOWNLOAD";
-
-		} break;
-		case SYSTEM_DIR_MOVIES: {
-			xdgparam = "VIDEOS";
-
-		} break;
-		case SYSTEM_DIR_MUSIC: {
-			xdgparam = "MUSIC";
-
-		} break;
-		case SYSTEM_DIR_PICTURES: {
-			xdgparam = "PICTURES";
-
-		} break;
-		case SYSTEM_DIR_RINGTONES: {
-			xdgparam = "MUSIC";
-
-		} break;
-	}
-
-	String pipe;
-	List<String> arg;
-	arg.push_back(xdgparam);
-	Error err = const_cast<OS_Server *>(this)->execute("xdg-user-dir", arg, true, nullptr, &pipe);
-	if (err != OK)
-		return ".";
-	return pipe.strip_edges();
-}
-
-void OS_Server::disable_crash_handler() {
-	crash_handler.disable();
-}
-
-bool OS_Server::is_disable_crash_handler() const {
-	return crash_handler.is_disabled();
-}
-
-OS_Server::OS_Server() {
-	//adriver here
-	grab = false;
-};

+ 0 - 116
platform/server/os_server.h

@@ -1,116 +0,0 @@
-/*************************************************************************/
-/*  os_server.h                                                          */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#ifndef OS_SERVER_H
-#define OS_SERVER_H
-
-#include "core/input/input.h"
-#include "drivers/dummy/texture_loader_dummy.h"
-#include "drivers/unix/os_unix.h"
-#ifdef __APPLE__
-#include "platform/osx/crash_handler_osx.h"
-#include "platform/osx/semaphore_osx.h"
-#else
-#include "platform/x11/crash_handler_linuxbsd.h"
-#endif
-#include "servers/audio_server.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering_server.h"
-
-#undef CursorShape
-
-class OS_Server : public OS_Unix {
-	RenderingServer *rendering_server = nullptr;
-	VideoMode current_videomode;
-	List<String> args;
-	MainLoop *main_loop = nullptr;
-
-	bool grab = false;
-
-	virtual void delete_main_loop();
-
-	bool force_quit = false;
-
-	InputDefault *input = nullptr;
-
-	CrashHandler crash_handler;
-
-	int video_driver_index = 0;
-
-	Ref<ResourceFormatDummyTexture> resource_loader_dummy;
-
-protected:
-	virtual int get_video_driver_count() const;
-	virtual const char *get_video_driver_name(int p_driver) const;
-	virtual int get_current_video_driver() const;
-
-	virtual void initialize_core();
-	virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
-	virtual void finalize();
-
-	virtual void set_main_loop(MainLoop *p_main_loop);
-
-public:
-	virtual String get_name() const;
-
-	virtual void set_mouse_show(bool p_show);
-	virtual void set_mouse_grab(bool p_grab);
-	virtual bool is_mouse_grab_enabled() const;
-	virtual Point2 get_mouse_position() const;
-	virtual int get_mouse_button_state() const;
-	virtual void set_window_title(const String &p_title);
-
-	virtual MainLoop *get_main_loop() const;
-
-	virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
-	virtual VideoMode get_video_mode(int p_screen = 0) const;
-	virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
-	virtual Size2 get_window_size() const;
-
-	virtual void move_window_to_foreground();
-
-	void run();
-
-	virtual bool _check_internal_feature_support(const String &p_feature);
-
-	virtual String get_config_path() const;
-	virtual String get_data_path() const;
-	virtual String get_cache_path() const;
-
-	virtual String get_system_dir(SystemDir p_dir) const;
-
-	void disable_crash_handler();
-	bool is_disable_crash_handler() const;
-
-	OS_Server();
-};
-
-#endif

+ 0 - 49
platform/server/platform_config.h

@@ -1,49 +0,0 @@
-/*************************************************************************/
-/*  platform_config.h                                                    */
-/*************************************************************************/
-/*                       This file is part of:                           */
-/*                           GODOT ENGINE                                */
-/*                      https://godotengine.org                          */
-/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
-/*                                                                       */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the       */
-/* "Software"), to deal in the Software without restriction, including   */
-/* without limitation the rights to use, copy, modify, merge, publish,   */
-/* distribute, sublicense, and/or sell copies of the Software, and to    */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions:                                             */
-/*                                                                       */
-/* The above copyright notice and this permission notice shall be        */
-/* included in all copies or substantial portions of the Software.       */
-/*                                                                       */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
-/*************************************************************************/
-
-#if defined(__linux__) || defined(__APPLE__)
-#include <alloca.h>
-#endif
-
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
-#include <stdlib.h> // alloca
-// FreeBSD and OpenBSD use pthread_set_name_np, while other platforms,
-// include NetBSD, use pthread_setname_np. NetBSD's version however requires
-// a different format, we handle this directly in thread_posix.
-#ifdef __NetBSD__
-#define PTHREAD_NETBSD_SET_NAME
-#else
-#define PTHREAD_BSD_SET_NAME
-#endif
-#endif
-
-#ifdef __APPLE__
-#define PTHREAD_RENAME_SELF
-#endif

+ 11 - 5
servers/display_server.cpp

@@ -32,14 +32,18 @@
 
 #include "core/input/input.h"
 #include "scene/resources/texture.h"
+#include "servers/display_server_headless.h"
 
 DisplayServer *DisplayServer::singleton = nullptr;
 DisplayServer::SwitchVSyncCallbackInThread DisplayServer::switch_vsync_function = nullptr;
 
 bool DisplayServer::hidpi_allowed = false;
 
-DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[DisplayServer::MAX_SERVERS];
-int DisplayServer::server_create_count = 0;
+DisplayServer::DisplayServerCreate DisplayServer::server_create_functions[DisplayServer::MAX_SERVERS] = {
+	{ "headless", &DisplayServerHeadless::create_func, &DisplayServerHeadless::get_rendering_drivers_func }
+};
+
+int DisplayServer::server_create_count = 1;
 
 void DisplayServer::global_menu_add_item(const String &p_menu_root, const String &p_label, const Callable &p_callback, const Variant &p_tag) {
 	WARN_PRINT("Global menus not supported by this display server.");
@@ -560,9 +564,11 @@ void DisplayServer::_bind_methods() {
 
 void DisplayServer::register_create_function(const char *p_name, CreateFunction p_function, GetRenderingDriversFunction p_get_drivers) {
 	ERR_FAIL_COND(server_create_count == MAX_SERVERS);
-	server_create_functions[server_create_count].name = p_name;
-	server_create_functions[server_create_count].create_function = p_function;
-	server_create_functions[server_create_count].get_rendering_drivers_function = p_get_drivers;
+	// Headless display server is always last
+	server_create_functions[server_create_count] = server_create_functions[server_create_count - 1];
+	server_create_functions[server_create_count - 1].name = p_name;
+	server_create_functions[server_create_count - 1].create_function = p_function;
+	server_create_functions[server_create_count - 1].get_rendering_drivers_function = p_get_drivers;
 	server_create_count++;
 }
 

+ 127 - 0
servers/display_server_headless.h

@@ -0,0 +1,127 @@
+/*************************************************************************/
+/*  display_server_headless.h                                            */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef DISPLAY_SERVER_HEADLESS_H
+#define DISPLAY_SERVER_HEADLESS_H
+
+#include "servers/display_server.h"
+
+#include "servers/rendering/rasterizer_dummy.h"
+
+class DisplayServerHeadless : public DisplayServer {
+private:
+	friend class DisplayServer;
+
+	static Vector<String> get_rendering_drivers_func() {
+		Vector<String> drivers;
+		drivers.push_back("dummy");
+		return drivers;
+	}
+
+	static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+		r_error = OK;
+		RasterizerDummy::make_current();
+		return memnew(DisplayServerHeadless());
+	}
+
+public:
+	bool has_feature(Feature p_feature) const override { return false; }
+	String get_name() const override { return "headless"; }
+
+	void alert(const String &p_alert, const String &p_title = "ALERT!") override {}
+
+	int get_screen_count() const override { return 0; }
+	Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Point2i(); }
+	Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Size2i(); }
+	Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return Rect2i(); }
+	int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return 96; /* 0 might cause issues */ }
+	float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override { return 1; }
+	float screen_get_max_scale() const override { return 1; }
+
+	Vector<DisplayServer::WindowID> get_window_list() const override { return Vector<DisplayServer::WindowID>(); }
+
+	WindowID get_window_at_screen_position(const Point2i &p_position) const override { return -1; }
+
+	void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override {}
+	ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override { return ObjectID(); }
+
+	void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override {}
+	void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override {}
+	void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override {}
+	void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	void window_set_mouse_passthrough(const Vector<Vector2> &p_region, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override { return -1; }
+	void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override { return Point2i(); }
+	void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	void window_set_transient(WindowID p_window, WindowID p_parent) override {}
+
+	void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {}
+	Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
+
+	void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {}
+	Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); };
+
+	void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override {}
+	Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
+	Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const override { return Size2i(); }
+
+	void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override {}
+	WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override { return WINDOW_MODE_MINIMIZED; }
+
+	bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
+
+	void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override {}
+	virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
+
+	void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override {}
+	void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override {}
+
+	bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override { return false; }
+
+	bool can_any_window_draw() const override { return false; }
+
+	void process_events() override {}
+
+	void set_icon(const Ref<Image> &p_icon) override {}
+
+	DisplayServerHeadless() {}
+	~DisplayServerHeadless() {}
+};
+
+#endif // DISPLAY_SERVER_HEADLESS_H

+ 3 - 0
drivers/dummy/rasterizer_dummy.h → servers/rendering/rasterizer_dummy.h

@@ -599,6 +599,8 @@ public:
 	void particles_add_collision(RID p_particles, RID p_instance) override {}
 	void particles_remove_collision(RID p_particles, RID p_instance) override {}
 
+	void particles_set_canvas_sdf_collision(RID p_particles, bool p_enable, const Transform2D &p_xform, const Rect2 &p_to_screen, RID p_texture) override {}
+
 	void update_particles() override {}
 
 	/* PARTICLES COLLISION */
@@ -662,6 +664,7 @@ public:
 
 	void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
 	Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
+	void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
 
 	RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
 	bool free(RID p_rid) override {