Merge pull request #98383 from RandomShaper/deprecate_unsafe_th_rend

Deprecate the pointless unsafe threading model for rendering
This commit is contained in:
Thaddeus Crews 2024-12-03 14:40:56 -06:00
commit a135a6478a
No known key found for this signature in database
GPG key ID: 62181B86FE9E5D84
5 changed files with 40 additions and 26 deletions

View file

@ -1516,7 +1516,11 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF("display/window/frame_pacing/android/enable_frame_pacing", true);
GLOBAL_DEF(PropertyInfo(Variant::INT, "display/window/frame_pacing/android/swappy_mode", PROPERTY_HINT_ENUM, "pipeline_forced_on,auto_fps_pipeline_forced_on,auto_fps_auto_pipeline"), 2);
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
#ifdef DISABLE_DEPRECATED
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Safe:1,Separate");
#else
custom_prop_info["rendering/driver/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/driver/threads/thread_model", PROPERTY_HINT_ENUM, "Unsafe (deprecated),Safe,Separate");
#endif
GLOBAL_DEF("physics/2d/run_on_separate_thread", false);
GLOBAL_DEF("physics/3d/run_on_separate_thread", false);

View file

@ -885,7 +885,7 @@ bool ResourceLoader::_ensure_load_progress() {
// Some servers may need a new engine iteration to allow the load to progress.
// Since the only known one is the rendering server (in single thread mode), let's keep it simple and just sync it.
// This may be refactored in the future to support other servers and have less coupling.
if (OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD) {
if (OS::get_singleton()->is_separate_thread_rendering_enabled()) {
return false; // Not needed.
}
RenderingServer::get_singleton()->sync();

View file

@ -111,7 +111,7 @@ protected:
friend int test_main(int argc, char *argv[]);
HasServerFeatureCallback has_server_feature_callback = nullptr;
RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
bool _separate_thread_render = false;
// Functions used by Main to initialize/deinitialize the OS.
void add_logger(Logger *p_logger);
@ -274,7 +274,7 @@ public:
virtual uint64_t get_static_memory_peak_usage() const;
virtual Dictionary get_memory_info() const;
RenderThreadMode get_render_thread_mode() const { return _render_thread_mode; }
bool is_separate_thread_rendering_enabled() const { return _separate_thread_render; }
virtual String get_locale() const;
String get_locale_language() const;

View file

@ -560,7 +560,11 @@ void Main::print_help(const char *p_binary) {
print_help_option("--path <directory>", "Path to a project (<directory> must contain a \"project.godot\" file).\n");
print_help_option("-u, --upwards", "Scan folders upwards for project.godot file.\n");
print_help_option("--main-pack <file>", "Path to a pack (.pck) file to load.\n");
print_help_option("--render-thread <mode>", "Render thread mode (\"unsafe\", \"safe\", \"separate\").\n");
#ifdef DISABLE_DEPRECATED
print_help_option("--render-thread <mode>", "Render thread mode (\"safe\", \"separate\").\n");
#else
print_help_option("--render-thread <mode>", "Render thread mode (\"unsafe\" [deprecated], \"safe\", \"separate\").\n");
#endif
print_help_option("--remote-fs <address>", "Remote filesystem (<host/IP>[:<port>] address).\n");
print_help_option("--remote-fs-password <password>", "Password for remote filesystem.\n");
@ -1003,7 +1007,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool skip_breakpoints = false;
String main_pack;
bool quiet_stdout = false;
int rtm = -1;
int separate_thread_render = -1; // Tri-state: -1 = not set, 0 = false, 1 = true.
String remotefs;
String remotefs_pass;
@ -1398,13 +1402,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (N) {
if (N->get() == "safe") {
rtm = OS::RENDER_THREAD_SAFE;
separate_thread_render = 0;
#ifndef DISABLE_DEPRECATED
} else if (N->get() == "unsafe") {
rtm = OS::RENDER_THREAD_UNSAFE;
OS::get_singleton()->print("The --render-thread unsafe option is unsupported in Godot 4 and will be removed.\n");
separate_thread_render = 0;
#endif
} else if (N->get() == "separate") {
rtm = OS::RENDER_SEPARATE_THREAD;
separate_thread_render = 1;
} else {
OS::get_singleton()->print("Unknown render thread mode, aborting.\nValid options are 'unsafe', 'safe' and 'separate'.\n");
OS::get_singleton()->print("Unknown render thread mode, aborting.\n");
#ifdef DISABLE_DEPRECATED
OS::get_singleton()->print("Valid options are 'safe' and 'separate'.\n");
#else
OS::get_singleton()->print("Valid options are 'unsafe', 'safe' and 'separate'.\n");
#endif
goto error;
}
@ -2502,20 +2514,18 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
#endif
if (rtm == -1) {
rtm = GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE);
if (separate_thread_render == -1) {
separate_thread_render = (int)GLOBAL_DEF("rendering/driver/threads/thread_model", OS::RENDER_THREAD_SAFE) == OS::RENDER_SEPARATE_THREAD;
}
if (rtm >= 0 && rtm < 3) {
if (editor || project_manager) {
// Editor and project manager cannot run with rendering in a separate thread (they will crash on startup).
rtm = OS::RENDER_THREAD_SAFE;
}
#if !defined(THREADS_ENABLED)
rtm = OS::RENDER_THREAD_SAFE;
#endif
OS::get_singleton()->_render_thread_mode = OS::RenderThreadMode(rtm);
if (editor || project_manager) {
// Editor and project manager cannot run with rendering in a separate thread (they will crash on startup).
separate_thread_render = 0;
}
#if !defined(THREADS_ENABLED)
separate_thread_render = 0;
#endif
OS::get_singleton()->_separate_thread_render = separate_thread_render;
/* Determine audio and video drivers */
@ -3067,10 +3077,10 @@ Error Main::setup2(bool p_show_boot_logo) {
}
}
if (OS::get_singleton()->_render_thread_mode == OS::RENDER_SEPARATE_THREAD) {
WARN_PRINT("The Multi-Threaded rendering thread model is experimental. Feel free to try it since it will eventually become a stable feature.\n"
if (OS::get_singleton()->_separate_thread_render) {
WARN_PRINT("The separate rendering thread feature is experimental. Feel free to try it since it will eventually become a stable feature.\n"
"However, bear in mind that at the moment it can lead to project crashes or instability.\n"
"So, unless you want to test the engine, use the Single-Safe option in the project settings instead.");
"So, unless you want to test the engine, set the \"rendering/driver/threads/thread_model\" project setting to 'Safe'.");
}
/* Initialize Pen Tablet Driver */
@ -3109,7 +3119,7 @@ Error Main::setup2(bool p_show_boot_logo) {
{
OS::get_singleton()->benchmark_begin_measure("Servers", "Rendering");
rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->get_render_thread_mode() == OS::RENDER_SEPARATE_THREAD));
rendering_server = memnew(RenderingServerDefault(OS::get_singleton()->is_separate_thread_rendering_enabled()));
rendering_server->init();
//rendering_server->call_set_use_vsync(OS::get_singleton()->_use_vsync);

View file

@ -51,7 +51,7 @@ void OS_MacOS::pre_wait_observer_cb(CFRunLoopObserverRef p_observer, CFRunLoopAc
// Do not redraw when rendering is done from the separate thread, it will conflict with the OpenGL context updates.
DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
if (get_singleton()->get_main_loop() && ds && (get_singleton()->get_render_thread_mode() != RENDER_SEPARATE_THREAD) && !ds->get_is_resizing()) {
if (get_singleton()->get_main_loop() && ds && !get_singleton()->is_separate_thread_rendering_enabled() && !ds->get_is_resizing()) {
Main::force_redraw();
if (!Main::is_iterating()) { // Avoid cyclic loop.
Main::iteration();