From d7cca8162d6e57332adf743d684452a4a7a069cd Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Fri, 8 Dec 2023 12:52:49 +0100 Subject: [PATCH] Improve logging and benchmarking in Main --- main/main.cpp | 576 +++++++++++++++++++++++++++++--------------------- 1 file changed, 336 insertions(+), 240 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index b6da0db0e8e..0157be79ad5 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -766,6 +766,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Benchmark tracking must be done after `OS::get_singleton()->initialize()` as on some // platforms, it's used to set up the time utilities. OS::get_singleton()->benchmark_begin_measure("Startup", "Total"); + OS::get_singleton()->benchmark_begin_measure("Startup", "Setup"); engine = memnew(Engine); @@ -2185,6 +2186,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph return setup2(); } + OS::get_singleton()->benchmark_end_measure("Startup", "Setup"); return OK; error: @@ -2239,6 +2241,7 @@ error: } OS::get_singleton()->benchmark_end_measure("Startup", "Core"); + OS::get_singleton()->benchmark_end_measure("Startup", "Setup"); OS::get_singleton()->finalize_core(); locale = String(); @@ -2272,25 +2275,10 @@ Error Main::setup2() { // Print engine name and version print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); - OS::get_singleton()->benchmark_begin_measure("Startup", "Servers"); - - tsman = memnew(TextServerManager); - - if (tsman) { - Ref ts; - ts.instantiate(); - tsman->add_interface(ts); - } - - physics_server_3d_manager = memnew(PhysicsServer3DManager); - physics_server_2d_manager = memnew(PhysicsServer2DManager); - - register_server_types(); - initialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS); - GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SERVERS); - #ifdef TOOLS_ENABLED if (editor || project_manager || cmdline_tool) { + OS::get_singleton()->benchmark_begin_measure("Startup", "Initialize Early Settings"); + EditorPaths::create(); // Editor setting class is not available, load config directly. @@ -2352,16 +2340,49 @@ Error Main::setup2() { return FAILED; } } + + OS::get_singleton()->benchmark_end_measure("Startup", "Initialize Early Settings"); } #endif + OS::get_singleton()->benchmark_begin_measure("Startup", "Servers"); + + tsman = memnew(TextServerManager); + if (tsman) { + Ref ts; + ts.instantiate(); + tsman->add_interface(ts); + } + + physics_server_3d_manager = memnew(PhysicsServer3DManager); + physics_server_2d_manager = memnew(PhysicsServer2DManager); + + register_server_types(); + { + OS::get_singleton()->benchmark_begin_measure("Servers", "Modules and Extensions"); + + initialize_modules(MODULE_INITIALIZATION_LEVEL_SERVERS); + GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SERVERS); + + OS::get_singleton()->benchmark_end_measure("Servers", "Modules and Extensions"); + } + /* Initialize Input */ - input = memnew(Input); + { + OS::get_singleton()->benchmark_begin_measure("Servers", "Input"); + + input = memnew(Input); + OS::get_singleton()->initialize_joypads(); + + OS::get_singleton()->benchmark_end_measure("Servers", "Input"); + } /* Initialize Display Server */ { + OS::get_singleton()->benchmark_begin_measure("Servers", "Display"); + String display_driver = DisplayServer::get_create_function_name(display_driver_idx); Vector2i *window_position = nullptr; @@ -2395,10 +2416,12 @@ Error Main::setup2() { ERR_PRINT("Unable to create DisplayServer, all display drivers failed."); return err; } - } - if (display_server->has_feature(DisplayServer::FEATURE_ORIENTATION)) { - display_server->screen_set_orientation(window_orientation); + if (display_server->has_feature(DisplayServer::FEATURE_ORIENTATION)) { + display_server->screen_set_orientation(window_orientation); + } + + OS::get_singleton()->benchmark_end_measure("Servers", "Display"); } if (GLOBAL_GET("debug/settings/stdout/print_fps") || print_fps) { @@ -2426,48 +2449,58 @@ Error Main::setup2() { /* Initialize Pen Tablet Driver */ { + OS::get_singleton()->benchmark_begin_measure("Servers", "Tablet Driver"); + GLOBAL_DEF_RST_NOVAL("input_devices/pen_tablet/driver", ""); GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "input_devices/pen_tablet/driver.windows", PROPERTY_HINT_ENUM, "wintab,winink"), ""); - } - if (tablet_driver.is_empty()) { // specified in project.godot - tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver"); - if (tablet_driver.is_empty()) { - tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0); + if (tablet_driver.is_empty()) { // specified in project.godot + tablet_driver = GLOBAL_GET("input_devices/pen_tablet/driver"); + if (tablet_driver.is_empty()) { + tablet_driver = DisplayServer::get_singleton()->tablet_get_driver_name(0); + } } - } - for (int i = 0; i < DisplayServer::get_singleton()->tablet_get_driver_count(); i++) { - if (tablet_driver == DisplayServer::get_singleton()->tablet_get_driver_name(i)) { - DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(i)); - break; + for (int i = 0; i < DisplayServer::get_singleton()->tablet_get_driver_count(); i++) { + if (tablet_driver == DisplayServer::get_singleton()->tablet_get_driver_name(i)) { + DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(i)); + break; + } } - } - if (DisplayServer::get_singleton()->tablet_get_current_driver().is_empty()) { - DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0)); - } + if (DisplayServer::get_singleton()->tablet_get_current_driver().is_empty()) { + DisplayServer::get_singleton()->tablet_set_current_driver(DisplayServer::get_singleton()->tablet_get_driver_name(0)); + } - print_verbose("Using \"" + tablet_driver + "\" pen tablet driver..."); + print_verbose("Using \"" + tablet_driver + "\" pen tablet driver..."); + + OS::get_singleton()->benchmark_end_measure("Servers", "Tablet Driver"); + } /* Initialize Rendering Server */ - rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); + { + OS::get_singleton()->benchmark_begin_measure("Servers", "Rendering"); - rendering_server->init(); - //rendering_server->call_set_use_vsync(OS::get_singleton()->_use_vsync); - rendering_server->set_render_loop_enabled(!disable_render_loop); + rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); - if (profile_gpu || (!editor && bool(GLOBAL_GET("debug/settings/stdout/print_gpu_profile")))) { - rendering_server->set_print_gpu_profile(true); - } + rendering_server->init(); + //rendering_server->call_set_use_vsync(OS::get_singleton()->_use_vsync); + rendering_server->set_render_loop_enabled(!disable_render_loop); - if (Engine::get_singleton()->get_write_movie_path() != String()) { - movie_writer = MovieWriter::find_writer_for_file(Engine::get_singleton()->get_write_movie_path()); - if (movie_writer == nullptr) { - ERR_PRINT("Can't find movie writer for file type, aborting: " + Engine::get_singleton()->get_write_movie_path()); - Engine::get_singleton()->set_write_movie_path(String()); + if (profile_gpu || (!editor && bool(GLOBAL_GET("debug/settings/stdout/print_gpu_profile")))) { + rendering_server->set_print_gpu_profile(true); } + + if (Engine::get_singleton()->get_write_movie_path() != String()) { + movie_writer = MovieWriter::find_writer_for_file(Engine::get_singleton()->get_write_movie_path()); + if (movie_writer == nullptr) { + ERR_PRINT("Can't find movie writer for file type, aborting: " + Engine::get_singleton()->get_write_movie_path()); + Engine::get_singleton()->set_write_movie_path(String()); + } + } + + OS::get_singleton()->benchmark_end_measure("Servers", "Rendering"); } #ifdef UNIX_ENABLED @@ -2477,207 +2510,243 @@ Error Main::setup2() { } #endif - OS::get_singleton()->initialize_joypads(); - /* Initialize Audio Driver */ - AudioDriverManager::initialize(audio_driver_idx); + { + OS::get_singleton()->benchmark_begin_measure("Servers", "Audio"); - print_line(" "); //add a blank line for readability + AudioDriverManager::initialize(audio_driver_idx); - // right moment to create and initialize the audio server + print_line(" "); // Add a blank line for readability. - audio_server = memnew(AudioServer); - audio_server->init(); + // Right moment to create and initialize the audio server. + audio_server = memnew(AudioServer); + audio_server->init(); - // also init our xr_server from here - xr_server = memnew(XRServer); - - register_core_singletons(); - - MAIN_PRINT("Main: Setup Logo"); - -#if !defined(TOOLS_ENABLED) && (defined(WEB_ENABLED) || defined(ANDROID_ENABLED)) - bool show_logo = false; -#else - bool show_logo = true; -#endif - - if (init_windowed) { - //do none.. - } else if (init_maximized) { - DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_MAXIMIZED); - } else if (init_fullscreen) { - DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_FULLSCREEN); - } - if (init_always_on_top) { - DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true); + OS::get_singleton()->benchmark_end_measure("Servers", "Audio"); } - MAIN_PRINT("Main: Load Boot Image"); + /* Initialize XR Server */ - Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)); - RenderingServer::get_singleton()->set_default_clear_color(clear); + { + OS::get_singleton()->benchmark_begin_measure("Servers", "XR"); - if (show_logo) { //boot logo! - const bool boot_logo_image = GLOBAL_DEF_BASIC("application/boot_splash/show_image", true); - const String boot_logo_path = String(GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/boot_splash/image", PROPERTY_HINT_FILE, "*.png"), String())).strip_edges(); - const bool boot_logo_scale = GLOBAL_DEF_BASIC("application/boot_splash/fullsize", true); - const bool boot_logo_filter = GLOBAL_DEF_BASIC("application/boot_splash/use_filter", true); + xr_server = memnew(XRServer); - Ref boot_logo; - - if (boot_logo_image) { - if (!boot_logo_path.is_empty()) { - boot_logo.instantiate(); - Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo); - if (load_err) { - ERR_PRINT("Non-existing or invalid boot splash at '" + boot_logo_path + "'. Loading default splash."); - } - } - } else { - // Create a 1×1 transparent image. This will effectively hide the splash image. - boot_logo.instantiate(); - boot_logo->initialize_data(1, 1, false, Image::FORMAT_RGBA8); - boot_logo->set_pixel(0, 0, Color(0, 0, 0, 0)); - } - - Color boot_bg_color = GLOBAL_GET("application/boot_splash/bg_color"); - -#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) - boot_bg_color = - GLOBAL_DEF_BASIC("application/boot_splash/bg_color", - (editor || project_manager) ? boot_splash_editor_bg_color : boot_splash_bg_color); -#endif - if (boot_logo.is_valid()) { - RenderingServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale, - boot_logo_filter); - - } else { -#ifndef NO_DEFAULT_BOOT_LOGO - MAIN_PRINT("Main: Create bootsplash"); -#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) - Ref splash = (editor || project_manager) ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png)); -#else - Ref splash = memnew(Image(boot_splash_png)); -#endif - - MAIN_PRINT("Main: ClearColor"); - RenderingServer::get_singleton()->set_default_clear_color(boot_bg_color); - MAIN_PRINT("Main: Image"); - RenderingServer::get_singleton()->set_boot_image(splash, boot_bg_color, false); -#endif - } - -#if defined(TOOLS_ENABLED) && defined(MACOS_ENABLED) - if (OS::get_singleton()->get_bundle_icon_path().is_empty()) { - Ref icon = memnew(Image(app_icon_png)); - DisplayServer::get_singleton()->set_icon(icon); - } -#endif - } - - DisplayServer::set_early_window_clear_color_override(false); - - MAIN_PRINT("Main: DCC"); - RenderingServer::get_singleton()->set_default_clear_color( - GLOBAL_GET("rendering/environment/defaults/default_clear_color")); - - GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), String()); - GLOBAL_DEF(PropertyInfo(Variant::STRING, "application/config/macos_native_icon", PROPERTY_HINT_FILE, "*.icns"), String()); - GLOBAL_DEF(PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico"), String()); - - Input *id = Input::get_singleton(); - if (id) { - agile_input_event_flushing = GLOBAL_DEF("input_devices/buffering/agile_event_flushing", false); - - if (bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_touch_from_mouse", false)) && - !(editor || project_manager)) { - if (!DisplayServer::get_singleton()->is_touchscreen_available()) { - //only if no touchscreen ui hint, set emulation - id->set_emulate_touch_from_mouse(true); - } - } - - id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true))); - } - - GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); - GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); - - MAIN_PRINT("Main: Load Translations and Remaps"); - - translation_server->setup(); //register translations, load them, etc. - if (!locale.is_empty()) { - translation_server->set_locale(locale); - } - translation_server->load_translations(); - ResourceLoader::load_translation_remaps(); //load remaps for resources - - ResourceLoader::load_path_remaps(); - - MAIN_PRINT("Main: Load TextServer"); - - /* Enum text drivers */ - GLOBAL_DEF_RST("internationalization/rendering/text_driver", ""); - String text_driver_options; - for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { - const String driver_name = TextServerManager::get_singleton()->get_interface(i)->get_name(); - if (driver_name == "Dummy") { - // Dummy text driver cannot draw any text, making the editor unusable if selected. - continue; - } - if (!text_driver_options.is_empty() && text_driver_options.find(",") == -1) { - // Not the first option; add a comma before it as a separator for the property hint. - text_driver_options += ","; - } - text_driver_options += driver_name; - } - ProjectSettings::get_singleton()->set_custom_property_info(PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options)); - - /* Determine text driver */ - if (text_driver.is_empty()) { - text_driver = GLOBAL_GET("internationalization/rendering/text_driver"); - } - - if (!text_driver.is_empty()) { - /* Load user selected text server. */ - for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { - if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) { - text_driver_idx = i; - break; - } - } - } - - if (text_driver_idx < 0) { - /* If not selected, use one with the most features available. */ - int max_features = 0; - for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { - uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features(); - int feature_number = 0; - while (features) { - feature_number += features & 1; - features >>= 1; - } - if (feature_number >= max_features) { - max_features = feature_number; - text_driver_idx = i; - } - } - } - if (text_driver_idx >= 0) { - Ref ts = TextServerManager::get_singleton()->get_interface(text_driver_idx); - TextServerManager::get_singleton()->set_primary_interface(ts); - if (ts->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { - ts->load_support_data("res://" + ts->get_support_data_filename()); - } - } else { - ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface."); + OS::get_singleton()->benchmark_end_measure("Servers", "XR"); } OS::get_singleton()->benchmark_end_measure("Startup", "Servers"); + register_core_singletons(); + + /* Initialize the main window and boot screen */ + + { + OS::get_singleton()->benchmark_begin_measure("Startup", "Setup Window and Boot"); + + MAIN_PRINT("Main: Setup Logo"); + +#if !defined(TOOLS_ENABLED) && (defined(WEB_ENABLED) || defined(ANDROID_ENABLED)) + bool show_logo = false; +#else + bool show_logo = true; +#endif + + if (init_windowed) { + //do none.. + } else if (init_maximized) { + DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_MAXIMIZED); + } else if (init_fullscreen) { + DisplayServer::get_singleton()->window_set_mode(DisplayServer::WINDOW_MODE_FULLSCREEN); + } + if (init_always_on_top) { + DisplayServer::get_singleton()->window_set_flag(DisplayServer::WINDOW_FLAG_ALWAYS_ON_TOP, true); + } + + MAIN_PRINT("Main: Load Boot Image"); + + Color clear = GLOBAL_DEF_BASIC("rendering/environment/defaults/default_clear_color", Color(0.3, 0.3, 0.3)); + RenderingServer::get_singleton()->set_default_clear_color(clear); + + if (show_logo) { //boot logo! + const bool boot_logo_image = GLOBAL_DEF_BASIC("application/boot_splash/show_image", true); + const String boot_logo_path = String(GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/boot_splash/image", PROPERTY_HINT_FILE, "*.png"), String())).strip_edges(); + const bool boot_logo_scale = GLOBAL_DEF_BASIC("application/boot_splash/fullsize", true); + const bool boot_logo_filter = GLOBAL_DEF_BASIC("application/boot_splash/use_filter", true); + + Ref boot_logo; + + if (boot_logo_image) { + if (!boot_logo_path.is_empty()) { + boot_logo.instantiate(); + Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo); + if (load_err) { + ERR_PRINT("Non-existing or invalid boot splash at '" + boot_logo_path + "'. Loading default splash."); + } + } + } else { + // Create a 1×1 transparent image. This will effectively hide the splash image. + boot_logo.instantiate(); + boot_logo->initialize_data(1, 1, false, Image::FORMAT_RGBA8); + boot_logo->set_pixel(0, 0, Color(0, 0, 0, 0)); + } + + Color boot_bg_color = GLOBAL_GET("application/boot_splash/bg_color"); + +#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) + boot_bg_color = + GLOBAL_DEF_BASIC("application/boot_splash/bg_color", + (editor || project_manager) ? boot_splash_editor_bg_color : boot_splash_bg_color); +#endif + if (boot_logo.is_valid()) { + RenderingServer::get_singleton()->set_boot_image(boot_logo, boot_bg_color, boot_logo_scale, + boot_logo_filter); + + } else { +#ifndef NO_DEFAULT_BOOT_LOGO + MAIN_PRINT("Main: Create bootsplash"); +#if defined(TOOLS_ENABLED) && !defined(NO_EDITOR_SPLASH) + Ref splash = (editor || project_manager) ? memnew(Image(boot_splash_editor_png)) : memnew(Image(boot_splash_png)); +#else + Ref splash = memnew(Image(boot_splash_png)); +#endif + + MAIN_PRINT("Main: ClearColor"); + RenderingServer::get_singleton()->set_default_clear_color(boot_bg_color); + MAIN_PRINT("Main: Image"); + RenderingServer::get_singleton()->set_boot_image(splash, boot_bg_color, false); +#endif + } + +#if defined(TOOLS_ENABLED) && defined(MACOS_ENABLED) + if (OS::get_singleton()->get_bundle_icon_path().is_empty()) { + Ref icon = memnew(Image(app_icon_png)); + DisplayServer::get_singleton()->set_icon(icon); + } +#endif + } + + MAIN_PRINT("Main: Clear Color"); + + DisplayServer::set_early_window_clear_color_override(false); + RenderingServer::get_singleton()->set_default_clear_color( + GLOBAL_GET("rendering/environment/defaults/default_clear_color")); + + GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), String()); + GLOBAL_DEF(PropertyInfo(Variant::STRING, "application/config/macos_native_icon", PROPERTY_HINT_FILE, "*.icns"), String()); + GLOBAL_DEF(PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico"), String()); + + MAIN_PRINT("Main: Touch Input"); + + Input *id = Input::get_singleton(); + if (id) { + agile_input_event_flushing = GLOBAL_DEF("input_devices/buffering/agile_event_flushing", false); + + if (bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_touch_from_mouse", false)) && + !(editor || project_manager)) { + if (!DisplayServer::get_singleton()->is_touchscreen_available()) { + //only if no touchscreen ui hint, set emulation + id->set_emulate_touch_from_mouse(true); + } + } + + id->set_emulate_mouse_from_touch(bool(GLOBAL_DEF_BASIC("input_devices/pointing/emulate_mouse_from_touch", true))); + } + + GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); + GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); + + OS::get_singleton()->benchmark_end_measure("Startup", "Setup Window and Boot"); + } + + MAIN_PRINT("Main: Load Translations and Remaps"); + + /* Setup translations and remaps */ + + { + OS::get_singleton()->benchmark_begin_measure("Startup", "Translations and Remaps"); + + translation_server->setup(); //register translations, load them, etc. + if (!locale.is_empty()) { + translation_server->set_locale(locale); + } + translation_server->load_translations(); + ResourceLoader::load_translation_remaps(); //load remaps for resources + + ResourceLoader::load_path_remaps(); + + OS::get_singleton()->benchmark_end_measure("Startup", "Translations and Remaps"); + } + + MAIN_PRINT("Main: Load TextServer"); + + /* Setup Text Server */ + + { + OS::get_singleton()->benchmark_begin_measure("Startup", "Text Server"); + + /* Enum text drivers */ + GLOBAL_DEF_RST("internationalization/rendering/text_driver", ""); + String text_driver_options; + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + const String driver_name = TextServerManager::get_singleton()->get_interface(i)->get_name(); + if (driver_name == "Dummy") { + // Dummy text driver cannot draw any text, making the editor unusable if selected. + continue; + } + if (!text_driver_options.is_empty() && text_driver_options.find(",") == -1) { + // Not the first option; add a comma before it as a separator for the property hint. + text_driver_options += ","; + } + text_driver_options += driver_name; + } + ProjectSettings::get_singleton()->set_custom_property_info(PropertyInfo(Variant::STRING, "internationalization/rendering/text_driver", PROPERTY_HINT_ENUM, text_driver_options)); + + /* Determine text driver */ + if (text_driver.is_empty()) { + text_driver = GLOBAL_GET("internationalization/rendering/text_driver"); + } + + if (!text_driver.is_empty()) { + /* Load user selected text server. */ + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + if (TextServerManager::get_singleton()->get_interface(i)->get_name() == text_driver) { + text_driver_idx = i; + break; + } + } + } + + if (text_driver_idx < 0) { + /* If not selected, use one with the most features available. */ + int max_features = 0; + for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { + uint32_t features = TextServerManager::get_singleton()->get_interface(i)->get_features(); + int feature_number = 0; + while (features) { + feature_number += features & 1; + features >>= 1; + } + if (feature_number >= max_features) { + max_features = feature_number; + text_driver_idx = i; + } + } + } + if (text_driver_idx >= 0) { + Ref ts = TextServerManager::get_singleton()->get_interface(text_driver_idx); + TextServerManager::get_singleton()->set_primary_interface(ts); + if (ts->has_feature(TextServer::FEATURE_USE_SUPPORT_DATA)) { + ts->load_support_data("res://" + ts->get_support_data_filename()); + } + } else { + ERR_FAIL_V_MSG(ERR_CANT_CREATE, "TextServer: Unable to create TextServer interface."); + } + + OS::get_singleton()->benchmark_end_measure("Startup", "Text Server"); + } + MAIN_PRINT("Main: Load Scene Types"); OS::get_singleton()->benchmark_begin_measure("Startup", "Scene"); @@ -2691,23 +2760,42 @@ Error Main::setup2() { register_scene_singletons(); - initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE); - GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SCENE); + { + OS::get_singleton()->benchmark_begin_measure("Scene", "Modules and Extensions"); + + initialize_modules(MODULE_INITIALIZATION_LEVEL_SCENE); + GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_SCENE); + + OS::get_singleton()->benchmark_end_measure("Scene", "Modules and Extensions"); + } + + OS::get_singleton()->benchmark_end_measure("Startup", "Scene"); #ifdef TOOLS_ENABLED ClassDB::set_current_api(ClassDB::API_EDITOR); register_editor_types(); - initialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR); - GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_EDITOR); + + { + OS::get_singleton()->benchmark_begin_measure("Editor", "Modules and Extensions"); + + initialize_modules(MODULE_INITIALIZATION_LEVEL_EDITOR); + GDExtensionManager::get_singleton()->initialize_extensions(GDExtension::INITIALIZATION_LEVEL_EDITOR); + + OS::get_singleton()->benchmark_end_measure("Editor", "Modules and Extensions"); + } ClassDB::set_current_api(ClassDB::API_CORE); #endif - MAIN_PRINT("Main: Load Modules"); + MAIN_PRINT("Main: Load Platforms"); + + OS::get_singleton()->benchmark_begin_measure("Startup", "Platforms"); register_platform_apis(); + OS::get_singleton()->benchmark_end_measure("Startup", "Platforms"); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::STRING, "display/mouse_cursor/custom_image", PROPERTY_HINT_FILE, "*.png,*.webp"), String()); GLOBAL_DEF_BASIC("display/mouse_cursor/custom_image_hotspot", Vector2()); GLOBAL_DEF_BASIC("display/mouse_cursor/tooltip_position_offset", Point2(10, 10)); @@ -2721,12 +2809,18 @@ Error Main::setup2() { } } + OS::get_singleton()->benchmark_begin_measure("Startup", "Finalize Setup"); + camera_server = CameraServer::create(); MAIN_PRINT("Main: Load Physics"); initialize_physics(); + + MAIN_PRINT("Main: Load Navigation"); + initialize_navigation_server(); + register_server_singletons(); // This loads global classes, so it must happen before custom loaders and savers are registered @@ -2758,6 +2852,8 @@ Error Main::setup2() { rendering_server->global_shader_parameters_load_settings(!editor); } + OS::get_singleton()->benchmark_end_measure("Startup", "Finalize Setup"); + _start_success = true; ClassDB::set_current_api(ClassDB::API_NONE); //no more APIs are registered at this point @@ -2766,7 +2862,7 @@ Error Main::setup2() { print_verbose("EDITOR API HASH: " + uitos(ClassDB::get_api_hash(ClassDB::API_EDITOR))); MAIN_PRINT("Main: Done"); - OS::get_singleton()->benchmark_end_measure("Startup", "Scene"); + OS::get_singleton()->benchmark_end_measure("Startup", "Setup"); return OK; }