Browse Source

Merge pull request #104093 from akien-mga/4.4-cherrypicks

[4.4] Cherry-picks for the 4.4 branch (future 4.4.1) - 2nd batch
Rémi Verschelde 6 tháng trước cách đây
mục cha
commit
0b1ab74af9

+ 24 - 3
core/io/resource_loader.cpp

@@ -264,6 +264,14 @@ void ResourceLoader::LoadToken::clear() {
 				thread_load_tasks.erase(local_path);
 				thread_load_tasks.erase(local_path);
 			}
 			}
 			local_path.clear(); // Mark as already cleared.
 			local_path.clear(); // Mark as already cleared.
+			if (task_to_await) {
+				for (KeyValue<String, ResourceLoader::ThreadLoadTask> &E : thread_load_tasks) {
+					if (E.value.task_id == task_to_await) {
+						task_to_await = 0;
+						break; // Same task is reused by nested loads, do not wait for completion here.
+					}
+				}
+			}
 		}
 		}
 	}
 	}
 
 
@@ -772,6 +780,10 @@ Ref<Resource> ResourceLoader::_load_complete(LoadToken &p_load_token, Error *r_e
 	return _load_complete_inner(p_load_token, r_error, thread_load_lock);
 	return _load_complete_inner(p_load_token, r_error, thread_load_lock);
 }
 }
 
 
+void ResourceLoader::set_is_import_thread(bool p_import_thread) {
+	import_thread = p_import_thread;
+}
+
 Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock<SafeBinaryMutex<BINARY_MUTEX_TAG>> &p_thread_load_lock) {
 Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Error *r_error, MutexLock<SafeBinaryMutex<BINARY_MUTEX_TAG>> &p_thread_load_lock) {
 	if (r_error) {
 	if (r_error) {
 		*r_error = OK;
 		*r_error = OK;
@@ -825,6 +837,12 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
 
 
 				p_thread_load_lock.temp_relock();
 				p_thread_load_lock.temp_relock();
 				load_task.awaited = true;
 				load_task.awaited = true;
+				// Mark nested loads with the same task id as awaited.
+				for (KeyValue<String, ResourceLoader::ThreadLoadTask> &E : thread_load_tasks) {
+					if (E.value.task_id == load_task.task_id) {
+						E.value.awaited = true;
+					}
+				}
 
 
 				DEV_ASSERT(load_task.status == THREAD_LOAD_FAILED || load_task.status == THREAD_LOAD_LOADED);
 				DEV_ASSERT(load_task.status == THREAD_LOAD_FAILED || load_task.status == THREAD_LOAD_LOADED);
 			} else if (load_task.need_wait) {
 			} else if (load_task.need_wait) {
@@ -886,9 +904,11 @@ Ref<Resource> ResourceLoader::_load_complete_inner(LoadToken &p_load_token, Erro
 							MessageQueue::get_main_singleton()->push_callable(callable_mp(rcc.source, &Resource::connect_changed).bind(rcc.callable, rcc.flags));
 							MessageQueue::get_main_singleton()->push_callable(callable_mp(rcc.source, &Resource::connect_changed).bind(rcc.callable, rcc.flags));
 						}
 						}
 					}
 					}
-					core_bind::Semaphore done;
-					MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &core_bind::Semaphore::post).bind(1));
-					done.wait();
+					if (!import_thread) { // Main thread is blocked by initial resource reimport, do not wait.
+						core_bind::Semaphore done;
+						MessageQueue::get_main_singleton()->push_callable(callable_mp(&done, &core_bind::Semaphore::post).bind(1));
+						done.wait();
+					}
 				}
 				}
 			}
 			}
 		}
 		}
@@ -1565,6 +1585,7 @@ bool ResourceLoader::create_missing_resources_if_class_unavailable = false;
 bool ResourceLoader::abort_on_missing_resource = true;
 bool ResourceLoader::abort_on_missing_resource = true;
 bool ResourceLoader::timestamp_on_load = false;
 bool ResourceLoader::timestamp_on_load = false;
 
 
+thread_local bool ResourceLoader::import_thread = false;
 thread_local int ResourceLoader::load_nesting = 0;
 thread_local int ResourceLoader::load_nesting = 0;
 thread_local Vector<String> ResourceLoader::load_paths_stack;
 thread_local Vector<String> ResourceLoader::load_paths_stack;
 thread_local HashMap<int, HashMap<String, Ref<Resource>>> ResourceLoader::res_ref_overrides;
 thread_local HashMap<int, HashMap<String, Ref<Resource>>> ResourceLoader::res_ref_overrides;

+ 3 - 0
core/io/resource_loader.h

@@ -205,6 +205,7 @@ private:
 
 
 	static void _run_load_task(void *p_userdata);
 	static void _run_load_task(void *p_userdata);
 
 
+	static thread_local bool import_thread;
 	static thread_local int load_nesting;
 	static thread_local int load_nesting;
 	static thread_local HashMap<int, HashMap<String, Ref<Resource>>> res_ref_overrides; // Outermost key is nesting level.
 	static thread_local HashMap<int, HashMap<String, Ref<Resource>>> res_ref_overrides; // Outermost key is nesting level.
 	static thread_local Vector<String> load_paths_stack;
 	static thread_local Vector<String> load_paths_stack;
@@ -254,6 +255,8 @@ public:
 	static bool is_imported(const String &p_path);
 	static bool is_imported(const String &p_path);
 	static int get_import_order(const String &p_path);
 	static int get_import_order(const String &p_path);
 
 
+	static void set_is_import_thread(bool p_import_thread);
+
 	static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
 	static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load = p_timestamp; }
 	static bool get_timestamp_on_load() { return timestamp_on_load; }
 	static bool get_timestamp_on_load() { return timestamp_on_load; }
 
 

+ 3 - 0
doc/classes/Node.xml

@@ -1226,6 +1226,9 @@
 		<constant name="NOTIFICATION_VP_MOUSE_EXIT" value="1011">
 		<constant name="NOTIFICATION_VP_MOUSE_EXIT" value="1011">
 			Notification received when the mouse cursor leaves the [Viewport]'s visible area, that is not occluded behind other [Control]s or [Window]s, provided its [member Viewport.gui_disable_input] is [code]false[/code] and regardless if it's currently focused or not.
 			Notification received when the mouse cursor leaves the [Viewport]'s visible area, that is not occluded behind other [Control]s or [Window]s, provided its [member Viewport.gui_disable_input] is [code]false[/code] and regardless if it's currently focused or not.
 		</constant>
 		</constant>
+		<constant name="NOTIFICATION_WM_POSITION_CHANGED" value="1012">
+			Notification received when the window is moved.
+		</constant>
 		<constant name="NOTIFICATION_OS_MEMORY_WARNING" value="2009">
 		<constant name="NOTIFICATION_OS_MEMORY_WARNING" value="2009">
 			Notification received from the OS when the application is exceeding its allocated memory.
 			Notification received from the OS when the application is exceeding its allocated memory.
 			Implemented only on iOS.
 			Implemented only on iOS.

+ 3 - 0
drivers/gles3/storage/utilities.cpp

@@ -421,6 +421,9 @@ bool Utilities::has_os_feature(const String &p_feature) const {
 	if (p_feature == "etc2") {
 	if (p_feature == "etc2") {
 		return config->etc2_supported;
 		return config->etc2_supported;
 	}
 	}
+	if (p_feature == "astc_hdr") {
+		return config->astc_hdr_supported;
+	}
 
 
 	return false;
 	return false;
 }
 }

+ 3 - 0
editor/editor_file_system.cpp

@@ -3107,8 +3107,11 @@ void EditorFileSystem::_refresh_filesystem() {
 }
 }
 
 
 void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
 void EditorFileSystem::_reimport_thread(uint32_t p_index, ImportThreadData *p_import_data) {
+	ResourceLoader::set_is_import_thread(true);
 	int file_idx = p_import_data->reimport_from + int(p_index);
 	int file_idx = p_import_data->reimport_from + int(p_index);
 	_reimport_file(p_import_data->reimport_files[file_idx].path);
 	_reimport_file(p_import_data->reimport_files[file_idx].path);
+	ResourceLoader::set_is_import_thread(false);
+
 	p_import_data->imported_sem->post();
 	p_import_data->imported_sem->post();
 }
 }
 
 

+ 32 - 3
editor/export/export_template_manager.cpp

@@ -43,6 +43,7 @@
 #include "editor/progress_dialog.h"
 #include "editor/progress_dialog.h"
 #include "editor/themes/editor_scale.h"
 #include "editor/themes/editor_scale.h"
 #include "scene/gui/file_dialog.h"
 #include "scene/gui/file_dialog.h"
+#include "scene/gui/link_button.h"
 #include "scene/gui/menu_button.h"
 #include "scene/gui/menu_button.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/tree.h"
 #include "scene/gui/tree.h"
@@ -56,9 +57,6 @@ enum DownloadsAvailability {
 
 
 static DownloadsAvailability _get_downloads_availability() {
 static DownloadsAvailability _get_downloads_availability() {
 	const int network_mode = EDITOR_GET("network/connection/network_mode");
 	const int network_mode = EDITOR_GET("network/connection/network_mode");
-	if (network_mode == EditorSettings::NETWORK_OFFLINE) {
-		return DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE;
-	}
 
 
 	// Downloadable export templates are only available for stable and official alpha/beta/RC builds
 	// Downloadable export templates are only available for stable and official alpha/beta/RC builds
 	// (which always have a number following their status, e.g. "alpha1").
 	// (which always have a number following their status, e.g. "alpha1").
@@ -71,6 +69,10 @@ static DownloadsAvailability _get_downloads_availability() {
 		return DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS;
 		return DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS;
 	}
 	}
 
 
+	if (network_mode == EditorSettings::NETWORK_OFFLINE) {
+		return DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE;
+	}
+
 	return DOWNLOADS_AVAILABLE;
 	return DOWNLOADS_AVAILABLE;
 }
 }
 
 
@@ -335,6 +337,14 @@ void ExportTemplateManager::_refresh_mirrors_completed(int p_status, int p_code,
 	}
 	}
 }
 }
 
 
+void ExportTemplateManager::_force_online_mode() {
+	EditorSettings::get_singleton()->set_setting("network/connection/network_mode", EditorSettings::NETWORK_ONLINE);
+	EditorSettings::get_singleton()->notify_changes();
+	EditorSettings::get_singleton()->save();
+
+	popup_manager();
+}
+
 bool ExportTemplateManager::_humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes) {
 bool ExportTemplateManager::_humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes) {
 	*r_status = "";
 	*r_status = "";
 	*r_downloaded_bytes = -1;
 	*r_downloaded_bytes = -1;
@@ -694,6 +704,8 @@ void ExportTemplateManager::popup_manager() {
 			if (!is_downloading_templates) {
 			if (!is_downloading_templates) {
 				_refresh_mirrors();
 				_refresh_mirrors();
 			}
 			}
+
+			enable_online_hb->hide();
 		} break;
 		} break;
 
 
 		case DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE: {
 		case DOWNLOADS_NOT_AVAILABLE_IN_OFFLINE_MODE: {
@@ -708,6 +720,8 @@ void ExportTemplateManager::popup_manager() {
 
 
 			download_current_button->set_disabled(true);
 			download_current_button->set_disabled(true);
 			download_current_button->set_tooltip_text(TTR("Template downloading is disabled in offline mode."));
 			download_current_button->set_tooltip_text(TTR("Template downloading is disabled in offline mode."));
+
+			enable_online_hb->show();
 		} break;
 		} break;
 
 
 		case DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS: {
 		case DOWNLOADS_NOT_AVAILABLE_FOR_DEV_BUILDS: {
@@ -722,6 +736,8 @@ void ExportTemplateManager::popup_manager() {
 
 
 			download_current_button->set_disabled(true);
 			download_current_button->set_disabled(true);
 			download_current_button->set_tooltip_text(TTR("Official export templates aren't available for development builds."));
 			download_current_button->set_tooltip_text(TTR("Official export templates aren't available for development builds."));
+
+			enable_online_hb->hide();
 		} break;
 		} break;
 	}
 	}
 
 
@@ -1053,6 +1069,19 @@ ExportTemplateManager::ExportTemplateManager() {
 	install_file_hb->add_child(install_file_button);
 	install_file_hb->add_child(install_file_button);
 	install_file_button->connect(SceneStringName(pressed), callable_mp(this, &ExportTemplateManager::_install_file));
 	install_file_button->connect(SceneStringName(pressed), callable_mp(this, &ExportTemplateManager::_install_file));
 
 
+	enable_online_hb = memnew(HBoxContainer);
+	install_options_vb->add_child(enable_online_hb);
+
+	Label *enable_online_label = memnew(Label);
+	enable_online_label->set_text(TTR("Online mode is needed to download the templates."));
+	enable_online_hb->add_child(enable_online_label);
+
+	LinkButton *enable_online_button = memnew(LinkButton);
+	enable_online_button->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
+	enable_online_button->set_text(TTR("Go Online"));
+	enable_online_hb->add_child(enable_online_button);
+	enable_online_button->connect(SceneStringName(pressed), callable_mp(this, &ExportTemplateManager::_force_online_mode));
+
 	// Templates are being downloaded; buttons unavailable.
 	// Templates are being downloaded; buttons unavailable.
 	download_progress_hb = memnew(HBoxContainer);
 	download_progress_hb = memnew(HBoxContainer);
 	download_progress_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
 	download_progress_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);

+ 2 - 0
editor/export/export_template_manager.h

@@ -68,6 +68,7 @@ class ExportTemplateManager : public AcceptDialog {
 	};
 	};
 
 
 	MenuButton *mirror_options_button = nullptr;
 	MenuButton *mirror_options_button = nullptr;
+	HBoxContainer *enable_online_hb = nullptr;
 	HBoxContainer *download_progress_hb = nullptr;
 	HBoxContainer *download_progress_hb = nullptr;
 	ProgressBar *download_progress_bar = nullptr;
 	ProgressBar *download_progress_bar = nullptr;
 	Label *download_progress_label = nullptr;
 	Label *download_progress_label = nullptr;
@@ -96,6 +97,7 @@ class ExportTemplateManager : public AcceptDialog {
 	void _cancel_template_download();
 	void _cancel_template_download();
 	void _refresh_mirrors();
 	void _refresh_mirrors();
 	void _refresh_mirrors_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
 	void _refresh_mirrors_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data);
+	void _force_online_mode();
 
 
 	bool _humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes);
 	bool _humanize_http_status(HTTPRequest *p_request, String *r_status, int *r_downloaded_bytes, int *r_total_bytes);
 	void _set_current_progress_status(const String &p_status, bool p_error = false);
 	void _set_current_progress_status(const String &p_status, bool p_error = false);

+ 2 - 1
modules/basis_universal/image_compress_basisu.cpp

@@ -275,6 +275,7 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
 	bool rgtc_supported = RS::get_singleton()->has_os_feature("rgtc");
 	bool rgtc_supported = RS::get_singleton()->has_os_feature("rgtc");
 	bool s3tc_supported = RS::get_singleton()->has_os_feature("s3tc");
 	bool s3tc_supported = RS::get_singleton()->has_os_feature("s3tc");
 	bool etc2_supported = RS::get_singleton()->has_os_feature("etc2");
 	bool etc2_supported = RS::get_singleton()->has_os_feature("etc2");
+	bool astc_hdr_supported = RS::get_singleton()->has_os_feature("astc_hdr");
 
 
 	bool needs_ra_rg_swap = false;
 	bool needs_ra_rg_swap = false;
 	bool needs_rg_trim = false;
 	bool needs_rg_trim = false;
@@ -379,7 +380,7 @@ Ref<Image> basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size) {
 			if (bptc_supported) {
 			if (bptc_supported) {
 				basisu_format = basist::transcoder_texture_format::cTFBC6H;
 				basisu_format = basist::transcoder_texture_format::cTFBC6H;
 				image_format = Image::FORMAT_BPTC_RGBFU;
 				image_format = Image::FORMAT_BPTC_RGBFU;
-			} else if (astc_supported) {
+			} else if (astc_hdr_supported) {
 				basisu_format = basist::transcoder_texture_format::cTFASTC_HDR_4x4_RGBA;
 				basisu_format = basist::transcoder_texture_format::cTFASTC_HDR_4x4_RGBA;
 				image_format = Image::FORMAT_ASTC_4x4_HDR;
 				image_format = Image::FORMAT_ASTC_4x4_HDR;
 			} else {
 			} else {

+ 2 - 0
modules/interactive_music/audio_stream_interactive.h

@@ -183,6 +183,8 @@ public:
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual String get_stream_name() const override;
 	virtual String get_stream_name() const override;
 	virtual double get_length() const override { return 0; }
 	virtual double get_length() const override { return 0; }
+	virtual bool is_meta_stream() const override { return true; }
+
 	AudioStreamInteractive();
 	AudioStreamInteractive();
 
 
 protected:
 protected:

+ 1 - 0
modules/interactive_music/audio_stream_playlist.h

@@ -70,6 +70,7 @@ public:
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual String get_stream_name() const override;
 	virtual String get_stream_name() const override;
 	virtual double get_length() const override;
 	virtual double get_length() const override;
+	virtual bool is_meta_stream() const override { return true; }
 
 
 protected:
 protected:
 	static void _bind_methods();
 	static void _bind_methods();

+ 2 - 0
modules/interactive_music/audio_stream_synchronized.h

@@ -66,6 +66,8 @@ public:
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual Ref<AudioStreamPlayback> instantiate_playback() override;
 	virtual String get_stream_name() const override;
 	virtual String get_stream_name() const override;
 	virtual double get_length() const override;
 	virtual double get_length() const override;
+	virtual bool is_meta_stream() const override { return true; }
+
 	AudioStreamSynchronized();
 	AudioStreamSynchronized();
 
 
 protected:
 protected:

+ 1 - 0
scene/main/node.cpp

@@ -3820,6 +3820,7 @@ void Node::_bind_methods() {
 	BIND_CONSTANT(NOTIFICATION_WM_DPI_CHANGE);
 	BIND_CONSTANT(NOTIFICATION_WM_DPI_CHANGE);
 	BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
 	BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
 	BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
 	BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
+	BIND_CONSTANT(NOTIFICATION_WM_POSITION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
 	BIND_CONSTANT(NOTIFICATION_WM_ABOUT);

+ 3 - 0
servers/audio/effects/audio_effect_pitch_shift.cpp

@@ -288,6 +288,9 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
 void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
 void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
 	// Avoid distortion by skipping processing if pitch_scale is 1.0.
 	// Avoid distortion by skipping processing if pitch_scale is 1.0.
 	if (Math::is_equal_approx(base->pitch_scale, 1.0f)) {
 	if (Math::is_equal_approx(base->pitch_scale, 1.0f)) {
+		for (int i = 0; i < p_frame_count; i++) {
+			p_dst_frames[i] = p_src_frames[i];
+		}
 		return;
 		return;
 	}
 	}
 
 

+ 4 - 0
servers/rendering/renderer_rd/storage_rd/utilities.cpp

@@ -286,6 +286,10 @@ bool Utilities::has_os_feature(const String &p_feature) const {
 		return true;
 		return true;
 	}
 	}
 
 
+	if (p_feature == "astc_hdr" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ASTC_4x4_SFLOAT_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+		return true;
+	}
+
 	return false;
 	return false;
 }
 }