diff options
Diffstat (limited to 'main')
-rw-r--r-- | main/main.cpp | 252 | ||||
-rw-r--r-- | main/main.h | 1 | ||||
-rw-r--r-- | main/main_timer_sync.cpp | 26 | ||||
-rw-r--r-- | main/main_timer_sync.h | 22 | ||||
-rw-r--r-- | main/performance.cpp | 64 | ||||
-rw-r--r-- | main/performance.h | 24 |
6 files changed, 202 insertions, 187 deletions
diff --git a/main/main.cpp b/main/main.cpp index aa925c508c..d91cc5c9bf 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -34,8 +34,10 @@ #include "core/core_string_names.h" #include "core/crypto/crypto.h" #include "core/debugger/engine_debugger.h" +#include "core/extension/extension_api_dump.h" #include "core/input/input.h" #include "core/input/input_map.h" +#include "core/io/dir_access.h" #include "core/io/file_access_network.h" #include "core/io/file_access_pack.h" #include "core/io/file_access_zip.h" @@ -43,8 +45,8 @@ #include "core/io/ip.h" #include "core/io/resource_loader.h" #include "core/object/message_queue.h" -#include "core/os/dir_access.h" #include "core/os/os.h" +#include "core/os/time.h" #include "core/register_core_types.h" #include "core/string/translation.h" #include "core/version.h" @@ -101,6 +103,7 @@ static InputMap *input_map = nullptr; static TranslationServer *translation_server = nullptr; static Performance *performance = nullptr; static PackedData *packed_data = nullptr; +static Time *time_singleton = nullptr; #ifdef MINIZIP_ENABLED static ZipArchive *zip_packed_data = nullptr; #endif @@ -135,6 +138,7 @@ static int audio_driver_idx = -1; static bool single_window = false; static bool editor = false; static bool project_manager = false; +static bool cmdline_tool = false; static String locale; static bool show_help = false; static bool auto_quit = false; @@ -147,9 +151,9 @@ static bool auto_build_solutions = false; static DisplayServer::WindowMode window_mode = DisplayServer::WINDOW_MODE_WINDOWED; static DisplayServer::ScreenOrientation window_orientation = DisplayServer::SCREEN_LANDSCAPE; +static DisplayServer::VSyncMode window_vsync_mode = DisplayServer::VSYNC_ENABLED; static uint32_t window_flags = 0; static Size2i window_size = Size2i(1024, 600); -static bool window_vsync_via_compositor = false; static int init_screen = -1; static bool init_fullscreen = false; @@ -171,7 +175,9 @@ static int frame_delay = 0; static bool disable_render_loop = false; static int fixed_fps = -1; static bool print_fps = false; - +#ifdef TOOLS_ENABLED +static bool dump_extension_api = false; +#endif bool profile_gpu = false; /* Helper methods */ @@ -183,6 +189,10 @@ bool Main::is_project_manager() { return project_manager; } +bool Main::is_cmdline_tool() { + return cmdline_tool; +} + static String unescape_cmdline(const String &p_str) { return p_str.replace("%20", " "); } @@ -316,9 +326,10 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n"); + OS::get_singleton()->print(" --headless Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.\n"); + OS::get_singleton()->print("\n"); -#ifndef SERVER_ENABLED OS::get_singleton()->print("Display options:\n"); OS::get_singleton()->print(" -f, --fullscreen Request fullscreen mode.\n"); OS::get_singleton()->print(" -m, --maximized Request a maximized window.\n"); @@ -327,13 +338,9 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); OS::get_singleton()->print(" --low-dpi Force low-DPI mode (macOS and Windows only).\n"); - OS::get_singleton()->print(" --no-window Disable window creation (Windows only). Useful together with --script.\n"); - OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n"); - OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n"); OS::get_singleton()->print("\n"); -#endif OS::get_singleton()->print("Debug options:\n"); OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); @@ -344,7 +351,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n"); #endif OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n"); -#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) +#if defined(DEBUG_ENABLED) OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n"); OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n"); #endif @@ -365,7 +372,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n"); OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n"); OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n"); - OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n"); + OS::get_singleton()->print(" --doctool [<path>] Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.\n"); OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n"); OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n"); #ifdef DEBUG_METHODS_ENABLED @@ -375,8 +382,8 @@ void Main::print_help(const char *p_binary) { #ifdef TESTS_ENABLED OS::get_singleton()->print(" --test [--help] Run unit tests. Use --test --help for more information.\n"); #endif - OS::get_singleton()->print("\n"); #endif + OS::get_singleton()->print("\n"); } #ifdef TESTS_ENABLED @@ -390,6 +397,8 @@ Error Main::test_setup() { register_core_types(); register_core_driver_types(); + packed_data = memnew(PackedData); + globals = memnew(ProjectSettings); GLOBAL_DEF("debug/settings/crash_handler/message", @@ -397,6 +406,8 @@ Error Main::test_setup() { translation_server = memnew(TranslationServer); + register_core_extensions(); + // From `Main::setup2()`. preregister_module_types(); preregister_server_types(); @@ -459,6 +470,9 @@ void Main::test_cleanup() { if (globals) { memdelete(globals); } + if (packed_data) { + memdelete(packed_data); + } if (engine) { memdelete(engine); } @@ -527,13 +541,14 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph MAIN_PRINT("Main: Initialize Globals"); input_map = memnew(InputMap); + time_singleton = memnew(Time); globals = memnew(ProjectSettings); register_core_settings(); //here globals are present translation_server = memnew(TranslationServer); performance = memnew(Performance); - ClassDB::register_class<Performance>(); + GDREGISTER_CLASS(Performance); engine->add_singleton(Engine::Singleton("Performance", performance)); // Only flush stdout in debug builds by default, as spamming `print()` will @@ -581,11 +596,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Vector<String> breakpoints; bool use_custom_res = true; bool force_res = false; - bool saw_vsync_via_compositor_override = false; #ifdef TOOLS_ENABLED bool found_project = false; #endif - bool use_vsync = false; packed_data = PackedData::get_singleton(); if (!packed_data) { @@ -714,7 +727,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->print("Missing video driver argument, aborting.\n"); goto error; } -#ifndef SERVER_ENABLED } else if (I->get() == "-f" || I->get() == "--fullscreen") { // force fullscreen init_fullscreen = true; @@ -804,16 +816,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "--low-dpi") { // force low DPI (macOS only) force_lowdpi = true; - } else if (I->get() == "--no-window") { // disable window creation (Windows only) - - OS::get_singleton()->set_no_window_mode(true); - } else if (I->get() == "--enable-vsync-via-compositor") { - window_vsync_via_compositor = true; - saw_vsync_via_compositor_override = true; - } else if (I->get() == "--disable-vsync-via-compositor") { - window_vsync_via_compositor = false; - saw_vsync_via_compositor_override = true; -#endif + } else if (I->get() == "--headless") { // enable headless mode (no audio, no rendering). + + audio_driver = "Dummy"; + display_driver = "headless"; + } else if (I->get() == "--profiling") { // enable profiling use_debug_profiler = true; @@ -873,18 +880,31 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph auto_build_solutions = true; editor = true; -#ifdef DEBUG_METHODS_ENABLED + cmdline_tool = true; + } else if (I->get() == "--gdnative-generate-json-api" || I->get() == "--gdnative-generate-json-builtin-api") { // Register as an editor instance to use low-end fallback if relevant. editor = true; + cmdline_tool = true; // We still pass it to the main arguments since the argument handling itself is not done in this function main_args.push_back(I->get()); -#endif + } else if (I->get() == "--dump-extension-api") { + // Register as an editor instance to use low-end fallback if relevant. + editor = true; + cmdline_tool = true; + dump_extension_api = true; + print_line("dump extension?"); + main_args.push_back(I->get()); } else if (I->get() == "--export" || I->get() == "--export-debug" || I->get() == "--export-pack") { // Export project - + // Actually handling is done in start(). editor = true; + cmdline_tool = true; + main_args.push_back(I->get()); + } else if (I->get() == "--doctool") { + // Actually handling is done in start(). + cmdline_tool = true; main_args.push_back(I->get()); #endif } else if (I->get() == "--path") { // set path of project to start or edit @@ -965,11 +985,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "-d" || I->get() == "--debug") { debug_uri = "local://"; OS::get_singleton()->_debug_stdout = true; -#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED) +#if defined(DEBUG_ENABLED) } else if (I->get() == "--debug-collisions") { debug_collisions = true; } else if (I->get() == "--debug-navigation") { debug_navigation = true; + } else if (I->get() == "--debug-stringnames") { + StringName::set_debug_stringnames(true); #endif } else if (I->get() == "--remote-debug") { if (I->next()) { @@ -1057,7 +1079,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #else const String error_msg = "Error: Couldn't load project data at path \"" + project_path + "\". Is the .pck file missing?\nIf you've renamed the executable, the associated .pck file should also be renamed to match the executable's name (without the extension).\n"; OS::get_singleton()->print("%s", error_msg.ascii().get_data()); - DisplayServer::get_singleton()->alert(error_msg); + OS::get_singleton()->alert(error_msg); goto error; #endif @@ -1066,6 +1088,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph // Initialize user data dir. OS::get_singleton()->ensure_user_data_dir(); + ResourceUID::get_singleton()->load_from_cache(); // load UUIDs from cache. + GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60); ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc", PropertyInfo(Variant::INT, @@ -1117,8 +1141,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } if (!project_manager && !editor) { - // Determine if the project manager should be requested - project_manager = main_args.size() == 0 && !found_project; + // If we didn't find a project, we fall back to the project manager. + project_manager = !found_project && !cmdline_tool; } #endif @@ -1178,6 +1202,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph OS::get_singleton()->set_cmdline(execpath, main_args); + register_core_extensions(); //before display + GLOBAL_DEF("rendering/driver/driver_name", "Vulkan"); ProjectSettings::get_singleton()->set_custom_property_info("rendering/driver/driver_name", PropertyInfo(Variant::STRING, @@ -1248,24 +1274,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); + GLOBAL_DEF("internationalization/locale/include_text_server_data", false); if (!force_lowdpi) { OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", false); } - use_vsync = GLOBAL_DEF_RST("display/window/vsync/use_vsync", true); - OS::get_singleton()->_use_vsync = use_vsync; - - if (!saw_vsync_via_compositor_override) { - // If one of the command line options to enable/disable vsync via the - // window compositor ("--enable-vsync-via-compositor" or - // "--disable-vsync-via-compositor") was present then it overrides the - // project setting. - window_vsync_via_compositor = GLOBAL_DEF("display/window/vsync/vsync_via_compositor", false); - } - - OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor; - /* todo restore OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false); video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false); @@ -1321,35 +1335,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } { - String orientation = GLOBAL_DEF("display/window/handheld/orientation", "landscape"); - - if (orientation == "portrait") { - window_orientation = DisplayServer::SCREEN_PORTRAIT; - } else if (orientation == "reverse_landscape") { - window_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE; - } else if (orientation == "reverse_portrait") { - window_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT; - } else if (orientation == "sensor_landscape") { - window_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE; - } else if (orientation == "sensor_portrait") { - window_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT; - } else if (orientation == "sensor") { - window_orientation = DisplayServer::SCREEN_SENSOR; - } else { - window_orientation = DisplayServer::SCREEN_LANDSCAPE; - } + window_orientation = DisplayServer::ScreenOrientation(int(GLOBAL_DEF_BASIC("display/window/handheld/orientation", DisplayServer::ScreenOrientation::SCREEN_LANDSCAPE))); + } + { + window_vsync_mode = DisplayServer::VSyncMode(int(GLOBAL_DEF("display/window/vsync/vsync_mode", DisplayServer::VSyncMode::VSYNC_ENABLED))); } - Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF_BASIC("physics/common/physics_fps", 60)); ProjectSettings::get_singleton()->set_custom_property_info("physics/common/physics_fps", PropertyInfo(Variant::INT, "physics/common/physics_fps", - PROPERTY_HINT_RANGE, "1,120,1,or_greater")); + PROPERTY_HINT_RANGE, "1,1000,1")); Engine::get_singleton()->set_physics_jitter_fix(GLOBAL_DEF("physics/common/physics_jitter_fix", 0.5)); Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0)); ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", - PROPERTY_HINT_RANGE, "0,120,1,or_greater")); + PROPERTY_HINT_RANGE, "0,1000,1")); GLOBAL_DEF("debug/settings/stdout/print_fps", false); GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false); @@ -1412,6 +1412,9 @@ error: if (input_map) { memdelete(input_map); } + if (time_singleton) { + memdelete(time_singleton); + } if (translation_server) { memdelete(translation_server); } @@ -1455,6 +1458,12 @@ Error Main::setup2(Thread::ID p_main_tid_override) { } #endif +#ifdef TOOLS_ENABLED + if (editor || project_manager || cmdline_tool) { + EditorPaths::create(); + } +#endif + /* Determine text driver */ if (text_driver == "") { @@ -1523,14 +1532,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) { String rendering_driver; // temp broken Error err; - display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_flags, window_size, err); + display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err); if (err != OK || display_server == nullptr) { //ok i guess we can't use this display server, try other ones for (int i = 0; i < DisplayServer::get_create_function_count(); i++) { if (i == display_driver_idx) { continue; //don't try the same twice } - display_server = DisplayServer::create(i, rendering_driver, window_mode, window_flags, window_size, err); + display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_size, err); if (err == OK && display_server != nullptr) { break; } @@ -1575,7 +1584,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { print_verbose("Using \"" + tablet_driver + "\" pen tablet driver..."); - /* Initialize Visual Server */ + /* Initialize Rendering Server */ rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD)); @@ -1586,6 +1595,13 @@ Error Main::setup2(Thread::ID p_main_tid_override) { rendering_server->set_print_gpu_profile(true); } +#ifdef UNIX_ENABLED + // Print warning after initializing the renderer but before initializing audio. + if (OS::get_singleton()->get_environment("USER") == "root" && !OS::get_singleton()->has_environment("GODOT_SILENCE_ROOT_WARNING")) { + WARN_PRINT("Started the engine as `root`/superuser. This is a security risk, and subsystems like audio may not work correctly.\nSet the environment variable `GODOT_SILENCE_ROOT_WARNING` to 1 to silence this warning."); + } +#endif + OS::get_singleton()->initialize_joypads(); /* Initialize Audio Driver */ @@ -1655,7 +1671,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { boot_logo_path = boot_logo_path.strip_edges(); if (boot_logo_path != String()) { - boot_logo.instance(); + 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."); @@ -1826,14 +1842,13 @@ bool Main::start() { ERR_FAIL_COND_V(!_start_success, false); bool hasicon = false; - String doc_tool; - List<String> removal_docs; String positional_arg; String game_path; String script; bool check_only = false; #ifdef TOOLS_ENABLED + String doc_tool_path; bool doc_base = true; String _export_preset; bool export_debug = false; @@ -1843,8 +1858,9 @@ bool Main::start() { main_timer_sync.init(OS::get_singleton()->get_ticks_usec()); List<String> args = OS::get_singleton()->get_cmdline_args(); - // parameters that do not have an argument to the right for (int i = 0; i < args.size(); i++) { + // First check parameters that do not have an argument to the right. + // Doctest Unit Testing Handler // Designed to override and pass arguments to the unit test handler. if (args[i] == "--check-only") { @@ -1874,16 +1890,18 @@ bool Main::start() { game_path = args[i]; } } - //parameters that have an argument to the right + // Then parameters that have an argument to the right. else if (i < (args.size() - 1)) { bool parsed_pair = true; if (args[i] == "-s" || args[i] == "--script") { script = args[i + 1]; #ifdef TOOLS_ENABLED } else if (args[i] == "--doctool") { - doc_tool = args[i + 1]; - for (int j = i + 2; j < args.size(); j++) { - removal_docs.push_back(args[j]); + doc_tool_path = args[i + 1]; + if (doc_tool_path.begins_with("-")) { + // Assuming other command line arg, so default to cwd. + doc_tool_path = "."; + parsed_pair = false; } } else if (args[i] == "--export") { editor = true; //needs editor @@ -1905,15 +1923,21 @@ bool Main::start() { i++; } } +#ifdef TOOLS_ENABLED + // Handle case where no path is given to --doctool. + else if (args[i] == "--doctool") { + doc_tool_path = "."; + } +#endif } #ifdef TOOLS_ENABLED - if (doc_tool != "") { - Engine::get_singleton()->set_editor_hint( - true); // Needed to instance editor-only classes for their default values + if (doc_tool_path != "") { + // Needed to instance editor-only classes for their default values + Engine::get_singleton()->set_editor_hint(true); { - DirAccessRef da = DirAccess::open(doc_tool); + DirAccessRef da = DirAccess::open(doc_tool_path); ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a valid directory path."); } @@ -1943,7 +1967,7 @@ bool Main::start() { // Custom modules are always located by absolute path. String path = _doc_data_class_paths[i].path; if (path.is_rel_path()) { - path = doc_tool.plus_file(path); + path = doc_tool_path.plus_file(path); } String name = _doc_data_class_paths[i].name; doc_data_classes[name] = path; @@ -1960,7 +1984,7 @@ bool Main::start() { } } - String index_path = doc_tool.plus_file("doc/classes"); + String index_path = doc_tool_path.plus_file("doc/classes"); // Create the main documentation directory if it doesn't exist DirAccess *da = DirAccess::create_for_path(index_path); da->make_dir_recursive(index_path); @@ -1983,16 +2007,31 @@ bool Main::start() { return false; } + if (dump_extension_api) { + NativeExtensionAPIDump::generate_extension_json_file("extension_api.json"); + return false; + } #endif if (script == "" && game_path == "" && String(GLOBAL_GET("application/run/main_scene")) != "") { game_path = GLOBAL_GET("application/run/main_scene"); } +#ifdef TOOLS_ENABLED + if (!editor && !project_manager && !cmdline_tool && script == "" && game_path == "") { + // If we end up here, it means we didn't manage to detect what we want to run. + // Let's throw an error gently. The code leading to this is pretty brittle so + // this might end up triggered by valid usage, in which case we'll have to + // fine-tune further. + OS::get_singleton()->alert("Couldn't detect whether to run the editor, the project manager or a specific project. Aborting."); + ERR_FAIL_V_MSG(false, "Couldn't detect whether to run the editor, the project manager or a specific project. Aborting."); + } +#endif + MainLoop *main_loop = nullptr; if (editor) { main_loop = memnew(SceneTree); - }; + } String main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "SceneTree"); if (script != "") { @@ -2006,17 +2045,16 @@ bool Main::start() { return false; } - if (script_res->can_instance()) { + if (script_res->can_instantiate()) { StringName instance_type = script_res->get_instance_base_type(); - Object *obj = ClassDB::instance(instance_type); + Object *obj = ClassDB::instantiate(instance_type); MainLoop *script_loop = Object::cast_to<MainLoop>(obj); if (!script_loop) { if (obj) { memdelete(obj); } - ERR_FAIL_V_MSG(false, - vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", - script)); + OS::get_singleton()->alert(vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script)); + ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script)); } script_loop->set_initialize_script(script_res); @@ -2029,13 +2067,13 @@ bool Main::start() { String script_path = ScriptServer::get_global_class_path(main_loop_type); Ref<Script> script_res = ResourceLoader::load(script_path); StringName script_base = ScriptServer::get_global_class_native_base(main_loop_type); - Object *obj = ClassDB::instance(script_base); + Object *obj = ClassDB::instantiate(script_base); MainLoop *script_loop = Object::cast_to<MainLoop>(obj); if (!script_loop) { if (obj) { memdelete(obj); } - DisplayServer::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base); + OS::get_singleton()->alert("Error: Invalid MainLoop script base type: " + script_base); ERR_FAIL_V_MSG(false, vformat("The global class %s does not inherit from SceneTree or MainLoop.", main_loop_type)); } script_loop->set_initialize_script(script_res); @@ -2049,10 +2087,10 @@ bool Main::start() { if (!main_loop) { if (!ClassDB::class_exists(main_loop_type)) { - DisplayServer::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type); + OS::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type); return false; } else { - Object *ml = ClassDB::instance(main_loop_type); + Object *ml = ClassDB::instantiate(main_loop_type); ERR_FAIL_COND_V_MSG(!ml, false, "Can't instance MainLoop type."); main_loop = Object::cast_to<MainLoop>(ml); @@ -2109,14 +2147,14 @@ bool Main::start() { Node *n = nullptr; if (res->is_class("PackedScene")) { Ref<PackedScene> ps = res; - n = ps->instance(); + n = ps->instantiate(); } else if (res->is_class("Script")) { Ref<Script> script_res = res; StringName ibt = script_res->get_instance_base_type(); bool valid_type = ClassDB::is_parent_class(ibt, "Node"); ERR_CONTINUE_MSG(!valid_type, "Script does not inherit a Node: " + info.path); - Object *obj = ClassDB::instance(ibt); + Object *obj = ClassDB::instantiate(ibt); ERR_CONTINUE_MSG(obj == nullptr, "Cannot instance script for autoload, expected 'Node' inheritance, got: " + @@ -2139,8 +2177,8 @@ bool Main::start() { } } - for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) { - sml->get_root()->add_child(E->get()); + for (Node *E : to_add) { + sml->get_root()->add_child(E); } } } @@ -2242,7 +2280,7 @@ bool Main::start() { ProjectSettings::get_singleton()->set_custom_property_info( "rendering/textures/canvas_textures/default_texture_filter", PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, - "Nearest,Linear,MipmapLinear,MipmapNearest")); + "Nearest,Linear,Linear Mipmap,Nearest Mipmap")); GLOBAL_DEF_BASIC("rendering/textures/canvas_textures/default_texture_repeat", 0); ProjectSettings::get_singleton()->set_custom_property_info( "rendering/textures/canvas_textures/default_texture_repeat", @@ -2319,7 +2357,7 @@ bool Main::start() { Node *scene = nullptr; Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path); if (scenedata.is_valid()) { - scene = scenedata->instance(); + scene = scenedata->instantiate(); } ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path); @@ -2344,7 +2382,7 @@ bool Main::start() { String iconpath = GLOBAL_DEF("application/config/icon", "Variant()"); if ((iconpath != "") && (!hasicon)) { Ref<Image> icon; - icon.instance(); + icon.instantiate(); if (ImageLoader::load_image(iconpath, icon) == OK) { DisplayServer::get_singleton()->set_icon(icon); hasicon = true; @@ -2354,14 +2392,13 @@ bool Main::start() { } #ifdef TOOLS_ENABLED - if (project_manager || (script == "" && game_path == "" && !editor)) { + if (project_manager) { Engine::get_singleton()->set_editor_hint(true); ProjectManager *pmanager = memnew(ProjectManager); ProgressDialog *progress_dialog = memnew(ProgressDialog); pmanager->add_child(progress_dialog); sml->get_root()->add_child(pmanager); DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_PROJECTMAN); - project_manager = true; } if (project_manager || editor) { @@ -2373,10 +2410,8 @@ bool Main::start() { } // Load SSL Certificates from Editor Settings (or builtin) - Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting( - "network/ssl/editor_ssl_certificates") - . - operator String()); + Crypto::load_default_certificates( + EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String()); } #endif } @@ -2533,10 +2568,10 @@ bool Main::iteration() { if (frame > 1000000) { if (editor || project_manager) { if (print_fps) { - print_line("Editor FPS: " + itos(frames)); + print_line(vformat("Editor FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(1))); } } else if (GLOBAL_GET("debug/settings/stdout/print_fps") || print_fps) { - print_line("Game FPS: " + itos(frames)); + print_line(vformat("Project FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(1))); } Engine::get_singleton()->_fps = frames; @@ -2667,6 +2702,9 @@ void Main::cleanup(bool p_force) { if (input_map) { memdelete(input_map); } + if (time_singleton) { + memdelete(time_singleton); + } if (translation_server) { memdelete(translation_server); } diff --git a/main/main.h b/main/main.h index f4fff6b97e..84077137ba 100644 --- a/main/main.h +++ b/main/main.h @@ -45,6 +45,7 @@ class Main { public: static bool is_project_manager(); + static bool is_cmdline_tool(); static int test_entrypoint(int argc, char *argv[], bool &tests_need_run); static Error setup(const char *execpath, int argc, char *argv[], bool p_second_phase = true); static Error setup2(Thread::ID p_main_tid_override = 0); diff --git a/main/main_timer_sync.cpp b/main/main_timer_sync.cpp index 93448d0904..94e62bea97 100644 --- a/main/main_timer_sync.cpp +++ b/main/main_timer_sync.cpp @@ -30,7 +30,7 @@ #include "main_timer_sync.h" -void MainFrameTime::clamp_process_step(float min_process_step, float max_process_step) { +void MainFrameTime::clamp_process_step(double min_process_step, double max_process_step) { if (process_step < min_process_step) { process_step = min_process_step; } else if (process_step > max_process_step) { @@ -43,25 +43,25 @@ void MainFrameTime::clamp_process_step(float min_process_step, float max_process // returns the fraction of p_physics_step required for the timer to overshoot // before advance_core considers changing the physics_steps return from // the typical values as defined by typical_physics_steps -float MainTimerSync::get_physics_jitter_fix() { +double MainTimerSync::get_physics_jitter_fix() { return Engine::get_singleton()->get_physics_jitter_fix(); } // gets our best bet for the average number of physics steps per render frame // return value: number of frames back this data is consistent -int MainTimerSync::get_average_physics_steps(float &p_min, float &p_max) { +int MainTimerSync::get_average_physics_steps(double &p_min, double &p_max) { p_min = typical_physics_steps[0]; p_max = p_min + 1; for (int i = 1; i < CONTROL_STEPS; ++i) { - const float typical_lower = typical_physics_steps[i]; - const float current_min = typical_lower / (i + 1); + const double typical_lower = typical_physics_steps[i]; + const double current_min = typical_lower / (i + 1); if (current_min > p_max) { return i; // bail out of further restrictions would void the interval } else if (current_min > p_min) { p_min = current_min; } - const float current_max = (typical_lower + 1) / (i + 1); + const double current_max = (typical_lower + 1) / (i + 1); if (current_max < p_min) { return i; } else if (current_max < p_max) { @@ -73,7 +73,7 @@ int MainTimerSync::get_average_physics_steps(float &p_min, float &p_max) { } // advance physics clock by p_process_step, return appropriate number of steps to simulate -MainFrameTime MainTimerSync::advance_core(float p_physics_step, int p_physics_fps, float p_process_step) { +MainFrameTime MainTimerSync::advance_core(double p_physics_step, int p_physics_fps, double p_process_step) { MainFrameTime ret; ret.process_step = p_process_step; @@ -146,7 +146,7 @@ MainFrameTime MainTimerSync::advance_core(float p_physics_step, int p_physics_fp } // calls advance_core, keeps track of deficit it adds to animaption_step, make sure the deficit sum stays close to zero -MainFrameTime MainTimerSync::advance_checked(float p_physics_step, int p_physics_fps, float p_process_step) { +MainFrameTime MainTimerSync::advance_checked(double p_physics_step, int p_physics_fps, double p_process_step) { if (fixed_fps != -1) { p_process_step = 1.0 / fixed_fps; } @@ -163,7 +163,7 @@ MainFrameTime MainTimerSync::advance_checked(float p_physics_step, int p_physics // first, least important clamping: keep ret.process_step consistent with typical_physics_steps. // this smoothes out the process steps and culls small but quick variations. { - float min_average_physics_steps, max_average_physics_steps; + double min_average_physics_steps, max_average_physics_steps; int consistent_steps = get_average_physics_steps(min_average_physics_steps, max_average_physics_steps); if (consistent_steps > 3) { ret.clamp_process_step(min_average_physics_steps * p_physics_step, max_average_physics_steps * p_physics_step); @@ -171,7 +171,7 @@ MainFrameTime MainTimerSync::advance_checked(float p_physics_step, int p_physics } // second clamping: keep abs(time_deficit) < jitter_fix * frame_slise - float max_clock_deviation = get_physics_jitter_fix() * p_physics_step; + double max_clock_deviation = get_physics_jitter_fix() * p_physics_step; ret.clamp_process_step(p_process_step - max_clock_deviation, p_process_step + max_clock_deviation); // last clamping: make sure time_accum is between 0 and p_physics_step for consistency between physics and process @@ -191,7 +191,7 @@ MainFrameTime MainTimerSync::advance_checked(float p_physics_step, int p_physics } // determine wall clock step since last iteration -float MainTimerSync::get_cpu_process_step() { +double MainTimerSync::get_cpu_process_step() { uint64_t cpu_ticks_elapsed = current_cpu_ticks_usec - last_cpu_ticks_usec; last_cpu_ticks_usec = current_cpu_ticks_usec; @@ -220,8 +220,8 @@ void MainTimerSync::set_fixed_fps(int p_fixed_fps) { } // advance one physics frame, return timesteps to take -MainFrameTime MainTimerSync::advance(float p_physics_step, int p_physics_fps) { - float cpu_process_step = get_cpu_process_step(); +MainFrameTime MainTimerSync::advance(double p_physics_step, int p_physics_fps) { + double cpu_process_step = get_cpu_process_step(); return advance_checked(p_physics_step, p_physics_fps, cpu_process_step); } diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h index 884978bf96..abdec18f6d 100644 --- a/main/main_timer_sync.h +++ b/main/main_timer_sync.h @@ -34,11 +34,11 @@ #include "core/config/engine.h" struct MainFrameTime { - float process_step; // delta time to advance during process() + double process_step; // delta time to advance during process() int physics_steps; // number of times to iterate the physics engine - float interpolation_fraction; // fraction through the current physics tick + double interpolation_fraction; // fraction through the current physics tick - void clamp_process_step(float min_process_step, float max_process_step); + void clamp_process_step(double min_process_step, double max_process_step); }; class MainTimerSync { @@ -47,10 +47,10 @@ class MainTimerSync { uint64_t current_cpu_ticks_usec = 0; // logical game time since last physics timestep - float time_accum = 0; + double time_accum = 0; // current difference between wall clock time and reported sum of process_steps - float time_deficit = 0; + double time_deficit = 0; // number of frames back for keeping accumulated physics steps roughly constant. // value of 12 chosen because that is what is required to make 144 Hz monitors @@ -70,20 +70,20 @@ protected: // returns the fraction of p_physics_step required for the timer to overshoot // before advance_core considers changing the physics_steps return from // the typical values as defined by typical_physics_steps - float get_physics_jitter_fix(); + double get_physics_jitter_fix(); // gets our best bet for the average number of physics steps per render frame // return value: number of frames back this data is consistent - int get_average_physics_steps(float &p_min, float &p_max); + int get_average_physics_steps(double &p_min, double &p_max); // advance physics clock by p_process_step, return appropriate number of steps to simulate - MainFrameTime advance_core(float p_physics_step, int p_physics_fps, float p_process_step); + MainFrameTime advance_core(double p_physics_step, int p_physics_fps, double p_process_step); // calls advance_core, keeps track of deficit it adds to animaption_step, make sure the deficit sum stays close to zero - MainFrameTime advance_checked(float p_physics_step, int p_physics_fps, float p_process_step); + MainFrameTime advance_checked(double p_physics_step, int p_physics_fps, double p_process_step); // determine wall clock step since last iteration - float get_cpu_process_step(); + double get_cpu_process_step(); public: MainTimerSync(); @@ -96,7 +96,7 @@ public: void set_fixed_fps(int p_fixed_fps); // advance one frame, return timesteps to take - MainFrameTime advance(float p_physics_step, int p_physics_fps); + MainFrameTime advance(double p_physics_step, int p_physics_fps); }; #endif // MAIN_TIMER_SYNC_H diff --git a/main/performance.cpp b/main/performance.cpp index a2e53f2ee2..f9ff34c05d 100644 --- a/main/performance.cpp +++ b/main/performance.cpp @@ -60,16 +60,12 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(OBJECT_RESOURCE_COUNT); BIND_ENUM_CONSTANT(OBJECT_NODE_COUNT); BIND_ENUM_CONSTANT(OBJECT_ORPHAN_NODE_COUNT); - BIND_ENUM_CONSTANT(RENDER_OBJECTS_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_VERTICES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_MATERIAL_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_SHADER_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_SURFACE_CHANGES_IN_FRAME); - BIND_ENUM_CONSTANT(RENDER_DRAW_CALLS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_OBJECTS_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_PRIMITIVES_IN_FRAME); + BIND_ENUM_CONSTANT(RENDER_TOTAL_DRAW_CALLS_IN_FRAME); BIND_ENUM_CONSTANT(RENDER_VIDEO_MEM_USED); BIND_ENUM_CONSTANT(RENDER_TEXTURE_MEM_USED); - BIND_ENUM_CONSTANT(RENDER_VERTEX_MEM_USED); - BIND_ENUM_CONSTANT(RENDER_USAGE_VIDEO_MEM_TOTAL); + BIND_ENUM_CONSTANT(RENDER_BUFFER_MEM_USED); BIND_ENUM_CONSTANT(PHYSICS_2D_ACTIVE_OBJECTS); BIND_ENUM_CONSTANT(PHYSICS_2D_COLLISION_PAIRS); BIND_ENUM_CONSTANT(PHYSICS_2D_ISLAND_COUNT); @@ -81,7 +77,7 @@ void Performance::_bind_methods() { BIND_ENUM_CONSTANT(MONITOR_MAX); } -float Performance::_get_node_count() const { +int Performance::_get_node_count() const { MainLoop *ml = OS::get_singleton()->get_main_loop(); SceneTree *sml = Object::cast_to<SceneTree>(ml); if (!sml) { @@ -103,16 +99,12 @@ String Performance::get_monitor_name(Monitor p_monitor) const { "object/resources", "object/nodes", "object/orphan_nodes", - "raster/objects_drawn", - "raster/vertices_drawn", - "raster/mat_changes", - "raster/shader_changes", - "raster/surface_changes", - "raster/draw_calls", + "raster/total_objects_drawn", + "raster/total_primitives_drawn", + "raster/total_draw_calls", "video/video_mem", "video/texture_mem", - "video/vertex_mem", - "video/video_mem_max", + "video/buffer_mem", "physics_2d/active_objects", "physics_2d/collision_pairs", "physics_2d/islands", @@ -126,7 +118,7 @@ String Performance::get_monitor_name(Monitor p_monitor) const { return names[p_monitor]; } -float Performance::get_monitor(Monitor p_monitor) const { +double Performance::get_monitor(Monitor p_monitor) const { switch (p_monitor) { case TIME_FPS: return Engine::get_singleton()->get_frames_per_second(); @@ -148,26 +140,18 @@ float Performance::get_monitor(Monitor p_monitor) const { return _get_node_count(); case OBJECT_ORPHAN_NODE_COUNT: return Node::orphan_node_count; - case RENDER_OBJECTS_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_OBJECTS_IN_FRAME); - case RENDER_VERTICES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_VERTICES_IN_FRAME); - case RENDER_MATERIAL_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME); - case RENDER_SHADER_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME); - case RENDER_SURFACE_CHANGES_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME); - case RENDER_DRAW_CALLS_IN_FRAME: - return RS::get_singleton()->get_render_info(RS::INFO_DRAW_CALLS_IN_FRAME); + case RENDER_TOTAL_OBJECTS_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_OBJECTS_IN_FRAME); + case RENDER_TOTAL_PRIMITIVES_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_PRIMITIVES_IN_FRAME); + case RENDER_TOTAL_DRAW_CALLS_IN_FRAME: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME); case RENDER_VIDEO_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_VIDEO_MEM_USED); + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_VIDEO_MEM_USED); case RENDER_TEXTURE_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED); - case RENDER_VERTEX_MEM_USED: - return RS::get_singleton()->get_render_info(RS::INFO_VERTEX_MEM_USED); - case RENDER_USAGE_VIDEO_MEM_TOTAL: - return RS::get_singleton()->get_render_info(RS::INFO_USAGE_VIDEO_MEM_TOTAL); + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_TEXTURE_MEM_USED); + case RENDER_BUFFER_MEM_USED: + return RS::get_singleton()->get_rendering_info(RS::RENDERING_INFO_BUFFER_MEM_USED); case PHYSICS_2D_ACTIVE_OBJECTS: return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ACTIVE_OBJECTS); case PHYSICS_2D_COLLISION_PAIRS: @@ -207,10 +191,6 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const MONITOR_TYPE_QUANTITY, MONITOR_TYPE_QUANTITY, MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_QUANTITY, - MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, MONITOR_TYPE_MEMORY, @@ -227,11 +207,11 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const return types[p_monitor]; } -void Performance::set_process_time(float p_pt) { +void Performance::set_process_time(double p_pt) { _process_time = p_pt; } -void Performance::set_physics_process_time(float p_pt) { +void Performance::set_physics_process_time(double p_pt) { _physics_process_time = p_pt; } diff --git a/main/performance.h b/main/performance.h index 122e5a4f9a..4653051ebb 100644 --- a/main/performance.h +++ b/main/performance.h @@ -43,10 +43,10 @@ class Performance : public Object { static Performance *singleton; static void _bind_methods(); - float _get_node_count() const; + int _get_node_count() const; - float _process_time; - float _physics_process_time; + double _process_time; + double _physics_process_time; class MonitorCall { Callable _callable; @@ -73,16 +73,12 @@ public: OBJECT_RESOURCE_COUNT, OBJECT_NODE_COUNT, OBJECT_ORPHAN_NODE_COUNT, - RENDER_OBJECTS_IN_FRAME, - RENDER_VERTICES_IN_FRAME, - RENDER_MATERIAL_CHANGES_IN_FRAME, - RENDER_SHADER_CHANGES_IN_FRAME, - RENDER_SURFACE_CHANGES_IN_FRAME, - RENDER_DRAW_CALLS_IN_FRAME, + RENDER_TOTAL_OBJECTS_IN_FRAME, + RENDER_TOTAL_PRIMITIVES_IN_FRAME, + RENDER_TOTAL_DRAW_CALLS_IN_FRAME, RENDER_VIDEO_MEM_USED, RENDER_TEXTURE_MEM_USED, - RENDER_VERTEX_MEM_USED, - RENDER_USAGE_VIDEO_MEM_TOTAL, + RENDER_BUFFER_MEM_USED, PHYSICS_2D_ACTIVE_OBJECTS, PHYSICS_2D_COLLISION_PAIRS, PHYSICS_2D_ISLAND_COUNT, @@ -100,13 +96,13 @@ public: MONITOR_TYPE_TIME }; - float get_monitor(Monitor p_monitor) const; + double get_monitor(Monitor p_monitor) const; String get_monitor_name(Monitor p_monitor) const; MonitorType get_monitor_type(Monitor p_monitor) const; - void set_process_time(float p_pt); - void set_physics_process_time(float p_pt); + void set_process_time(double p_pt); + void set_physics_process_time(double p_pt); void add_custom_monitor(const StringName &p_id, const Callable &p_callable, const Vector<Variant> &p_args); void remove_custom_monitor(const StringName &p_id); |