瀏覽代碼

Merge pull request #82241 from akien-mga/3.5-cherrypicks

Cherry-picks for the 3.5 branch (future 3.5.3) - 4th batch
Rémi Verschelde 1 年之前
父節點
當前提交
2d2a2aabc1

+ 1 - 1
doc/classes/ProjectSettings.xml

@@ -1215,7 +1215,7 @@
 			Default map up vector for 3D navigation maps. See [method NavigationServer.map_set_up].
 			Default map up vector for 3D navigation maps. See [method NavigationServer.map_set_up].
 		</member>
 		</member>
 		<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
 		<member name="network/limits/debugger_stdout/max_chars_per_second" type="int" setter="" getter="" default="2048">
-			Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
+			Maximum amount of characters allowed to send as output from the debugger. Over this value, content is dropped with the message [code]"output overflow, print less text!"[/code]. This helps not to stall the debugger connection.
 		</member>
 		</member>
 		<member name="network/limits/debugger_stdout/max_errors_per_second" type="int" setter="" getter="" default="100">
 		<member name="network/limits/debugger_stdout/max_errors_per_second" type="int" setter="" getter="" default="100">
 			Maximum number of errors allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.
 			Maximum number of errors allowed to be sent as output from the debugger. Over this value, content is dropped. This helps not to stall the debugger connection.

+ 5 - 5
main/main.cpp

@@ -952,15 +952,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
 	// Initialize user data dir.
 	// Initialize user data dir.
 	OS::get_singleton()->ensure_user_data_dir();
 	OS::get_singleton()->ensure_user_data_dir();
 
 
-	GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60);
+	GLOBAL_DEF_RST("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, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1")); // No negative and limit to 500 due to crashes
 	ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/multithreaded_server/rid_pool_prealloc", PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1")); // No negative and limit to 500 due to crashes
-	GLOBAL_DEF("network/limits/debugger_stdout/max_chars_per_second", 2048);
+	GLOBAL_DEF_RST("network/limits/debugger_stdout/max_chars_per_second", 2048);
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater"));
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_chars_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_chars_per_second", PROPERTY_HINT_RANGE, "0, 4096, 1, or_greater"));
-	GLOBAL_DEF("network/limits/debugger_stdout/max_messages_per_frame", 10);
+	GLOBAL_DEF_RST("network/limits/debugger_stdout/max_messages_per_frame", 10);
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_messages_per_frame", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_messages_per_frame", PROPERTY_HINT_RANGE, "0, 20, 1, or_greater"));
-	GLOBAL_DEF("network/limits/debugger_stdout/max_errors_per_second", 100);
+	GLOBAL_DEF_RST("network/limits/debugger_stdout/max_errors_per_second", 100);
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_errors_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_errors_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
-	GLOBAL_DEF("network/limits/debugger_stdout/max_warnings_per_second", 100);
+	GLOBAL_DEF_RST("network/limits/debugger_stdout/max_warnings_per_second", 100);
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_warnings_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_warnings_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
 	ProjectSettings::get_singleton()->set_custom_property_info("network/limits/debugger_stdout/max_warnings_per_second", PropertyInfo(Variant::INT, "network/limits/debugger_stdout/max_warnings_per_second", PROPERTY_HINT_RANGE, "0, 200, 1, or_greater"));
 
 
 	if (debug_mode == "remote") {
 	if (debug_mode == "remote") {

+ 11 - 0
methods.py

@@ -944,6 +944,17 @@ def get_compiler_version(env):
         return None
         return None
 
 
 
 
+def is_vanilla_clang(env):
+    if not using_clang(env):
+        return False
+    try:
+        version = decode_utf8(subprocess.check_output([env.subst(env["CXX"]), "--version"]).strip())
+    except (subprocess.CalledProcessError, OSError):
+        print("Couldn't parse CXX environment variable to infer compiler version.")
+        return False
+    return not version.startswith("Apple")
+
+
 def using_gcc(env):
 def using_gcc(env):
     return "gcc" in os.path.basename(env["CC"])
     return "gcc" in os.path.basename(env["CC"])
 
 

+ 11 - 4
platform/osx/detect.py

@@ -1,6 +1,6 @@
 import os
 import os
 import sys
 import sys
-from methods import detect_darwin_sdk_path
+from methods import detect_darwin_sdk_path, get_compiler_version, is_vanilla_clang
 
 
 
 
 def is_active():
 def is_active():
@@ -78,14 +78,21 @@ def configure(env):
         env["osxcross"] = True
         env["osxcross"] = True
 
 
     if env["arch"] == "arm64":
     if env["arch"] == "arm64":
-        print("Building for macOS 10.15+, platform arm64.")
-        env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
-        env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=10.15"])
+        print("Building for macOS 11.0+, platform arm64.")
+        env.Append(CCFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
+        env.Append(LINKFLAGS=["-arch", "arm64", "-mmacosx-version-min=11.0"])
     else:
     else:
         print("Building for macOS 10.12+, platform x86-64.")
         print("Building for macOS 10.12+, platform x86-64.")
         env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(CCFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
         env.Append(LINKFLAGS=["-arch", "x86_64", "-mmacosx-version-min=10.12"])
 
 
+    cc_version = get_compiler_version(env) or [-1, -1]
+    vanilla = is_vanilla_clang(env)
+
+    # Workaround for Xcode 15 linker bug.
+    if not vanilla and cc_version[0] == 15 and cc_version[1] == 0:
+        env.Prepend(LINKFLAGS=["-ld_classic"])
+
     if not "osxcross" in env:  # regular native build
     if not "osxcross" in env:  # regular native build
         if env["macports_clang"] != "no":
         if env["macports_clang"] != "no":
             mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")
             mpprefix = os.environ.get("MACPORTS_PREFIX", "/opt/local")

+ 1 - 1
platform/osx/os_osx.mm

@@ -474,7 +474,7 @@ static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) {
 @implementation GodotContentView
 @implementation GodotContentView
 
 
 - (void)drawRect:(NSRect)dirtyRect {
 - (void)drawRect:(NSRect)dirtyRect {
-	if (OS_OSX::singleton->get_main_loop() && OS_OSX::singleton->is_resizing) {
+	if (OS_OSX::singleton->get_main_loop() && (OS_OSX::singleton->get_render_thread_mode() != OS::RENDER_SEPARATE_THREAD) && OS_OSX::singleton->is_resizing) {
 		Main::force_redraw();
 		Main::force_redraw();
 		if (!Main::is_iterating()) { // Avoid cyclic loop.
 		if (!Main::is_iterating()) { // Avoid cyclic loop.
 			Main::iteration();
 			Main::iteration();

+ 91 - 0
platform/uwp/export/export.cpp

@@ -1200,6 +1200,51 @@ public:
 		return valid;
 		return valid;
 	}
 	}
 
 
+#ifdef WINDOWS_ENABLED
+	void extract_all_files_from_zip(String zip_file_path, String extract_path) {
+		FileAccess *src_f = nullptr;
+		zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+		unzFile pkg = unzOpen2(zip_file_path.utf8().get_data(), &io);
+
+		int ret = unzGoToFirstFile(pkg);
+
+		while (ret == UNZ_OK) {
+			// get file name
+			unz_file_info info;
+			char fname[16384];
+			ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
+
+			String path = String::utf8(fname);
+
+			//write the files
+			Vector<uint8_t> data;
+
+			//read
+			data.resize(info.uncompressed_size);
+			unzOpenCurrentFile(pkg);
+			unzReadCurrentFile(pkg, data.ptrw(), data.size());
+			unzCloseCurrentFile(pkg);
+
+			//check if the subfolder doesn't exist and create it
+			String file_path = extract_path + "/" + path.get_base_dir();
+			DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+			if (!da->dir_exists(file_path)) {
+				da->make_dir_recursive(file_path);
+			}
+			memdelete(da);
+
+			FileAccess *unzipped_file = FileAccess::open(extract_path + "/" + path, FileAccess::WRITE);
+			unzipped_file->store_buffer(data.ptrw(), data.size());
+			unzipped_file->close();
+
+			ret = unzGoToNextFile(pkg);
+		}
+
+		unzClose(pkg);
+	}
+#endif
+
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
 	virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
 		ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
 		ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
 
 
@@ -1389,6 +1434,50 @@ public:
 		packager.finish();
 		packager.finish();
 
 
 #ifdef WINDOWS_ENABLED
 #ifdef WINDOWS_ENABLED
+		// Repackage it with makeappx if available
+		String makeappx_path = EditorSettings::get_singleton()->get("export/uwp/makeappx");
+		if (makeappx_path != String()) {
+			if (FileAccess::exists(makeappx_path)) {
+				// Get uwp_temp_path
+				String uwp_temp_path = EditorSettings::get_singleton()->get_cache_dir() + "/uwptemp";
+
+				// Extract current appx file
+				extract_all_files_from_zip(p_path, uwp_temp_path);
+
+				// Call makeappx
+				List<String> args_makeappx;
+				args_makeappx.push_back("pack");
+				args_makeappx.push_back("/d");
+				args_makeappx.push_back(uwp_temp_path);
+				args_makeappx.push_back("/p");
+				args_makeappx.push_back(p_path);
+				args_makeappx.push_back("/o");
+
+				OS::get_singleton()->execute(makeappx_path, args_makeappx, true);
+
+				// Delete uwp_temp_path folder recursively
+				DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+				Error err = da->change_dir(uwp_temp_path);
+				if (err == OK) {
+					err = da->erase_contents_recursive();
+					if (err != OK) {
+						ERR_PRINT("Could not delete UWP temporary folder: '" + uwp_temp_path + "'.");
+						return err;
+					} else {
+						da->remove(uwp_temp_path);
+					}
+				} else {
+					ERR_PRINT("Could not change dir to UWP temporary folder: '" + uwp_temp_path + "'.");
+					ERR_PRINT("Could not delete UWP temporary folder: '" + uwp_temp_path + "'.");
+					return err;
+				}
+				memdelete(da);
+			} else {
+				ERR_PRINT("Could not find makeappx executable at " + makeappx_path + ", aborting.");
+				return ERR_FILE_NOT_FOUND;
+			}
+		}
+
 		// Sign with signtool
 		// Sign with signtool
 		String signtool_path = EditorSettings::get_singleton()->get("export/uwp/signtool");
 		String signtool_path = EditorSettings::get_singleton()->get("export/uwp/signtool");
 		if (signtool_path == String()) {
 		if (signtool_path == String()) {
@@ -1466,6 +1555,8 @@ void register_uwp_exporter() {
 #ifdef WINDOWS_ENABLED
 #ifdef WINDOWS_ENABLED
 	EDITOR_DEF("export/uwp/signtool", "");
 	EDITOR_DEF("export/uwp/signtool", "");
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/signtool", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/signtool", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
+	EDITOR_DEF("export/uwp/makeappx", "");
+	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/makeappx", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
 	EDITOR_DEF("export/uwp/debug_certificate", "");
 	EDITOR_DEF("export/uwp/debug_certificate", "");
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/debug_certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx"));
 	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/debug_certificate", PROPERTY_HINT_GLOBAL_FILE, "*.pfx"));
 	EDITOR_DEF("export/uwp/debug_password", "");
 	EDITOR_DEF("export/uwp/debug_password", "");

+ 14 - 0
scene/gui/button.cpp

@@ -31,6 +31,7 @@
 #include "button.h"
 #include "button.h"
 
 
 #include "core/translation.h"
 #include "core/translation.h"
+#include "scene/scene_string_names.h"
 #include "servers/visual_server.h"
 #include "servers/visual_server.h"
 
 
 Size2 Button::get_minimum_size() const {
 Size2 Button::get_minimum_size() const {
@@ -301,7 +302,13 @@ void Button::set_icon(const Ref<Texture> &p_icon) {
 	if (icon == p_icon) {
 	if (icon == p_icon) {
 		return;
 		return;
 	}
 	}
+	if (icon.is_valid()) {
+		icon->disconnect(SceneStringNames::get_singleton()->changed, this, "_texture_changed");
+	}
 	icon = p_icon;
 	icon = p_icon;
+	if (icon.is_valid()) {
+		icon->connect(SceneStringNames::get_singleton()->changed, this, "_texture_changed");
+	}
 	update();
 	update();
 	_change_notify("icon");
 	_change_notify("icon");
 	minimum_size_changed();
 	minimum_size_changed();
@@ -311,6 +318,11 @@ Ref<Texture> Button::get_icon() const {
 	return icon;
 	return icon;
 }
 }
 
 
+void Button::_texture_changed() {
+	update();
+	minimum_size_changed();
+}
+
 void Button::set_expand_icon(bool p_expand_icon) {
 void Button::set_expand_icon(bool p_expand_icon) {
 	expand_icon = p_expand_icon;
 	expand_icon = p_expand_icon;
 	update();
 	update();
@@ -376,6 +388,8 @@ void Button::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_expand_icon", "enabled"), &Button::set_expand_icon);
 	ClassDB::bind_method(D_METHOD("set_expand_icon", "enabled"), &Button::set_expand_icon);
 	ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
 	ClassDB::bind_method(D_METHOD("is_expand_icon"), &Button::is_expand_icon);
 
 
+	ClassDB::bind_method(D_METHOD("_texture_changed"), &Button::_texture_changed);
+
 	BIND_ENUM_CONSTANT(ALIGN_LEFT);
 	BIND_ENUM_CONSTANT(ALIGN_LEFT);
 	BIND_ENUM_CONSTANT(ALIGN_CENTER);
 	BIND_ENUM_CONSTANT(ALIGN_CENTER);
 	BIND_ENUM_CONSTANT(ALIGN_RIGHT);
 	BIND_ENUM_CONSTANT(ALIGN_RIGHT);

+ 2 - 0
scene/gui/button.h

@@ -54,6 +54,8 @@ private:
 	TextAlign icon_align;
 	TextAlign icon_align;
 	float _internal_margin[4];
 	float _internal_margin[4];
 
 
+	void _texture_changed();
+
 protected:
 protected:
 	void _set_internal_margin(Margin p_margin, float p_value);
 	void _set_internal_margin(Margin p_margin, float p_value);
 	void _notification(int p_what);
 	void _notification(int p_what);

+ 1 - 1
scene/gui/text_edit.cpp

@@ -4932,7 +4932,7 @@ Rect2 TextEdit::get_rect_at_line_column(int p_line, int p_column) const {
 
 
 	int first_visible_char = cache_entry.first_visible_char[wrap_index];
 	int first_visible_char = cache_entry.first_visible_char[wrap_index];
 	int last_visible_char = cache_entry.last_visible_char[wrap_index];
 	int last_visible_char = cache_entry.last_visible_char[wrap_index];
-	if (p_column < first_visible_char || p_column > last_visible_char) {
+	if (p_column < first_visible_char || p_column > (last_visible_char + 1)) {
 		// Character is outside of the viewing area, no point calculating its position.
 		// Character is outside of the viewing area, no point calculating its position.
 		return Rect2i(-1, -1, 0, 0);
 		return Rect2i(-1, -1, 0, 0);
 	}
 	}

+ 33 - 11
scene/gui/texture_button.cpp

@@ -29,7 +29,10 @@
 /**************************************************************************/
 /**************************************************************************/
 
 
 #include "texture_button.h"
 #include "texture_button.h"
+
 #include "core/typedefs.h"
 #include "core/typedefs.h"
+#include "scene/scene_string_names.h"
+
 #include <stdlib.h>
 #include <stdlib.h>
 
 
 Size2 TextureButton::get_minimum_size() const {
 Size2 TextureButton::get_minimum_size() const {
@@ -272,6 +275,8 @@ void TextureButton::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_expand"), &TextureButton::get_expand);
 	ClassDB::bind_method(D_METHOD("get_expand"), &TextureButton::get_expand);
 	ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureButton::get_stretch_mode);
 	ClassDB::bind_method(D_METHOD("get_stretch_mode"), &TextureButton::get_stretch_mode);
 
 
+	ClassDB::bind_method(D_METHOD("_texture_changed"), &TextureButton::_texture_changed);
+
 	ADD_GROUP("Textures", "texture_");
 	ADD_GROUP("Textures", "texture_");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_texture", "get_normal_texture");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture");
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture_pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_pressed_texture", "get_pressed_texture");
@@ -294,25 +299,21 @@ void TextureButton::_bind_methods() {
 }
 }
 
 
 void TextureButton::set_normal_texture(const Ref<Texture> &p_normal) {
 void TextureButton::set_normal_texture(const Ref<Texture> &p_normal) {
-	normal = p_normal;
-	update();
-	minimum_size_changed();
+	_set_texture(&normal, p_normal);
 }
 }
 
 
 void TextureButton::set_pressed_texture(const Ref<Texture> &p_pressed) {
 void TextureButton::set_pressed_texture(const Ref<Texture> &p_pressed) {
-	pressed = p_pressed;
-	update();
-	minimum_size_changed();
+	_set_texture(&pressed, p_pressed);
 }
 }
+
 void TextureButton::set_hover_texture(const Ref<Texture> &p_hover) {
 void TextureButton::set_hover_texture(const Ref<Texture> &p_hover) {
-	hover = p_hover;
-	update();
-	minimum_size_changed();
+	_set_texture(&hover, p_hover);
 }
 }
+
 void TextureButton::set_disabled_texture(const Ref<Texture> &p_disabled) {
 void TextureButton::set_disabled_texture(const Ref<Texture> &p_disabled) {
-	disabled = p_disabled;
-	update();
+	_set_texture(&disabled, p_disabled);
 }
 }
+
 void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
 void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
 	click_mask = p_click_mask;
 	click_mask = p_click_mask;
 	update();
 	update();
@@ -343,6 +344,27 @@ void TextureButton::set_focused_texture(const Ref<Texture> &p_focused) {
 	focused = p_focused;
 	focused = p_focused;
 };
 };
 
 
+void TextureButton::_set_texture(Ref<Texture> *p_destination, const Ref<Texture> &p_texture) {
+	DEV_ASSERT(p_destination);
+	Ref<Texture> &destination = *p_destination;
+	if (destination == p_texture) {
+		return;
+	}
+	if (destination.is_valid()) {
+		destination->disconnect(SceneStringNames::get_singleton()->changed, this, "_texture_changed");
+	}
+	destination = p_texture;
+	if (destination.is_valid()) {
+		destination->connect(SceneStringNames::get_singleton()->changed, this, "_texture_changed", varray(), CONNECT_REFERENCE_COUNTED);
+	}
+	_texture_changed();
+}
+
+void TextureButton::_texture_changed() {
+	update();
+	minimum_size_changed();
+}
+
 bool TextureButton::get_expand() const {
 bool TextureButton::get_expand() const {
 	return expand;
 	return expand;
 }
 }

+ 3 - 0
scene/gui/texture_button.h

@@ -64,6 +64,9 @@ private:
 	bool hflip;
 	bool hflip;
 	bool vflip;
 	bool vflip;
 
 
+	void _set_texture(Ref<Texture> *p_destination, const Ref<Texture> &p_texture);
+	void _texture_changed();
+
 protected:
 protected:
 	virtual Size2 get_minimum_size() const;
 	virtual Size2 get_minimum_size() const;
 	virtual bool has_point(const Point2 &p_point) const;
 	virtual bool has_point(const Point2 &p_point) const;

+ 3 - 2
thirdparty/README.md

@@ -267,7 +267,7 @@ from the Android NDK r18.
 ## libwebp
 ## libwebp
 
 
 - Upstream: https://chromium.googlesource.com/webm/libwebp/
 - Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.3.1 (fd7bb21c0cb56e8a82e9bfa376164b842f433f3b, 2023)
+- Version: 1.3.2 (ca332209cb5567c9b249c86788cb2dbf8847e760, 2023)
 - License: BSD-3-Clause
 - License: BSD-3-Clause
 
 
 Files extracted from upstream source:
 Files extracted from upstream source:
@@ -289,7 +289,8 @@ File extracted from upstream release tarball:
 - The `LICENSE` file.
 - The `LICENSE` file.
 - Applied the patch in `patches/1453.diff` to fix UWP build (upstream PR:
 - Applied the patch in `patches/1453.diff` to fix UWP build (upstream PR:
   https://github.com/ARMmbed/mbedtls/pull/1453).
   https://github.com/ARMmbed/mbedtls/pull/1453).
-  Applied the patch in `patches/windows-arm64-hardclock.diff`
+  Applied the patch in `patches/windows-arm64-hardclock.diff`.
+  Applied the patch in `aesni-no-arm-intrinsics.patch` also to fix UWP build.
 - Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
 - Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
   providing configuration for light bundling with core.
   providing configuration for light bundling with core.
 
 

+ 1 - 1
thirdparty/libwebp/src/dec/vp8i_dec.h

@@ -32,7 +32,7 @@ extern "C" {
 // version numbers
 // version numbers
 #define DEC_MAJ_VERSION 1
 #define DEC_MAJ_VERSION 1
 #define DEC_MIN_VERSION 3
 #define DEC_MIN_VERSION 3
-#define DEC_REV_VERSION 1
+#define DEC_REV_VERSION 2
 
 
 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
 // YUV-cache parameters. Cache is 32-bytes wide (= one cacheline).
 // Constraints are: We need to store one 16x16 block of luma samples (y),
 // Constraints are: We need to store one 16x16 block of luma samples (y),

+ 25 - 21
thirdparty/libwebp/src/dec/vp8l_dec.c

@@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
   int symbol;
   int symbol;
   int max_symbol;
   int max_symbol;
   int prev_code_len = DEFAULT_CODE_LENGTH;
   int prev_code_len = DEFAULT_CODE_LENGTH;
-  HuffmanCode table[1 << LENGTHS_TABLE_BITS];
+  HuffmanTables tables;
 
 
-  if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
-                             code_length_code_lengths,
-                             NUM_CODE_LENGTH_CODES)) {
+  if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
+      !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
+                             code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
     goto End;
     goto End;
   }
   }
 
 
@@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
     int code_len;
     int code_len;
     if (max_symbol-- == 0) break;
     if (max_symbol-- == 0) break;
     VP8LFillBitWindow(br);
     VP8LFillBitWindow(br);
-    p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+    p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
     VP8LSetBitPos(br, br->bit_pos_ + p->bits);
     VP8LSetBitPos(br, br->bit_pos_ + p->bits);
     code_len = p->value;
     code_len = p->value;
     if (code_len < kCodeLengthLiterals) {
     if (code_len < kCodeLengthLiterals) {
@@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
   ok = 1;
   ok = 1;
 
 
  End:
  End:
+  VP8LHuffmanTablesDeallocate(&tables);
   if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
   if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
   return ok;
   return ok;
 }
 }
@@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
 // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
 // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
 // tree.
 // tree.
 static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
 static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
-                           int* const code_lengths, HuffmanCode* const table) {
+                           int* const code_lengths,
+                           HuffmanTables* const table) {
   int ok = 0;
   int ok = 0;
   int size = 0;
   int size = 0;
   VP8LBitReader* const br = &dec->br_;
   VP8LBitReader* const br = &dec->br_;
@@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   VP8LMetadata* const hdr = &dec->hdr_;
   VP8LMetadata* const hdr = &dec->hdr_;
   uint32_t* huffman_image = NULL;
   uint32_t* huffman_image = NULL;
   HTreeGroup* htree_groups = NULL;
   HTreeGroup* htree_groups = NULL;
-  HuffmanCode* huffman_tables = NULL;
-  HuffmanCode* huffman_table = NULL;
+  HuffmanTables* huffman_tables = &hdr->huffman_tables_;
   int num_htree_groups = 1;
   int num_htree_groups = 1;
   int num_htree_groups_max = 1;
   int num_htree_groups_max = 1;
   int max_alphabet_size = 0;
   int max_alphabet_size = 0;
@@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   int* mapping = NULL;
   int* mapping = NULL;
   int ok = 0;
   int ok = 0;
 
 
+  // Check the table has been 0 initialized (through InitMetadata).
+  assert(huffman_tables->root.start == NULL);
+  assert(huffman_tables->curr_segment == NULL);
+
   if (allow_recursion && VP8LReadBits(br, 1)) {
   if (allow_recursion && VP8LReadBits(br, 1)) {
     // use meta Huffman codes.
     // use meta Huffman codes.
     const int huffman_precision = VP8LReadBits(br, 3) + 2;
     const int huffman_precision = VP8LReadBits(br, 3) + 2;
@@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
 
 
   code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
   code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
                                       sizeof(*code_lengths));
                                       sizeof(*code_lengths));
-  huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
-                                                sizeof(*huffman_tables));
   htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
   htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
 
 
-  if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
+  if (htree_groups == NULL || code_lengths == NULL ||
+      !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
+                                 huffman_tables)) {
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
     dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
     goto Error;
     goto Error;
   }
   }
 
 
-  huffman_table = huffman_tables;
   for (i = 0; i < num_htree_groups_max; ++i) {
   for (i = 0; i < num_htree_groups_max; ++i) {
     // If the index "i" is unused in the Huffman image, just make sure the
     // If the index "i" is unused in the Huffman image, just make sure the
     // coefficients are valid but do not store them.
     // coefficients are valid but do not store them.
@@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
       int max_bits = 0;
       int max_bits = 0;
       for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
       for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
         int alphabet_size = kAlphabetSize[j];
         int alphabet_size = kAlphabetSize[j];
-        htrees[j] = huffman_table;
         if (j == 0 && color_cache_bits > 0) {
         if (j == 0 && color_cache_bits > 0) {
           alphabet_size += (1 << color_cache_bits);
           alphabet_size += (1 << color_cache_bits);
         }
         }
-        size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
+        size =
+            ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
+        htrees[j] = huffman_tables->curr_segment->curr_table;
         if (size == 0) {
         if (size == 0) {
           goto Error;
           goto Error;
         }
         }
         if (is_trivial_literal && kLiteralMap[j] == 1) {
         if (is_trivial_literal && kLiteralMap[j] == 1) {
-          is_trivial_literal = (huffman_table->bits == 0);
+          is_trivial_literal = (htrees[j]->bits == 0);
         }
         }
-        total_size += huffman_table->bits;
-        huffman_table += size;
+        total_size += htrees[j]->bits;
+        huffman_tables->curr_segment->curr_table += size;
         if (j <= ALPHA) {
         if (j <= ALPHA) {
           int local_max_bits = code_lengths[0];
           int local_max_bits = code_lengths[0];
           int k;
           int k;
@@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
   hdr->huffman_image_ = huffman_image;
   hdr->huffman_image_ = huffman_image;
   hdr->num_htree_groups_ = num_htree_groups;
   hdr->num_htree_groups_ = num_htree_groups;
   hdr->htree_groups_ = htree_groups;
   hdr->htree_groups_ = htree_groups;
-  hdr->huffman_tables_ = huffman_tables;
 
 
  Error:
  Error:
   WebPSafeFree(code_lengths);
   WebPSafeFree(code_lengths);
   WebPSafeFree(mapping);
   WebPSafeFree(mapping);
   if (!ok) {
   if (!ok) {
     WebPSafeFree(huffman_image);
     WebPSafeFree(huffman_image);
-    WebPSafeFree(huffman_tables);
+    VP8LHuffmanTablesDeallocate(huffman_tables);
     VP8LHtreeGroupsFree(htree_groups);
     VP8LHtreeGroupsFree(htree_groups);
   }
   }
   return ok;
   return ok;
@@ -1358,7 +1362,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
   assert(hdr != NULL);
   assert(hdr != NULL);
 
 
   WebPSafeFree(hdr->huffman_image_);
   WebPSafeFree(hdr->huffman_image_);
-  WebPSafeFree(hdr->huffman_tables_);
+  VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
   VP8LHtreeGroupsFree(hdr->htree_groups_);
   VP8LHtreeGroupsFree(hdr->htree_groups_);
   VP8LColorCacheClear(&hdr->color_cache_);
   VP8LColorCacheClear(&hdr->color_cache_);
   VP8LColorCacheClear(&hdr->saved_color_cache_);
   VP8LColorCacheClear(&hdr->saved_color_cache_);
@@ -1673,7 +1677,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
 
 
   if (dec == NULL) return 0;
   if (dec == NULL) return 0;
 
 
-  assert(dec->hdr_.huffman_tables_ != NULL);
+  assert(dec->hdr_.huffman_tables_.root.start != NULL);
   assert(dec->hdr_.htree_groups_ != NULL);
   assert(dec->hdr_.htree_groups_ != NULL);
   assert(dec->hdr_.num_htree_groups_ > 0);
   assert(dec->hdr_.num_htree_groups_ > 0);
 
 

+ 1 - 1
thirdparty/libwebp/src/dec/vp8li_dec.h

@@ -51,7 +51,7 @@ typedef struct {
   uint32_t*       huffman_image_;
   uint32_t*       huffman_image_;
   int             num_htree_groups_;
   int             num_htree_groups_;
   HTreeGroup*     htree_groups_;
   HTreeGroup*     htree_groups_;
-  HuffmanCode*    huffman_tables_;
+  HuffmanTables   huffman_tables_;
 } VP8LMetadata;
 } VP8LMetadata;
 
 
 typedef struct VP8LDecoder VP8LDecoder;
 typedef struct VP8LDecoder VP8LDecoder;

+ 1 - 1
thirdparty/libwebp/src/demux/demux.c

@@ -25,7 +25,7 @@
 
 
 #define DMUX_MAJ_VERSION 1
 #define DMUX_MAJ_VERSION 1
 #define DMUX_MIN_VERSION 3
 #define DMUX_MIN_VERSION 3
-#define DMUX_REV_VERSION 1
+#define DMUX_REV_VERSION 2
 
 
 typedef struct {
 typedef struct {
   size_t start_;        // start location of the data
   size_t start_;        // start location of the data

+ 1 - 1
thirdparty/libwebp/src/enc/vp8i_enc.h

@@ -32,7 +32,7 @@ extern "C" {
 // version numbers
 // version numbers
 #define ENC_MAJ_VERSION 1
 #define ENC_MAJ_VERSION 1
 #define ENC_MIN_VERSION 3
 #define ENC_MIN_VERSION 3
-#define ENC_REV_VERSION 1
+#define ENC_REV_VERSION 2
 
 
 enum { MAX_LF_LEVELS = 64,       // Maximum loop filter level
 enum { MAX_LF_LEVELS = 64,       // Maximum loop filter level
        MAX_VARIABLE_LEVEL = 67,  // last (inclusive) level with variable cost
        MAX_VARIABLE_LEVEL = 67,  // last (inclusive) level with variable cost

+ 1 - 1
thirdparty/libwebp/src/mux/muxi.h

@@ -29,7 +29,7 @@ extern "C" {
 
 
 #define MUX_MAJ_VERSION 1
 #define MUX_MAJ_VERSION 1
 #define MUX_MIN_VERSION 3
 #define MUX_MIN_VERSION 3
-#define MUX_REV_VERSION 1
+#define MUX_REV_VERSION 2
 
 
 // Chunk object.
 // Chunk object.
 typedef struct WebPChunk WebPChunk;
 typedef struct WebPChunk WebPChunk;

+ 79 - 18
thirdparty/libwebp/src/utils/huffman_utils.c

@@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
       if (num_open < 0) {
       if (num_open < 0) {
         return 0;
         return 0;
       }
       }
-      if (root_table == NULL) continue;
       for (; count[len] > 0; --count[len]) {
       for (; count[len] > 0; --count[len]) {
         HuffmanCode code;
         HuffmanCode code;
         if ((key & mask) != low) {
         if ((key & mask) != low) {
-          table += table_size;
+          if (root_table != NULL) table += table_size;
           table_bits = NextTableBitSize(count, len, root_bits);
           table_bits = NextTableBitSize(count, len, root_bits);
           table_size = 1 << table_bits;
           table_size = 1 << table_bits;
           total_size += table_size;
           total_size += table_size;
           low = key & mask;
           low = key & mask;
-          root_table[low].bits = (uint8_t)(table_bits + root_bits);
-          root_table[low].value = (uint16_t)((table - root_table) - low);
+          if (root_table != NULL) {
+            root_table[low].bits = (uint8_t)(table_bits + root_bits);
+            root_table[low].value = (uint16_t)((table - root_table) - low);
+          }
+        }
+        if (root_table != NULL) {
+          code.bits = (uint8_t)(len - root_bits);
+          code.value = (uint16_t)sorted[symbol++];
+          ReplicateValue(&table[key >> root_bits], step, table_size, code);
         }
         }
-        code.bits = (uint8_t)(len - root_bits);
-        code.value = (uint16_t)sorted[symbol++];
-        ReplicateValue(&table[key >> root_bits], step, table_size, code);
         key = GetNextKey(key, len);
         key = GetNextKey(key, len);
       }
       }
     }
     }
@@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
   ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
   ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
 // Cut-off value for switching between heap and stack allocation.
 // Cut-off value for switching between heap and stack allocation.
 #define SORTED_SIZE_CUTOFF 512
 #define SORTED_SIZE_CUTOFF 512
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
                           const int code_lengths[], int code_lengths_size) {
                           const int code_lengths[], int code_lengths_size) {
-  int total_size;
+  const int total_size =
+      BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size, NULL);
   assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
   assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
-  if (root_table == NULL) {
-    total_size = BuildHuffmanTable(NULL, root_bits,
-                                   code_lengths, code_lengths_size, NULL);
-  } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+  if (total_size == 0 || root_table == NULL) return total_size;
+
+  if (root_table->curr_segment->curr_table + total_size >=
+      root_table->curr_segment->start + root_table->curr_segment->size) {
+    // If 'root_table' does not have enough memory, allocate a new segment.
+    // The available part of root_table->curr_segment is left unused because we
+    // need a contiguous buffer.
+    const int segment_size = root_table->curr_segment->size;
+    struct HuffmanTablesSegment* next =
+        (HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
+    if (next == NULL) return 0;
+    // Fill the new segment.
+    // We need at least 'total_size' but if that value is small, it is better to
+    // allocate a big chunk to prevent more allocations later. 'segment_size' is
+    // therefore chosen (any other arbitrary value could be chosen).
+    next->size = total_size > segment_size ? total_size : segment_size;
+    next->start =
+        (HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
+    if (next->start == NULL) {
+      WebPSafeFree(next);
+      return 0;
+    }
+    next->curr_table = next->start;
+    next->next = NULL;
+    // Point to the new segment.
+    root_table->curr_segment->next = next;
+    root_table->curr_segment = next;
+  }
+  if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
     // use local stack-allocated array.
     // use local stack-allocated array.
     uint16_t sorted[SORTED_SIZE_CUTOFF];
     uint16_t sorted[SORTED_SIZE_CUTOFF];
-    total_size = BuildHuffmanTable(root_table, root_bits,
-                                   code_lengths, code_lengths_size, sorted);
-  } else {   // rare case. Use heap allocation.
+    BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+                      code_lengths, code_lengths_size, sorted);
+  } else {  // rare case. Use heap allocation.
     uint16_t* const sorted =
     uint16_t* const sorted =
         (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
         (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
     if (sorted == NULL) return 0;
     if (sorted == NULL) return 0;
-    total_size = BuildHuffmanTable(root_table, root_bits,
-                                   code_lengths, code_lengths_size, sorted);
+    BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
+                      code_lengths, code_lengths_size, sorted);
     WebPSafeFree(sorted);
     WebPSafeFree(sorted);
   }
   }
   return total_size;
   return total_size;
 }
 }
+
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
+  // Have 'segment' point to the first segment for now, 'root'.
+  HuffmanTablesSegment* const root = &huffman_tables->root;
+  huffman_tables->curr_segment = root;
+  // Allocate root.
+  root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
+  if (root->start == NULL) return 0;
+  root->curr_table = root->start;
+  root->next = NULL;
+  root->size = size;
+  return 1;
+}
+
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
+  HuffmanTablesSegment *current, *next;
+  if (huffman_tables == NULL) return;
+  // Free the root node.
+  current = &huffman_tables->root;
+  next = current->next;
+  WebPSafeFree(current->start);
+  current->start = NULL;
+  current->next = NULL;
+  current = next;
+  // Free the following nodes.
+  while (current != NULL) {
+    next = current->next;
+    WebPSafeFree(current->start);
+    WebPSafeFree(current);
+    current = next;
+  }
+}

+ 24 - 3
thirdparty/libwebp/src/utils/huffman_utils.h

@@ -43,6 +43,29 @@ typedef struct {
                     // or non-literal symbol otherwise
                     // or non-literal symbol otherwise
 } HuffmanCode32;
 } HuffmanCode32;
 
 
+// Contiguous memory segment of HuffmanCodes.
+typedef struct HuffmanTablesSegment {
+  HuffmanCode* start;
+  // Pointer to where we are writing into the segment. Starts at 'start' and
+  // cannot go beyond 'start' + 'size'.
+  HuffmanCode* curr_table;
+  // Pointer to the next segment in the chain.
+  struct HuffmanTablesSegment* next;
+  int size;
+} HuffmanTablesSegment;
+
+// Chained memory segments of HuffmanCodes.
+typedef struct HuffmanTables {
+  HuffmanTablesSegment root;
+  // Currently processed segment. At first, this is 'root'.
+  HuffmanTablesSegment* curr_segment;
+} HuffmanTables;
+
+// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
+// memory allocation error, 1 otherwise.
+int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
+void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
+
 #define HUFFMAN_PACKED_BITS 6
 #define HUFFMAN_PACKED_BITS 6
 #define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
 #define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
 
 
@@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
 // the huffman table.
 // the huffman table.
 // Returns built table size or 0 in case of error (invalid tree or
 // Returns built table size or 0 in case of error (invalid tree or
 // memory error).
 // memory error).
-// If root_table is NULL, it returns 0 if a lookup cannot be built, something
-// > 0 otherwise (but not the table size).
-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
                           const int code_lengths[], int code_lengths_size);
                           const int code_lengths[], int code_lengths_size);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus

+ 3 - 2
thirdparty/mbedtls/include/mbedtls/aesni.h

@@ -54,9 +54,10 @@
  *       macros that may change in future releases.
  *       macros that may change in future releases.
  */
  */
 #undef MBEDTLS_AESNI_HAVE_INTRINSICS
 #undef MBEDTLS_AESNI_HAVE_INTRINSICS
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
 /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
 /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
- * VS 2013 and up for other reasons anyway, so no need to check the version. */
+ * VS 2013 and up for other reasons anyway, so no need to check the version.
+ * Only supported on x64 and x86. */
 #define MBEDTLS_AESNI_HAVE_INTRINSICS
 #define MBEDTLS_AESNI_HAVE_INTRINSICS
 #endif
 #endif
 /* GCC-like compilers: currently, we only support intrinsics if the requisite
 /* GCC-like compilers: currently, we only support intrinsics if the requisite

+ 17 - 0
thirdparty/mbedtls/patches/aesni-no-arm-intrinsics.patch

@@ -0,0 +1,17 @@
+diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h
+index 6741dead05..6c545bd4a3 100644
+--- a/thirdparty/mbedtls/include/mbedtls/aesni.h
++++ b/thirdparty/mbedtls/include/mbedtls/aesni.h
+@@ -54,9 +54,10 @@
+  *       macros that may change in future releases.
+  */
+ #undef MBEDTLS_AESNI_HAVE_INTRINSICS
+-#if defined(_MSC_VER)
++#if defined(_MSC_VER) && (defined(_M_AMD64) || defined(_M_IX86))
+ /* Visual Studio supports AESNI intrinsics since VS 2008 SP1. We only support
+- * VS 2013 and up for other reasons anyway, so no need to check the version. */
++ * VS 2013 and up for other reasons anyway, so no need to check the version.
++ * Only supported on x64 and x86. */
+ #define MBEDTLS_AESNI_HAVE_INTRINSICS
+ #endif
+ /* GCC-like compilers: currently, we only support intrinsics if the requisite