diff --git a/core/os/os.cpp b/core/os/os.cpp index 59a0579ce36..1e9dbd2a184 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -536,9 +536,14 @@ bool OS::has_feature(const String &p_feature) { return true; } - if (has_server_feature_callback && has_server_feature_callback(p_feature)) { - return true; + if (has_server_feature_callback) { + return has_server_feature_callback(p_feature); } +#ifdef DEBUG_ENABLED + else if (is_stdout_verbose()) { + WARN_PRINT_ONCE("Server features cannot be checked before RenderingServer has been created. If you are checking a server feature, consider moving your OS::has_feature call after INITIALIZATION_LEVEL_SERVERS."); + } +#endif if (ProjectSettings::get_singleton()->has_custom_feature(p_feature)) { return true; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 3a578d01a6b..685ba9d3d98 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -313,17 +313,28 @@ void register_core_settings() { GLOBAL_DEF("threading/worker_pool/low_priority_thread_ratio", 0.3); } +void register_early_core_singletons() { + GDREGISTER_CLASS(core_bind::Engine); + Engine::get_singleton()->add_singleton(Engine::Singleton("Engine", core_bind::Engine::get_singleton())); + + GDREGISTER_CLASS(ProjectSettings); + Engine::get_singleton()->add_singleton(Engine::Singleton("ProjectSettings", ProjectSettings::get_singleton())); + + GDREGISTER_CLASS(core_bind::OS); + Engine::get_singleton()->add_singleton(Engine::Singleton("OS", core_bind::OS::get_singleton())); + + GDREGISTER_CLASS(Time); + Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); +} + void register_core_singletons() { OS::get_singleton()->benchmark_begin_measure("Core", "Register Singletons"); - GDREGISTER_CLASS(ProjectSettings); GDREGISTER_ABSTRACT_CLASS(IP); GDREGISTER_CLASS(core_bind::Geometry2D); GDREGISTER_CLASS(core_bind::Geometry3D); GDREGISTER_CLASS(core_bind::ResourceLoader); GDREGISTER_CLASS(core_bind::ResourceSaver); - GDREGISTER_CLASS(core_bind::OS); - GDREGISTER_CLASS(core_bind::Engine); GDREGISTER_CLASS(core_bind::special::ClassDB); GDREGISTER_CLASS(core_bind::Marshalls); GDREGISTER_CLASS(TranslationServer); @@ -331,23 +342,18 @@ void register_core_singletons() { GDREGISTER_CLASS(InputMap); GDREGISTER_CLASS(Expression); GDREGISTER_CLASS(core_bind::EngineDebugger); - GDREGISTER_CLASS(Time); - Engine::get_singleton()->add_singleton(Engine::Singleton("ProjectSettings", ProjectSettings::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("IP", IP::get_singleton(), "IP")); Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry2D", core_bind::Geometry2D::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry3D", core_bind::Geometry3D::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceLoader", core_bind::ResourceLoader::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceSaver", core_bind::ResourceSaver::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("OS", core_bind::OS::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("Engine", core_bind::Engine::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb)); Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", core_bind::Marshalls::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("EngineDebugger", core_bind::EngineDebugger::get_singleton())); - Engine::get_singleton()->add_singleton(Engine::Singleton("Time", Time::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("GDExtensionManager", GDExtensionManager::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceUID", ResourceUID::get_singleton())); Engine::get_singleton()->add_singleton(Engine::Singleton("WorkerThreadPool", worker_thread_pool)); diff --git a/core/register_core_types.h b/core/register_core_types.h index eba569272ee..b8db5c5d260 100644 --- a/core/register_core_types.h +++ b/core/register_core_types.h @@ -34,6 +34,7 @@ void register_core_types(); void register_core_settings(); void register_core_extensions(); +void register_early_core_singletons(); void register_core_singletons(); void unregister_core_types(); void unregister_core_extensions(); diff --git a/main/main.cpp b/main/main.cpp index f002e227660..123114ce8d0 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -733,6 +733,7 @@ Error Main::test_setup() { physics_server_2d_manager = memnew(PhysicsServer2DManager); // From `Main::setup2()`. + register_early_core_singletons(); initialize_modules(MODULE_INITIALIZATION_LEVEL_CORE); register_core_extensions(); @@ -1869,12 +1870,55 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph if (editor) { Engine::get_singleton()->set_editor_hint(true); Engine::get_singleton()->set_extension_reloading_enabled(true); + + main_args.push_back("--editor"); + if (!init_windowed && !init_fullscreen) { + init_maximized = true; + window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED; + } + } + + if (!project_manager && !editor) { + // If we didn't find a project, we fall back to the project manager. + project_manager = !found_project && !cmdline_tool; + } + + if (project_manager) { + Engine::get_singleton()->set_project_manager_hint(true); } #endif + OS::get_singleton()->set_cmdline(execpath, main_args, user_args); + + Engine::get_singleton()->set_physics_ticks_per_second(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/physics_ticks_per_second", PROPERTY_HINT_RANGE, "1,1000,1"), 60)); + Engine::get_singleton()->set_max_physics_steps_per_frame(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/max_physics_steps_per_frame", PROPERTY_HINT_RANGE, "1,100,1"), 8)); + Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5)); + Engine::get_singleton()->set_max_fps(GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/max_fps", PROPERTY_HINT_RANGE, "0,1000,1"), 0)); + if (max_fps >= 0) { + Engine::get_singleton()->set_max_fps(max_fps); + } + // Initialize user data dir. OS::get_singleton()->ensure_user_data_dir(); + OS::get_singleton()->set_low_processor_usage_mode(GLOBAL_DEF("application/run/low_processor_mode", false)); + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec( + GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater"), 6900)); // Roughly 144 FPS + + GLOBAL_DEF("application/run/delta_smoothing", true); + if (!delta_smoothing_override) { + OS::get_singleton()->set_delta_smoothing(GLOBAL_GET("application/run/delta_smoothing")); + } + + GLOBAL_DEF("debug/settings/stdout/print_fps", false); + GLOBAL_DEF("debug/settings/stdout/print_gpu_profile", false); + GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); + GLOBAL_DEF("debug/settings/physics_interpolation/enable_warnings", true); + if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden. + OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout"); + } + + register_early_core_singletons(); initialize_modules(MODULE_INITIALIZATION_LEVEL_CORE); register_core_extensions(); // core extensions must be registered after globals setup and before display @@ -1899,20 +1943,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED if (editor) { packed_data->set_disabled(true); - main_args.push_back("--editor"); - if (!init_windowed && !init_fullscreen) { - init_maximized = true; - window_mode = DisplayServer::WINDOW_MODE_MAXIMIZED; - } - } - - if (!project_manager && !editor) { - // If we didn't find a project, we fall back to the project manager. - project_manager = !found_project && !cmdline_tool; - } - - if (project_manager) { - Engine::get_singleton()->set_project_manager_hint(true); } #endif @@ -1984,8 +2014,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Logger::set_flush_stdout_on_print(GLOBAL_GET("application/run/flush_stdout_on_print")); - OS::get_singleton()->set_cmdline(execpath, main_args, user_args); - { String driver_hints = ""; String driver_hints_with_d3d12 = ""; @@ -2544,9 +2572,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph window_vsync_mode = DisplayServer::VSyncMode::VSYNC_DISABLED; } } - Engine::get_singleton()->set_physics_ticks_per_second(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/physics_ticks_per_second", PROPERTY_HINT_RANGE, "1,1000,1"), 60)); - Engine::get_singleton()->set_max_physics_steps_per_frame(GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "physics/common/max_physics_steps_per_frame", PROPERTY_HINT_RANGE, "1,100,1"), 8)); - Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5)); GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "audio/driver/output_latency", PROPERTY_HINT_RANGE, "1,100,1"), 15); // Use a safer default output_latency for web to avoid audio cracking on low-end devices, especially mobile. @@ -2554,15 +2579,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_audio_output_latency(GLOBAL_GET("audio/driver/output_latency")); - GLOBAL_DEF("debug/settings/stdout/print_fps", false); - GLOBAL_DEF("debug/settings/stdout/print_gpu_profile", false); - GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); - GLOBAL_DEF("debug/settings/physics_interpolation/enable_warnings", true); - - if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden. - OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout"); - } - #if defined(MACOS_ENABLED) || defined(IOS_ENABLED) OS::get_singleton()->set_environment("MVK_CONFIG_LOG_LEVEL", OS::get_singleton()->_verbose_stdout ? "3" : "1"); // 1 = Errors only, 3 = Info #endif @@ -2578,15 +2594,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::get_singleton()->set_audio_output_latency(audio_output_latency); } - OS::get_singleton()->set_low_processor_usage_mode(GLOBAL_DEF("application/run/low_processor_mode", false)); - OS::get_singleton()->set_low_processor_usage_mode_sleep_usec( - GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/low_processor_mode_sleep_usec", PROPERTY_HINT_RANGE, "0,33200,1,or_greater"), 6900)); // Roughly 144 FPS - - GLOBAL_DEF("application/run/delta_smoothing", true); - if (!delta_smoothing_override) { - OS::get_singleton()->set_delta_smoothing(GLOBAL_GET("application/run/delta_smoothing")); - } - GLOBAL_DEF("display/window/ios/allow_high_refresh_rate", true); GLOBAL_DEF("display/window/ios/hide_home_indicator", true); GLOBAL_DEF("display/window/ios/hide_status_bar", true); @@ -3013,10 +3020,9 @@ Error Main::setup2(bool p_show_boot_logo) { } // Max FPS needs to be set after the DisplayServer is created. - Engine::get_singleton()->set_max_fps(GLOBAL_DEF(PropertyInfo(Variant::INT, "application/run/max_fps", PROPERTY_HINT_RANGE, "0,1000,1"), 0)); - - if (max_fps >= 0) { - Engine::get_singleton()->set_max_fps(max_fps); + RenderingDevice *rd = RenderingDevice::get_singleton(); + if (rd) { + rd->_set_max_fps(engine->get_max_fps()); } #ifdef TOOLS_ENABLED diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 984c9ae90e3..2b5c77d4b93 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -1528,7 +1528,8 @@ DWRITE_FONT_STRETCH OS_Windows::_stretch_to_dw(int p_stretch) const { } Vector OS_Windows::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const { - if (!dwrite2_init) { + // This may be called before TextServerManager has been created, which would cause a crash downstream if we do not check here + if (!dwrite2_init || !TextServerManager::get_singleton()) { return Vector(); }