From bf2b98b8019a89008fd30656e4d3dafcc9c0184b Mon Sep 17 00:00:00 2001 From: BlueCube3310 <53150244+BlueCube3310@users.noreply.github.com> Date: Sun, 7 Jan 2024 12:53:01 +0100 Subject: [PATCH 01/35] Fix BasisUniversal ETC RA_AS_RG transcoding (cherry picked from commit 51ad937532fb2c00f89326ac1e102a56829df2ae) --- modules/basis_universal/register_types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp index 86f3385ae33..2e0642ed5a8 100644 --- a/modules/basis_universal/register_types.cpp +++ b/modules/basis_universal/register_types.cpp @@ -221,7 +221,7 @@ static Ref basis_universal_unpacker_ptr(const uint8_t *p_data, int p_size imgfmt = Image::FORMAT_DXT5_RA_AS_RG; } else if (RS::get_singleton()->has_os_feature("etc2")) { format = basist::transcoder_texture_format::cTFETC2; // get this from renderer - imgfmt = Image::FORMAT_ETC2_RGBA8; + imgfmt = Image::FORMAT_ETC2_RA_AS_RG; } else { //opengl most likely, bad for normal maps, nothing to do about this. format = basist::transcoder_texture_format::cTFRGBA32; From 5ffc22b06f28b5b2cdfab4e040830914692b0e5b Mon Sep 17 00:00:00 2001 From: Micky Date: Tue, 9 Jan 2024 16:27:09 +0100 Subject: [PATCH 02/35] Add missing descriptions to PrimitiveMesh and SoftBody3D (cherry picked from commit a33777d49d4c5a42b60e761db9bcb8d2542dbe25) --- doc/classes/PrimitiveMesh.xml | 1 + doc/classes/SoftBody3D.xml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 7bcf3ce46b6..e468e3ef547 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -12,6 +12,7 @@ + Override this method to customize how this primitive mesh should be generated. Should return an [Array] where each element is another Array of values required for the mesh (see the [enum Mesh.ArrayType] constants). diff --git a/doc/classes/SoftBody3D.xml b/doc/classes/SoftBody3D.xml index c66b64f4bea..7d42d2b621b 100644 --- a/doc/classes/SoftBody3D.xml +++ b/doc/classes/SoftBody3D.xml @@ -41,6 +41,7 @@ + Returns the internal [RID] used by the [PhysicsServer3D] for this body. @@ -100,11 +101,14 @@ [b]Note:[/b] Object A can detect a contact with object B only if object B is in any of the layers that object A scans. See [url=$DOCS_URL/tutorials/physics/physics_introduction.html#collision-layers-and-masks]Collision layers and masks[/url] in the documentation for more information. + The body's damping coefficient. Higher values will slow down the body more noticeably when forces are applied. Defines the behavior in physics when [member Node.process_mode] is set to [constant Node.PROCESS_MODE_DISABLED]. See [enum DisableMode] for more details about the different modes. + The body's drag coefficient. Higher values increase this body's air resistance. + [b]Note:[/b] This value is currently unused by Godot's default physics implementation. Higher values will result in a stiffer body, while lower values will increase the body's ability to bend. The value can be between [code]0.0[/code] and [code]1.0[/code] (inclusive). @@ -113,6 +117,7 @@ [NodePath] to a [CollisionObject3D] this SoftBody3D should avoid clipping. + The pressure coefficient of this soft body. Simulate pressure build-up from inside this body. Higher values increase the strength of this effect. If [code]true[/code], the [SoftBody3D] will respond to [RayCast3D]s. From 1fa33b607207e89c775168bcb0df9438d54f00d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alessandro=20Fam=C3=A0?= Date: Tue, 9 Jan 2024 16:37:06 +0100 Subject: [PATCH 03/35] Fix Dummy audio driver initialization issue on WASAPI output device initialization failure `AudioDriverWASAPI::init` consistently returns `Error::OK`, even when encountering a failure during the initialization of the output device. This behaviour blocks the dummy driver from initializing in `AudioDriverManager::initialize`. (cherry picked from commit 998078f8d7414a21214d4ad4056e0fb8b4e55180) --- drivers/wasapi/audio_driver_wasapi.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp index eeeb6ee689e..bdaef82d6f0 100644 --- a/drivers/wasapi/audio_driver_wasapi.cpp +++ b/drivers/wasapi/audio_driver_wasapi.cpp @@ -557,13 +557,11 @@ Error AudioDriverWASAPI::init() { target_latency_ms = GLOBAL_GET("audio/driver/output_latency"); - Error err = init_output_device(); - if (err != OK) { - ERR_PRINT("WASAPI: init_output_device error"); - } - exit_thread.clear(); + Error err = init_output_device(); + ERR_FAIL_COND_V_MSG(err != OK, err, "WASAPI: init_output_device error."); + thread.start(thread_func, this); return OK; From 2c062f1922565c80e3e142bff0701dbf15ecc3f4 Mon Sep 17 00:00:00 2001 From: 31 <31eee384@gmail.com> Date: Sun, 14 Jan 2024 10:29:02 -0800 Subject: [PATCH 04/35] Include animation.length in Animation example The length of an Animation isn't automatically set by adding keys, and it must be set manually. The existing example only has keys up to 0.5s, so the default value of 1.0s may be acceptable. However, this results in unexpected behavior for anyone who makes an animation longer than 1.0s. Include animation.length in the example because it's important. Also, increase the key position to 2.0s so it won't be confusing that the assignment is somewhat redundant. (cherry picked from commit 698c67d540cddf38c9ad7e73e99721c245b93588) --- doc/classes/Animation.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml index bb354320b3f..c0acaae45fc 100644 --- a/doc/classes/Animation.xml +++ b/doc/classes/Animation.xml @@ -8,21 +8,23 @@ [codeblocks] [gdscript] # This creates an animation that makes the node "Enemy" move to the right by - # 100 pixels in 0.5 seconds. + # 100 pixels in 2.0 seconds. var animation = Animation.new() var track_index = animation.add_track(Animation.TYPE_VALUE) animation.track_set_path(track_index, "Enemy:position:x") animation.track_insert_key(track_index, 0.0, 0) - animation.track_insert_key(track_index, 0.5, 100) + animation.track_insert_key(track_index, 2.0, 100) + animation.length = 2.0 [/gdscript] [csharp] // This creates an animation that makes the node "Enemy" move to the right by - // 100 pixels in 0.5 seconds. + // 100 pixels in 2.0 seconds. var animation = new Animation(); int trackIndex = animation.AddTrack(Animation.TrackType.Value); animation.TrackSetPath(trackIndex, "Enemy:position:x"); animation.TrackInsertKey(trackIndex, 0.0f, 0); - animation.TrackInsertKey(trackIndex, 0.5f, 100); + animation.TrackInsertKey(trackIndex, 2.0f, 100); + animation.Length = 2.0f; [/csharp] [/codeblocks] Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types. From dfcd70c09f020ab61b4845b1a42eda3d71ac34d5 Mon Sep 17 00:00:00 2001 From: Erik Johnson Date: Sat, 16 Dec 2023 19:01:03 -0500 Subject: [PATCH 05/35] Add descpription for rendering/limits/spatial_indexer/threaded_cull_minimum_instances (cherry picked from commit 498f46063dc3045a02ff84c47c8329d2587b6d6f) --- doc/classes/ProjectSettings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 977c0c0979f..5544baa1dc9 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2467,6 +2467,7 @@ [b]Note:[/b] This setting is only effective when using the Compatibility rendering method, not Forward+ and Mobile. + The minimum number of instances that must be present in a scene to enable culling computations on multiple threads. If a scene has fewer instances than this number, culling is done on a single thread. From a092b1aa38a5c4ce8482a03917491b09d61f67e8 Mon Sep 17 00:00:00 2001 From: Occalepsus Date: Thu, 5 Oct 2023 13:46:10 +0200 Subject: [PATCH 06/35] Fix body leaving area gravity influence (cherry picked from commit 492f1c2406fa0f8d0958bcb578d101e409a60237) --- servers/physics_2d/godot_area_pair_2d.cpp | 5 ++++- servers/physics_2d/godot_area_pair_2d.h | 1 + servers/physics_3d/godot_area_pair_3d.cpp | 10 ++++++++-- servers/physics_3d/godot_area_pair_3d.h | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/servers/physics_2d/godot_area_pair_2d.cpp b/servers/physics_2d/godot_area_pair_2d.cpp index bd1540bac86..ca12e30c292 100644 --- a/servers/physics_2d/godot_area_pair_2d.cpp +++ b/servers/physics_2d/godot_area_pair_2d.cpp @@ -66,6 +66,7 @@ bool GodotAreaPair2D::pre_solve(real_t p_step) { if (colliding) { if (has_space_override) { + body_has_attached_area = true; body->add_area(area); } @@ -74,6 +75,7 @@ bool GodotAreaPair2D::pre_solve(real_t p_step) { } } else { if (has_space_override) { + body_has_attached_area = false; body->remove_area(area); } @@ -103,7 +105,8 @@ GodotAreaPair2D::GodotAreaPair2D(GodotBody2D *p_body, int p_body_shape, GodotAre GodotAreaPair2D::~GodotAreaPair2D() { if (colliding) { - if (has_space_override) { + if (body_has_attached_area) { + body_has_attached_area = false; body->remove_area(area); } if (area->has_monitor_callback()) { diff --git a/servers/physics_2d/godot_area_pair_2d.h b/servers/physics_2d/godot_area_pair_2d.h index 938b9813b4c..eb091288a90 100644 --- a/servers/physics_2d/godot_area_pair_2d.h +++ b/servers/physics_2d/godot_area_pair_2d.h @@ -43,6 +43,7 @@ class GodotAreaPair2D : public GodotConstraint2D { bool colliding = false; bool has_space_override = false; bool process_collision = false; + bool body_has_attached_area = false; public: virtual bool setup(real_t p_step) override; diff --git a/servers/physics_3d/godot_area_pair_3d.cpp b/servers/physics_3d/godot_area_pair_3d.cpp index 5561210f2d3..aaa96f5a289 100644 --- a/servers/physics_3d/godot_area_pair_3d.cpp +++ b/servers/physics_3d/godot_area_pair_3d.cpp @@ -67,6 +67,7 @@ bool GodotAreaPair3D::pre_solve(real_t p_step) { if (colliding) { if (has_space_override) { + body_has_attached_area = true; body->add_area(area); } @@ -75,6 +76,7 @@ bool GodotAreaPair3D::pre_solve(real_t p_step) { } } else { if (has_space_override) { + body_has_attached_area = false; body->remove_area(area); } @@ -104,7 +106,8 @@ GodotAreaPair3D::GodotAreaPair3D(GodotBody3D *p_body, int p_body_shape, GodotAre GodotAreaPair3D::~GodotAreaPair3D() { if (colliding) { - if (has_space_override) { + if (body_has_attached_area) { + body_has_attached_area = false; body->remove_area(area); } if (area->has_monitor_callback()) { @@ -242,6 +245,7 @@ bool GodotAreaSoftBodyPair3D::pre_solve(real_t p_step) { if (colliding) { if (has_space_override) { + body_has_attached_area = true; soft_body->add_area(area); } @@ -250,6 +254,7 @@ bool GodotAreaSoftBodyPair3D::pre_solve(real_t p_step) { } } else { if (has_space_override) { + body_has_attached_area = false; soft_body->remove_area(area); } @@ -276,7 +281,8 @@ GodotAreaSoftBodyPair3D::GodotAreaSoftBodyPair3D(GodotSoftBody3D *p_soft_body, i GodotAreaSoftBodyPair3D::~GodotAreaSoftBodyPair3D() { if (colliding) { - if (has_space_override) { + if (body_has_attached_area) { + body_has_attached_area = false; soft_body->remove_area(area); } if (area->has_monitor_callback()) { diff --git a/servers/physics_3d/godot_area_pair_3d.h b/servers/physics_3d/godot_area_pair_3d.h index c11fa078275..a2c5df0f7ad 100644 --- a/servers/physics_3d/godot_area_pair_3d.h +++ b/servers/physics_3d/godot_area_pair_3d.h @@ -44,6 +44,7 @@ class GodotAreaPair3D : public GodotConstraint3D { bool colliding = false; bool process_collision = false; bool has_space_override = false; + bool body_has_attached_area = false; public: virtual bool setup(real_t p_step) override; @@ -83,6 +84,7 @@ class GodotAreaSoftBodyPair3D : public GodotConstraint3D { bool colliding = false; bool process_collision = false; bool has_space_override = false; + bool body_has_attached_area = false; public: virtual bool setup(real_t p_step) override; From 5376aea68807ed283cd571630ebb17760e244a43 Mon Sep 17 00:00:00 2001 From: jsjtxietian Date: Wed, 8 Nov 2023 17:50:20 +0800 Subject: [PATCH 07/35] Fix CollisionObject3D Gizmo not updated after calling shape_owner_* functions (cherry picked from commit 80a488a24271a860aa0b79fb2e83569bf8d49942) --- scene/3d/collision_object_3d.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp index 6d8d60dcaa8..e315e5ea710 100644 --- a/scene/3d/collision_object_3d.cpp +++ b/scene/3d/collision_object_3d.cpp @@ -625,6 +625,7 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref 0) { shape_owner_remove_shape(p_owner, 0); } + + update_gizmos(); } uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const { From b113602ce5ae5d9be89dcb0daa951169892c829c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20T=2E=20Listwon?= Date: Fri, 8 Dec 2023 14:47:28 +0100 Subject: [PATCH 08/35] Prevent overriding file info of another file when reimport creates files (cherry picked from commit aae48ac2b688a360b80ff06105190b1842644cb5) --- editor/editor_file_system.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index c3f176b4246..48e16df0f5f 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -2148,6 +2148,9 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMapfiles[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file + ".import"); From 3df61453615649a70cf6720c00461b2c703835e5 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:42:28 +0100 Subject: [PATCH 09/35] Redraw `TreeItem` on more changes * Custom font changes * Custom draw changes * Custom as button (cherry picked from commit 552594ffdcca599bf5d44a8b61f9a940ccab38e5) --- scene/gui/tree.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 6ec8724a775..cf431282cf7 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -580,6 +580,8 @@ void TreeItem::set_custom_draw(int p_column, Object *p_object, const StringName cells.write[p_column].custom_draw_obj = p_object->get_instance_id(); cells.write[p_column].custom_draw_callback = p_callback; + + _changed_notify(p_column); } void TreeItem::set_collapsed(bool p_collapsed) { @@ -1290,8 +1292,14 @@ void TreeItem::clear_custom_color(int p_column) { void TreeItem::set_custom_font(int p_column, const Ref &p_font) { ERR_FAIL_INDEX(p_column, cells.size()); + if (cells[p_column].custom_font == p_font) { + return; + } + cells.write[p_column].custom_font = p_font; cells.write[p_column].cached_minimum_size_dirty = true; + + _changed_notify(p_column); } Ref TreeItem::get_custom_font(int p_column) const { @@ -1302,8 +1310,14 @@ Ref TreeItem::get_custom_font(int p_column) const { void TreeItem::set_custom_font_size(int p_column, int p_font_size) { ERR_FAIL_INDEX(p_column, cells.size()); + if (cells[p_column].custom_font_size == p_font_size) { + return; + } + cells.write[p_column].custom_font_size = p_font_size; cells.write[p_column].cached_minimum_size_dirty = true; + + _changed_notify(p_column); } int TreeItem::get_custom_font_size(int p_column) const { @@ -1352,8 +1366,14 @@ Color TreeItem::get_custom_bg_color(int p_column) const { void TreeItem::set_custom_as_button(int p_column, bool p_button) { ERR_FAIL_INDEX(p_column, cells.size()); + if (cells[p_column].custom_button == p_button) { + return; + } + cells.write[p_column].custom_button = p_button; cells.write[p_column].cached_minimum_size_dirty = true; + + _changed_notify(p_column); } bool TreeItem::is_custom_set_as_button(int p_column) const { From b3018d81c5890f1fa0140e535769283d6265f189 Mon Sep 17 00:00:00 2001 From: CardboardCarl <31835840+CardboardCarl@users.noreply.github.com> Date: Sun, 21 Jan 2024 01:16:42 -0500 Subject: [PATCH 10/35] Clarified behavior of RayCast objects when get_collision_point() is used inside a collision shape (cherry picked from commit 6dfec4f70dfe77560de046fe99d6514e7831755a) --- doc/classes/RayCast2D.xml | 2 +- doc/classes/RayCast3D.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml index bcf1e364e97..872b73da8e8 100644 --- a/doc/classes/RayCast2D.xml +++ b/doc/classes/RayCast2D.xml @@ -74,7 +74,7 @@ - Returns the collision point at which the ray intersects the closest object. + Returns the collision point at which the ray intersects the closest object. If [member hit_from_inside] is [code]true[/code] and the ray starts inside of a collision shape, this function will return the origin point of the ray. [b]Note:[/b] This point is in the [b]global[/b] coordinate system. diff --git a/doc/classes/RayCast3D.xml b/doc/classes/RayCast3D.xml index fa2badb1db3..231fdf590ef 100644 --- a/doc/classes/RayCast3D.xml +++ b/doc/classes/RayCast3D.xml @@ -75,7 +75,7 @@ - Returns the collision point at which the ray intersects the closest object. + Returns the collision point at which the ray intersects the closest object. If [member hit_from_inside] is [code]true[/code] and the ray starts inside of a collision shape, this function will return the origin point of the ray. [b]Note:[/b] This point is in the [b]global[/b] coordinate system. From a4cabd7497351ac076d4b746dd0140e02faaa062 Mon Sep 17 00:00:00 2001 From: Lyuma Date: Mon, 25 Dec 2023 00:58:38 -0800 Subject: [PATCH 11/35] gltf: fix three bugs which prevented extracted textures from being refreshed. 1. Extracted texture paths in `GLTFDocument::_parse_image_save_image` at the project root started with res:/// which broke cache invalidation 2. md5 hashes were not being written to generator_parameters for new imports, which led Godot to think the file was manually created. 3. `EditorFileSystem::reimport_append` must emit the `resources_reimported` signal in order for the resource cache to be updated. (cherry picked from commit fea4165ca8e952cef8cb8c636b4399ffdaebbdb5) --- editor/editor_file_system.cpp | 8 +++++++- modules/gltf/gltf_document.cpp | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index 48e16df0f5f..c5285179d4d 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -2345,7 +2345,13 @@ void EditorFileSystem::reimport_files(const Vector &p_files) { Error EditorFileSystem::reimport_append(const String &p_file, const HashMap &p_custom_options, const String &p_custom_importer, Variant p_generator_parameters) { ERR_FAIL_COND_V_MSG(!importing, ERR_INVALID_PARAMETER, "Can only append files to import during a current reimport process."); - return _reimport_file(p_file, p_custom_options, p_custom_importer, &p_generator_parameters); + Error ret = _reimport_file(p_file, p_custom_options, p_custom_importer, &p_generator_parameters); + + // Emit the resource_reimported signal for the single file we just reimported. + Vector reloads; + reloads.append(p_file); + emit_signal(SNAME("resources_reimported"), reloads); + return ret; } Error EditorFileSystem::_resource_import(const String &p_path) { diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index c3c7a4c4b0d..5e066db8312 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -3126,7 +3126,7 @@ void GLTFDocument::_parse_image_save_image(Ref p_state, const String bool must_import = true; Vector img_data = p_image->get_data(); Dictionary generator_parameters; - String file_path = p_state->get_base_path() + "/" + p_state->filename.get_basename() + "_" + p_image->get_name() + ".png"; + String file_path = p_state->get_base_path().path_join(p_state->filename.get_basename() + "_" + p_image->get_name()) + ".png"; if (FileAccess::exists(file_path + ".import")) { Ref config; config.instantiate(); @@ -3137,6 +3137,8 @@ void GLTFDocument::_parse_image_save_image(Ref p_state, const String if (!generator_parameters.has("md5")) { must_import = false; // Didn't come from a gltf document; don't overwrite. } + } + if (must_import) { String existing_md5 = generator_parameters["md5"]; unsigned char md5_hash[16]; CryptoCore::md5(img_data.ptr(), img_data.size(), md5_hash); From f4e6063ed885dc7671a211fdc0f64b482430c63c Mon Sep 17 00:00:00 2001 From: Raul Santos Date: Wed, 12 Jul 2023 14:36:12 +0200 Subject: [PATCH 12/35] Ignore directory entries in TPZ Zip files may contain directory entries, they always end with a path separator and zip entries always use forward slashes for path separators. There's no need to create the directories included in the zip file, since they'll already be created when creating the individual files. (cherry picked from commit 59a5a1eb70dc02bec4a6462d36ef6a0daaa8694e) --- editor/export/export_template_manager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/editor/export/export_template_manager.cpp b/editor/export/export_template_manager.cpp index e551b0531af..0fb6eaaac8b 100644 --- a/editor/export/export_template_manager.cpp +++ b/editor/export/export_template_manager.cpp @@ -465,6 +465,13 @@ bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_ break; } + if (String::utf8(fname).ends_with("/")) { + // File is a directory, ignore it. + // Directories will be created when extracting each file. + ret = unzGoToNextFile(pkg); + continue; + } + String file_path(String::utf8(fname).simplify_path()); String file = file_path.get_file(); From 8d479e8389e7c87cb50f2e066632e078ebf11592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 24 Jan 2024 11:32:38 +0100 Subject: [PATCH 13/35] zlib/minizip: Update to version 1.3.1 Minizip includes previously backported fix for CVE-2023-45853, and a Debian patch for CVE-2014-9485 was also upstreamed. (cherry picked from commit 8ead8d2ddb4bef0f667e208b7f4532a75ba494f7) --- COPYRIGHT.txt | 2 +- thirdparty/README.md | 4 +- thirdparty/minizip/ioapi.h | 2 +- thirdparty/minizip/patches/godot-seek.patch | 10 ++--- thirdparty/minizip/unzip.c | 8 ++-- thirdparty/minizip/unzip.h | 2 +- thirdparty/minizip/zip.c | 10 ++--- thirdparty/minizip/zip.h | 4 +- thirdparty/zlib/deflate.c | 47 ++++++++++++++++----- thirdparty/zlib/deflate.h | 35 ++++++++++++++- thirdparty/zlib/gzguts.h | 8 +--- thirdparty/zlib/gzlib.c | 12 +++--- thirdparty/zlib/inflate.c | 2 +- thirdparty/zlib/inftrees.c | 6 +-- thirdparty/zlib/inftrees.h | 4 +- thirdparty/zlib/trees.c | 20 +++++++-- thirdparty/zlib/zconf.h | 10 +---- thirdparty/zlib/zlib.h | 22 +++++----- thirdparty/zlib/zutil.h | 27 ++---------- 19 files changed, 136 insertions(+), 99 deletions(-) diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 52e779f1bb0..05f408c1d28 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -487,7 +487,7 @@ License: Expat Files: ./thirdparty/zlib/ Comment: zlib -Copyright: 1995-2023, Jean-loup Gailly and Mark Adler +Copyright: 1995-2024, Jean-loup Gailly and Mark Adler License: Zlib Files: ./thirdparty/zstd/ diff --git a/thirdparty/README.md b/thirdparty/README.md index a751452d0d4..c3038b453ac 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -441,7 +441,7 @@ that file when upgrading. ## minizip - Upstream: https://www.zlib.net -- Version: 1.3 (zlib contrib, 2023) +- Version: 1.3.1 (zlib contrib, 2024) - License: zlib Files extracted from the upstream source: @@ -814,7 +814,7 @@ Files extracted from upstream source: ## zlib - Upstream: https://www.zlib.net -- Version: 1.3 (2023) +- Version: 1.3.1 (2024) - License: zlib Files extracted from upstream source: diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h index 14266141c6f..509b52da8af 100644 --- a/thirdparty/minizip/ioapi.h +++ b/thirdparty/minizip/ioapi.h @@ -144,7 +144,7 @@ typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream) typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); -/* here is the "old" 32 bits structure structure */ +/* here is the "old" 32 bits structure */ typedef struct zlib_filefunc_def_s { open_file_func zopen_file; diff --git a/thirdparty/minizip/patches/godot-seek.patch b/thirdparty/minizip/patches/godot-seek.patch index 269536ba855..649de2fe2fb 100644 --- a/thirdparty/minizip/patches/godot-seek.patch +++ b/thirdparty/minizip/patches/godot-seek.patch @@ -26,7 +26,7 @@ index 782d32469a..2e89f5f41a 100644 +*/ +/* GODOT end */ diff --git a/thirdparty/minizip/ioapi.h b/thirdparty/minizip/ioapi.h -index c588a18d03..14266141c6 100644 +index a2d2e6e60d..509b52da8a 100644 --- a/thirdparty/minizip/ioapi.h +++ b/thirdparty/minizip/ioapi.h @@ -155,6 +155,10 @@ typedef struct zlib_filefunc_def_s @@ -52,7 +52,7 @@ index c588a18d03..14266141c6 100644 void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def); diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c -index ed763f89f1..2f8c5f3675 100644 +index ea05b7d62a..981ba3c0cb 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -152,6 +152,9 @@ typedef struct @@ -232,7 +232,7 @@ index ed763f89f1..2f8c5f3675 100644 return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } diff --git a/thirdparty/minizip/unzip.h b/thirdparty/minizip/unzip.h -index 14105840f6..1a477ecb50 100644 +index 5cfc9c6274..0639674574 100644 --- a/thirdparty/minizip/unzip.h +++ b/thirdparty/minizip/unzip.h @@ -202,6 +202,10 @@ extern int ZEXPORT unzClose(unzFile file); @@ -261,7 +261,7 @@ index 14105840f6..1a477ecb50 100644 extern ZPOS64_T ZEXPORT unztell64(unzFile file); diff --git a/thirdparty/minizip/zip.c b/thirdparty/minizip/zip.c -index 3d3d4cadde..e859f9e42f 100644 +index 60bdffac34..1d2d918e72 100644 --- a/thirdparty/minizip/zip.c +++ b/thirdparty/minizip/zip.c @@ -820,9 +820,11 @@ extern zipFile ZEXPORT zipOpen3(const void *pathname, int append, zipcharpc* glo @@ -279,7 +279,7 @@ index 3d3d4cadde..e859f9e42f 100644 ziinit.z_filefunc = *pzlib_filefunc64_32_def; ziinit.filestream = ZOPEN64(ziinit.z_filefunc, -@@ -1171,8 +1173,10 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c +@@ -1182,8 +1184,10 @@ extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, c { if(zi->ci.method == Z_DEFLATED) { diff --git a/thirdparty/minizip/unzip.c b/thirdparty/minizip/unzip.c index 41a203b164c..981ba3c0cb7 100644 --- a/thirdparty/minizip/unzip.c +++ b/thirdparty/minizip/unzip.c @@ -117,7 +117,7 @@ const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; -/* unz_file_info_interntal contain internal info about a file in zipfile*/ +/* unz_file_info64_internal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ @@ -453,7 +453,7 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return CENTRALDIRINVALID; - /* number of the disk with the start of the zip64 end of central directory */ + /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return CENTRALDIRINVALID; if (uL != 0) @@ -500,9 +500,9 @@ local unzFile unzOpenInternal(const void *path, ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current disk, used for spanning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number the disk with central dir, used for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry_CD; /* total number of entries in the central dir diff --git a/thirdparty/minizip/unzip.h b/thirdparty/minizip/unzip.h index 1a477ecb507..06396745744 100644 --- a/thirdparty/minizip/unzip.h +++ b/thirdparty/minizip/unzip.h @@ -310,7 +310,7 @@ extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, Get Info about the current file if pfile_info!=NULL, the *pfile_info structure will contain some info about the current file - if szFileName!=NULL, the filemane string will be copied in szFileName + if szFileName!=NULL, the filename string will be copied in szFileName (fileNameBufferSize is the size of the buffer) if extraField!=NULL, the extra field information will be copied in extraField (extraFieldBufferSize is the size of the buffer). diff --git a/thirdparty/minizip/zip.c b/thirdparty/minizip/zip.c index e859f9e42f1..4440f6d9411 100644 --- a/thirdparty/minizip/zip.c +++ b/thirdparty/minizip/zip.c @@ -575,7 +575,7 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; - /* number of the disk with the start of the zip64 end of central directory */ + /* number of the disk with the start of the zip64 end of central directory */ if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) return 0; if (uL != 0) @@ -614,9 +614,9 @@ local int LoadCentralDirectoryRecord(zip64_internal* pziinit) { ZPOS64_T central_pos; uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current disk, used for spanning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number of the disk with central dir, used for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry; ZPOS64_T number_entry_CD; /* total number of entries in @@ -1601,7 +1601,7 @@ extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_si if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) { - // we can not write more data to the buffer that we have room for. + // we cannot write more data to the buffer that we have room for. return ZIP_BADZIPFILE; } @@ -1865,7 +1865,7 @@ extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { free_linkedlist(&(zi->central_dir)); pos = centraldir_pos_inzip - zi->add_position_when_writing_offset; - if(pos >= 0xffffffff || zi->number_entry > 0xFFFF) + if(pos >= 0xffffffff || zi->number_entry >= 0xFFFF) { ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); diff --git a/thirdparty/minizip/zip.h b/thirdparty/minizip/zip.h index 5fc08413241..3e230d3405f 100644 --- a/thirdparty/minizip/zip.h +++ b/thirdparty/minizip/zip.h @@ -177,9 +177,9 @@ extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local - contains the extrafield data the the local header + contains the extrafield data for the local header if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global - contains the extrafield data the the local header + contains the extrafield data for the global header if comment != NULL, comment contain the comment string method contain the compression method (0 for store, Z_DEFLATED for deflate) level contain the level of compression (can be Z_DEFAULT_COMPRESSION) diff --git a/thirdparty/zlib/deflate.c b/thirdparty/zlib/deflate.c index bd011751920..012ea8148e8 100644 --- a/thirdparty/zlib/deflate.c +++ b/thirdparty/zlib/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/thirdparty/zlib/deflate.h b/thirdparty/zlib/deflate.h index 8696791429f..300c6ada62b 100644 --- a/thirdparty/zlib/deflate.h +++ b/thirdparty/zlib/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/thirdparty/zlib/gzguts.h b/thirdparty/zlib/gzguts.h index f9375047e8c..eba72085bb7 100644 --- a/thirdparty/zlib/gzguts.h +++ b/thirdparty/zlib/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -210,9 +210,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/thirdparty/zlib/gzlib.c b/thirdparty/zlib/gzlib.c index 29fc4486fba..983153cc8e4 100644 --- a/thirdparty/zlib/gzlib.c +++ b/thirdparty/zlib/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/thirdparty/zlib/inflate.c b/thirdparty/zlib/inflate.c index b0757a9b249..94ecff015a9 100644 --- a/thirdparty/zlib/inflate.c +++ b/thirdparty/zlib/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/thirdparty/zlib/inftrees.c b/thirdparty/zlib/inftrees.c index 8a208c2daa8..98cfe164458 100644 --- a/thirdparty/zlib/inftrees.c +++ b/thirdparty/zlib/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/thirdparty/zlib/inftrees.h b/thirdparty/zlib/inftrees.h index a10712d8cb5..396f74b5da7 100644 --- a/thirdparty/zlib/inftrees.h +++ b/thirdparty/zlib/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/thirdparty/zlib/trees.c b/thirdparty/zlib/trees.c index 8dbdc40bacc..6a523ef34e3 100644 --- a/thirdparty/zlib/trees.c +++ b/thirdparty/zlib/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/thirdparty/zlib/zconf.h b/thirdparty/zlib/zconf.h index fb76ffe312a..62adc8d8431 100644 --- a/thirdparty/zlib/zconf.h +++ b/thirdparty/zlib/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -300,14 +300,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/thirdparty/zlib/zlib.h b/thirdparty/zlib/zlib.h index 6b7244f9943..8d4b932eaf6 100644 --- a/thirdparty/zlib/zlib.h +++ b/thirdparty/zlib/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -936,10 +936,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1758,14 +1758,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/thirdparty/zlib/zutil.h b/thirdparty/zlib/zutil.h index 902a304cc2d..48dd7febae6 100644 --- a/thirdparty/zlib/zutil.h +++ b/thirdparty/zlib/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -56,7 +56,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -137,17 +137,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -170,18 +161,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 From dc6ae4a8f03651c11d36278866763e586429b307 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Mon, 22 Jan 2024 14:55:20 -0800 Subject: [PATCH 14/35] Disable scissor test after rendering batches in compatibility renderer (cherry picked from commit 062e8802b7a5569f37d6a42e8a270c31b58ff6e6) --- drivers/gles3/rasterizer_canvas_gles3.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index e78d13c462d..101bad8c1e1 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -774,6 +774,7 @@ void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_cou _render_batch(p_lights, i); } + glDisable(GL_SCISSOR_TEST); state.current_batch_index = 0; state.canvas_instance_batches.clear(); state.last_item_index += index; From ab7d9578b7c2ada58334569ea1fef135e87502d1 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Fri, 15 Sep 2023 13:16:14 +0200 Subject: [PATCH 15/35] Clarify `PackedByteArray.decompress*` limitations with external data (cherry picked from commit 4850b866e84ee49cf494dd85813f4b74f816897c) --- doc/classes/PackedByteArray.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml index 3926ea8bebe..f85ab5c65ba 100644 --- a/doc/classes/PackedByteArray.xml +++ b/doc/classes/PackedByteArray.xml @@ -174,6 +174,7 @@ Returns a new [PackedByteArray] with the data decompressed. Set [param buffer_size] to the size of the uncompressed data. Set the compression mode using one of [enum FileAccess.CompressionMode]'s constants. + [b]Note:[/b] Decompression is not guaranteed to work with data not compressed by Godot, for example if data compressed with the deflate compression mode lacks a checksum or header. @@ -184,6 +185,7 @@ Returns a new [PackedByteArray] with the data decompressed. Set the compression mode using one of [enum FileAccess.CompressionMode]'s constants. [b]This method only accepts brotli, gzip, and deflate compression modes.[/b] This method is potentially slower than [code]decompress[/code], as it may have to re-allocate its output buffer multiple times while decompressing, whereas [code]decompress[/code] knows it's output buffer size from the beginning. GZIP has a maximal compression ratio of 1032:1, meaning it's very possible for a small compressed payload to decompress to a potentially very large output. To guard against this, you may provide a maximum size this function is allowed to allocate in bytes via [param max_output_size]. Passing -1 will allow for unbounded output. If any positive value is passed, and the decompression exceeds that amount in bytes, then an error will be returned. + [b]Note:[/b] Decompression is not guaranteed to work with data not compressed by Godot, for example if data compressed with the deflate compression mode lacks a checksum or header. From a8180680afc876f07f64949b66e79a2035818c98 Mon Sep 17 00:00:00 2001 From: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com> Date: Sat, 30 Dec 2023 18:53:54 +0100 Subject: [PATCH 16/35] Fix invalid 3-to-4 renames of `add_animation` to `add_animation_library` This rename breaks `SpriteFrames` and also isn't valid as the new method takes an `AnimationLibrary`, not an `Animation` (cherry picked from commit 4b7ea9fe478c5f6c6a3477cb4d81872f9d5538c8) --- editor/renames_map_3_to_4.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/editor/renames_map_3_to_4.cpp b/editor/renames_map_3_to_4.cpp index 952b07b870b..9c18872ccc7 100644 --- a/editor/renames_map_3_to_4.cpp +++ b/editor/renames_map_3_to_4.cpp @@ -163,6 +163,7 @@ const char *RenamesMap3To4::gdscript_function_renames[][2] = { // { "_set_name", "get_tracker_name" }, // XRPositionalTracker -- CameraFeed uses this. // { "_unhandled_input", "_unhandled_key_input" }, // BaseButton, ViewportContainer -- Breaks Node, FileDialog, SubViewportContainer. + // { "add_animation", "add_animation_library" }, // AnimationPlayer -- Breaks SpriteFrames (and isn't a correct conversion). // { "create_gizmo", "_create_gizmo" }, // EditorNode3DGizmoPlugin -- May be used. // { "get_dependencies", "_get_dependencies" }, // ResourceFormatLoader -- Breaks ResourceLoader. // { "get_extents", "get_size" }, // BoxShape, RectangleShape -- Breaks Decal, VoxelGI, GPUParticlesCollisionBox, GPUParticlesCollisionSDF, GPUParticlesCollisionHeightField, GPUParticlesAttractorBox, GPUParticlesAttractorVectorField, FogVolume @@ -214,8 +215,6 @@ const char *RenamesMap3To4::gdscript_function_renames[][2] = { { "_set_current", "set_current" }, // Camera2D { "_set_editor_description", "set_editor_description" }, // Node { "_toplevel_raise_self", "_top_level_raise_self" }, // CanvasItem - { "_update_wrap_at", "_update_wrap_at_column" }, // TextEdit - { "add_animation", "add_animation_library" }, // AnimationPlayer { "add_cancel", "add_cancel_button" }, // AcceptDialog { "add_central_force", "apply_central_force" }, //RigidBody2D { "add_child_below_node", "add_sibling" }, // Node @@ -643,8 +642,6 @@ const char *RenamesMap3To4::csharp_function_renames[][2] = { { "_SetEditorDescription", "SetEditorDescription" }, // Node { "_SetPlaying", "SetPlaying" }, // AnimatedSprite3D { "_ToplevelRaiseSelf", "_TopLevelRaiseSelf" }, // CanvasItem - { "_UpdateWrapAt", "_UpdateWrapAtColumn" }, // TextEdit - { "AddAnimation", "AddAnimationLibrary" }, // AnimationPlayer { "AddCancel", "AddCancelButton" }, // AcceptDialog { "AddCentralForce", "AddConstantCentralForce" }, //RigidBody2D { "AddChildBelowNode", "AddSibling" }, // Node From 307a6eba6b3246d0889a91861ea99660d1e15432 Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Thu, 9 Nov 2023 10:26:18 -0800 Subject: [PATCH 17/35] Update the validation logic for the package name: - When using the project name, allow underscore (`_`) characters - Send a warning instead of an error when the project name is modified to fit the package name format (cherry picked from commit 0325568a9bb9b9e33e5fe145b69cf3759aaa0027) --- platform/android/export/export_plugin.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 233a168a00d..e2d0f71c122 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -456,7 +456,7 @@ String EditorExportPlatformAndroid::get_valid_basename() const { if (is_digit(c) && first) { continue; } - if (is_ascii_alphanumeric_char(c)) { + if (is_ascii_identifier_char(c)) { name += String::chr(c); first = false; } @@ -533,13 +533,6 @@ bool EditorExportPlatformAndroid::is_package_name_valid(const String &p_package, return false; } - if (p_package.find("$genname") >= 0 && !is_project_name_valid()) { - if (r_error) { - *r_error = TTR("The project name does not meet the requirement for the package name format. Please explicitly specify the package name."); - } - return false; - } - return true; } @@ -2435,6 +2428,13 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Refget("package/unique_name"); + if (package_name.find("$genname") >= 0 && !is_project_name_valid()) { + // Warning only, so don't override `valid`. + err += vformat(TTR("The project name does not meet the requirement for the package name format and will be updated to \"%s\". Please explicitly specify the package name if needed."), get_valid_basename()); + err += "\n"; + } + r_error = err; return valid; } From 4b71c38e4792b1d25434ef84910ca72b7973d460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Thu, 30 Nov 2023 09:46:24 +0100 Subject: [PATCH 18/35] Remove redundant explicit clears in the Vulkan RD (cherry picked from commit 4964d9a083fd9179148b942c2301e6b6fdf58fda) --- drivers/vulkan/rendering_device_vulkan.cpp | 103 +++++++++++++-------- drivers/vulkan/rendering_device_vulkan.h | 2 +- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index d06a78f0494..c4694541b2f 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -6713,24 +6713,24 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu return OK; } -Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector &p_storage_textures) { +Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector &p_storage_textures, bool p_constrained_to_region) { VkRenderPassBeginInfo render_pass_begin; render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin.pNext = nullptr; render_pass_begin.renderPass = render_pass; render_pass_begin.framebuffer = vkframebuffer; - /* - * Given how API works, it makes sense to always fully operate on the whole framebuffer. - * This allows better continue operations for operations like shadowmapping. - render_pass_begin.renderArea.extent.width = viewport_size.width; - render_pass_begin.renderArea.extent.height = viewport_size.height; - render_pass_begin.renderArea.offset.x = viewport_offset.x; - render_pass_begin.renderArea.offset.y = viewport_offset.y; - */ - render_pass_begin.renderArea.extent.width = framebuffer->size.width; - render_pass_begin.renderArea.extent.height = framebuffer->size.height; - render_pass_begin.renderArea.offset.x = 0; - render_pass_begin.renderArea.offset.y = 0; + + if (p_constrained_to_region) { + render_pass_begin.renderArea.extent.width = viewport_size.width; + render_pass_begin.renderArea.extent.height = viewport_size.height; + render_pass_begin.renderArea.offset.x = viewport_offset.x; + render_pass_begin.renderArea.offset.y = viewport_offset.y; + } else { + render_pass_begin.renderArea.extent.width = framebuffer->size.width; + render_pass_begin.renderArea.extent.height = framebuffer->size.height; + render_pass_begin.renderArea.offset.x = 0; + render_pass_begin.renderArea.offset.y = 0; + } Vector clear_values; clear_values.resize(framebuffer->texture_ids.size()); @@ -6880,6 +6880,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu Point2i viewport_offset; Point2i viewport_size = framebuffer->size; + bool constrained_to_region = false; bool needs_clear_color = false; bool needs_clear_depth = false; @@ -6894,21 +6895,30 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { - needs_clear_color = true; - p_initial_color_action = INITIAL_ACTION_CONTINUE; - } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { - needs_clear_depth = true; - p_initial_depth_action = INITIAL_ACTION_CONTINUE; - } - if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { - needs_clear_color = true; - p_initial_color_action = INITIAL_ACTION_KEEP; - } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { - needs_clear_depth = true; - p_initial_depth_action = INITIAL_ACTION_KEEP; + + // If clearing regions both in color and depth, we can switch to a fast path where we let Vulkan to the clears + // and we constrain the render area to the region. + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION && p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { + constrained_to_region = true; + p_initial_color_action = INITIAL_ACTION_CLEAR; + p_initial_depth_action = INITIAL_ACTION_CLEAR; + } else { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_KEEP; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_KEEP; + } } } @@ -6935,7 +6945,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu ERR_FAIL_COND_V(err != OK, INVALID_ID); VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; - err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE, p_storage_textures); + err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, command_buffer, VK_SUBPASS_CONTENTS_INLINE, p_storage_textures, constrained_to_region); if (err != OK) { return INVALID_ID; @@ -6951,6 +6961,7 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu draw_list_current_subpass = 0; if (needs_clear_color || needs_clear_depth) { + DEV_ASSERT(!constrained_to_region); _draw_list_insert_clear_region(draw_list, framebuffer, viewport_offset, viewport_size, needs_clear_color, p_clear_color_values, needs_clear_depth, p_clear_depth, p_clear_stencil); } @@ -6989,6 +7000,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p Point2i viewport_offset; Point2i viewport_size = framebuffer->size; + bool constrained_to_region = false; bool needs_clear_color = false; bool needs_clear_depth = false; @@ -7004,13 +7016,29 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { - needs_clear_color = true; - p_initial_color_action = INITIAL_ACTION_KEEP; - } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { - needs_clear_depth = true; - p_initial_depth_action = INITIAL_ACTION_KEEP; + // If clearing regions both in color and depth, we can switch to a fast path where we let Vulkan to the clears + // and we constrain the render area to the region. + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION && p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { + constrained_to_region = true; + p_initial_color_action = INITIAL_ACTION_CLEAR; + p_initial_depth_action = INITIAL_ACTION_CLEAR; + } else { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION_CONTINUE) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_CONTINUE; + } + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { + needs_clear_color = true; + p_initial_color_action = INITIAL_ACTION_KEEP; + } + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { + needs_clear_depth = true; + p_initial_depth_action = INITIAL_ACTION_KEEP; + } } } @@ -7036,7 +7064,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); VkCommandBuffer frame_command_buffer = frames[frame].draw_command_buffer; - err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, p_storage_textures); + err = _draw_list_render_pass_begin(framebuffer, p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, viewport_offset, viewport_size, vkframebuffer, render_pass, frame_command_buffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, p_storage_textures, constrained_to_region); if (err != OK) { return ERR_CANT_CREATE; @@ -7056,6 +7084,7 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p } if (needs_clear_color || needs_clear_depth) { + DEV_ASSERT(!constrained_to_region); _draw_list_insert_clear_region(&draw_list[0], framebuffer, viewport_offset, viewport_size, needs_clear_color, p_clear_color_values, needs_clear_depth, p_clear_depth, p_clear_stencil); } diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 9c621c1d441..969b581752d 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -929,7 +929,7 @@ class RenderingDeviceVulkan : public RenderingDevice { void _draw_list_insert_clear_region(DrawList *p_draw_list, Framebuffer *p_framebuffer, Point2i p_viewport_offset, Point2i p_viewport_size, bool p_clear_color, const Vector &p_clear_colors, bool p_clear_depth, float p_depth, uint32_t p_stencil); Error _draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass, uint32_t *r_subpass_count); - Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector &p_storage_textures); + Error _draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents, const Vector &p_storage_textures, bool p_constrained_to_region); _FORCE_INLINE_ DrawList *_get_draw_list_ptr(DrawListID p_id); Buffer *_get_buffer_from_owner(RID p_buffer, VkPipelineStageFlags &dst_stage_mask, VkAccessFlags &dst_access, BitField p_post_barrier); Error _draw_list_allocate(const Rect2i &p_viewport, uint32_t p_splits, uint32_t p_subpass); From 62485a51fd6b2a92a1929803a41f20ff1e6b7fcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Thu, 30 Nov 2023 13:05:29 +0100 Subject: [PATCH 19/35] Remove superfluous locking in RID owners in Vulkan RD (cherry picked from commit 72bf8dfecfc08ef189012d002a05a740d72135a1) --- drivers/vulkan/rendering_device_vulkan.h | 26 ++++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h index 969b581752d..b43c9d03d89 100644 --- a/drivers/vulkan/rendering_device_vulkan.h +++ b/drivers/vulkan/rendering_device_vulkan.h @@ -159,7 +159,7 @@ class RenderingDeviceVulkan : public RenderingDevice { RID owner; }; - RID_Owner texture_owner; + RID_Owner texture_owner; uint32_t texture_upload_region_size_px = 0; Vector _texture_get_data_from_image(Texture *tex, VkImage p_image, VmaAllocation p_allocation, uint32_t p_layer, bool p_2d = false); @@ -409,7 +409,7 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t view_count; }; - RID_Owner framebuffer_owner; + RID_Owner framebuffer_owner; /***********************/ /**** VERTEX BUFFER ****/ @@ -424,7 +424,7 @@ class RenderingDeviceVulkan : public RenderingDevice { // This mapping is done here internally, and it's not // exposed. - RID_Owner vertex_buffer_owner; + RID_Owner vertex_buffer_owner; struct VertexDescriptionKey { Vector vertex_formats; @@ -506,7 +506,7 @@ class RenderingDeviceVulkan : public RenderingDevice { Vector offsets; }; - RID_Owner vertex_array_owner; + RID_Owner vertex_array_owner; struct IndexBuffer : public Buffer { uint32_t max_index = 0; // Used for validation. @@ -515,7 +515,7 @@ class RenderingDeviceVulkan : public RenderingDevice { bool supports_restart_indices = false; }; - RID_Owner index_buffer_owner; + RID_Owner index_buffer_owner; struct IndexArray { uint32_t max_index = 0; // Remember the maximum index here too, for validation. @@ -526,7 +526,7 @@ class RenderingDeviceVulkan : public RenderingDevice { bool supports_restart_indices = false; }; - RID_Owner index_array_owner; + RID_Owner index_array_owner; /****************/ /**** SHADER ****/ @@ -649,7 +649,7 @@ class RenderingDeviceVulkan : public RenderingDevice { String _shader_uniform_debug(RID p_shader, int p_set = -1); - RID_Owner shader_owner; + RID_Owner shader_owner; /******************/ /**** UNIFORMS ****/ @@ -713,8 +713,8 @@ class RenderingDeviceVulkan : public RenderingDevice { DescriptorPool *_descriptor_pool_allocate(const DescriptorPoolKey &p_key); void _descriptor_pool_free(const DescriptorPoolKey &p_key, DescriptorPool *p_pool); - RID_Owner uniform_buffer_owner; - RID_Owner storage_buffer_owner; + RID_Owner uniform_buffer_owner; + RID_Owner storage_buffer_owner; // Texture buffer needs a view. struct TextureBuffer { @@ -722,7 +722,7 @@ class RenderingDeviceVulkan : public RenderingDevice { VkBufferView view = VK_NULL_HANDLE; }; - RID_Owner texture_buffer_owner; + RID_Owner texture_buffer_owner; // This structure contains the descriptor set. They _need_ to be allocated // for a shader (and will be erased when this shader is erased), but should @@ -752,7 +752,7 @@ class RenderingDeviceVulkan : public RenderingDevice { void *invalidated_callback_userdata = nullptr; }; - RID_Owner uniform_set_owner; + RID_Owner uniform_set_owner; /*******************/ /**** PIPELINES ****/ @@ -791,7 +791,7 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t push_constant_stages_mask = 0; }; - RID_Owner render_pipeline_owner; + RID_Owner render_pipeline_owner; struct PipelineCacheHeader { uint32_t magic; @@ -828,7 +828,7 @@ class RenderingDeviceVulkan : public RenderingDevice { uint32_t local_group_size[3] = { 0, 0, 0 }; }; - RID_Owner compute_pipeline_owner; + RID_Owner compute_pipeline_owner; /*******************/ /**** DRAW LIST ****/ From c9924b11a4af21ab7235f1045715fe71d0236982 Mon Sep 17 00:00:00 2001 From: rsburke4 Date: Sat, 11 Nov 2023 22:17:56 -0500 Subject: [PATCH 20/35] Added error to catch conversion on invalid image (cherry picked from commit dec2269bca8c616dac73ec987f7e670cf0451c77) --- core/io/image.cpp | 1 + tests/core/io/test_image.h | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/core/io/image.cpp b/core/io/image.cpp index 9bb987b670c..d5c246bf2c0 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -509,6 +509,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p } void Image::convert(Format p_new_format) { + ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, "The Image format specified (" + itos(p_new_format) + ") is out of range. See Image's Format enum."); if (data.size() == 0) { return; } diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h index 4f43f184523..d88bcaa813a 100644 --- a/tests/core/io/test_image.h +++ b/tests/core/io/test_image.h @@ -323,6 +323,30 @@ TEST_CASE("[Image] Modifying pixels of an image") { CHECK_MESSAGE(gray_image->get_pixel(2, 2).is_equal_approx(Color(0.266666681, 0.266666681, 0.266666681, 1)), "convert() RGBA to L8 should be around 0.266666681 (68)."); } } + +TEST_CASE("[Image] Convert image") { + for (int format = Image::FORMAT_RF; format < Image::FORMAT_RGBE9995; format++) { + for (int new_format = Image::FORMAT_RF; new_format < Image::FORMAT_RGBE9995; new_format++) { + Ref image = memnew(Image(4, 4, false, (Image::Format)format)); + image->convert((Image::Format)new_format); + String format_string = Image::format_names[(Image::Format)format]; + String new_format_string = Image::format_names[(Image::Format)new_format]; + format_string = "Error converting from " + format_string + " to " + new_format_string + "."; + CHECK_MESSAGE(image->get_format() == new_format, format_string); + } + } + + Ref image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8)); + PackedByteArray image_data = image->get_data(); + image->convert((Image::Format)-1); + CHECK_MESSAGE(image->get_data() == image_data, "Image conversion to invalid type (-1) should not alter image."); + + Ref image2 = memnew(Image(4, 4, false, Image::FORMAT_RGBA8)); + image_data = image2->get_data(); + image2->convert((Image::Format)(Image::FORMAT_MAX + 1)); + CHECK_MESSAGE(image2->get_data() == image_data, "Image conversion to invalid type (Image::FORMAT_MAX + 1) should not alter image."); +} + } // namespace TestImage #endif // TEST_IMAGE_H From c8fabac8c76d72edc203232a4bd96d6a6e4e2c1a Mon Sep 17 00:00:00 2001 From: Ricardo Subtil Date: Tue, 14 Nov 2023 16:51:38 +0000 Subject: [PATCH 21/35] Fix DAP breakpoints being cleared on closed scripts (cherry picked from commit 760ff2e9339b95bcad1e4045c330c06e0ce9c98c) --- editor/plugins/script_editor_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 4b379807b67..e0148e8030a 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -536,7 +536,7 @@ void ScriptEditor::_set_breakpoint(Ref p_script, int p_line, bool p_ } state["breakpoints"] = breakpoints; script_editor_cache->set_value(scr->get_path(), "state", state); - EditorDebuggerNode::get_singleton()->set_breakpoint(scr->get_path(), p_line + 1, false); + EditorDebuggerNode::get_singleton()->set_breakpoint(scr->get_path(), p_line + 1, p_enabled); } } From afac25a3f8de9b4ea3c559d65d12c3d1d9ba2335 Mon Sep 17 00:00:00 2001 From: LunaticInAHat Date: Tue, 19 Dec 2023 13:23:42 -0500 Subject: [PATCH 22/35] Support unspecified linear size in DDS files Not all exporters choose to populate that (optional) header field. (cherry picked from commit a344d7f9065af4762bc4c9dba90d40c52f9102e4) --- modules/dds/texture_loader_dds.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index a8d83e2490b..f5280870e07 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -220,8 +220,12 @@ Ref ResourceFormatDDS::load(const String &p_path, const String &p_orig //compressed bc uint32_t size = MAX(info.divisor, w) / info.divisor * MAX(info.divisor, h) / info.divisor * info.block_size; - ERR_FAIL_COND_V(size != pitch, Ref()); - ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), Ref()); + + if (flags & DDSD_LINEARSIZE) { + ERR_FAIL_COND_V_MSG(size != pitch, Ref(), "DDS header flags specify that a linear size of the top-level image is present, but the specified size does not match the expected value."); + } else { + ERR_FAIL_COND_V_MSG(pitch != 0, Ref(), "DDS header flags specify that no linear size will given for the top-level image, but a non-zero linear size value is present in the header."); + } for (uint32_t i = 1; i < mipmaps; i++) { w = MAX(1u, w >> 1); From 0904f0affda1c0256a63a7280cf163b3f6965f58 Mon Sep 17 00:00:00 2001 From: Michael Macha Date: Tue, 19 Dec 2023 04:46:34 -0700 Subject: [PATCH 23/35] Remove pointer to deprecated class page, from Skeleton3D SkeletonIK3D is now deprecated, but Skeleton3D is recommending looking into its use for complicated inverse kinematics. What's worse, the removed line is not perfectly clear for non-developers and people less experienced with the engine, and could still stand to be improved. (cherry picked from commit 0e52ffeb699f6d3a7164133912c7491d0b1c876f) --- doc/classes/Skeleton3D.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index a3f0a6c734a..7184928d71f 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -7,7 +7,6 @@ [Skeleton3D] provides an interface for managing a hierarchy of bones, including pose, rest and animation (see [Animation]). It can also use ragdoll physics. The overall transform of a bone with respect to the skeleton is determined by bone pose. Bone rest defines the initial transform of the bone pose. Note that "global pose" below refers to the overall transform of the bone with respect to skeleton, so it is not the actual global/world transform of the bone. - To setup different types of inverse kinematics, consider using [SkeletonIK3D], or add a custom IK implementation in [method Node._process] as a child node. https://godotengine.org/asset-library/asset/523 From e11165d7f18de7e728234cf00392aa48a8902dd4 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Sun, 17 Dec 2023 12:27:24 +0100 Subject: [PATCH 24/35] [MP] Fix complete_auth notifying the wrong peer The SceneMultiplayer complete_auth method was not configuring the multiplayer peer correctly, causing it to potentially send the notification to the wrong peer, on the wrong channel, and/or with an incorrect transfer mode. (cherry picked from commit 4826c14d2042aa8044d9751d459aeab644bcb602) --- modules/multiplayer/scene_multiplayer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/multiplayer/scene_multiplayer.cpp b/modules/multiplayer/scene_multiplayer.cpp index 3e3118b1cd4..36f46ea371d 100644 --- a/modules/multiplayer/scene_multiplayer.cpp +++ b/modules/multiplayer/scene_multiplayer.cpp @@ -483,9 +483,14 @@ Error SceneMultiplayer::complete_auth(int p_peer) { ERR_FAIL_COND_V(!pending_peers.has(p_peer), ERR_INVALID_PARAMETER); ERR_FAIL_COND_V_MSG(pending_peers[p_peer].local, ERR_FILE_CANT_WRITE, "The authentication session was already marked as completed."); pending_peers[p_peer].local = true; + // Notify the remote peer that the authentication has completed. uint8_t buf[2] = { NETWORK_COMMAND_SYS, SYS_COMMAND_AUTH }; + multiplayer_peer->set_target_peer(p_peer); + multiplayer_peer->set_transfer_channel(0); + multiplayer_peer->set_transfer_mode(MultiplayerPeer::TRANSFER_MODE_RELIABLE); Error err = _send(buf, 2); + // The remote peer already reported the authentication as completed, so admit the peer. // May generate new packets, so it must happen after sending confirmation. if (pending_peers[p_peer].remote) { From c72c69379a4f7b7f7f00f4fd5e69a39089d3bf62 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 19 Dec 2023 17:29:49 +0100 Subject: [PATCH 25/35] Improve RichTextLabel `install_effect()` documentation (cherry picked from commit 78fff7292cfd5938f316dfaea7cc11e4fc570ca3) --- doc/classes/RichTextEffect.xml | 2 +- doc/classes/RichTextLabel.xml | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml index 7d91987e7f9..8467e4e1149 100644 --- a/doc/classes/RichTextEffect.xml +++ b/doc/classes/RichTextEffect.xml @@ -4,7 +4,7 @@ A custom effect for a [RichTextLabel]. - A custom effect for a [RichTextLabel]. + A custom effect for a [RichTextLabel], which can be loaded in the [RichTextLabel] inspector or using [method RichTextLabel.install_effect]. [b]Note:[/b] For a [RichTextEffect] to be usable, a BBCode tag must be defined as a member variable called [code]bbcode[/code] in the script. [codeblocks] [gdscript] diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 6fbdb4faadb..623fddcb4ce 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -218,7 +218,28 @@ - Installs a custom effect. [param effect] should be a valid [RichTextEffect]. + Installs a custom effect. This can also be done in the RichTextLabel inspector using the [member custom_effects] property. [param effect] should be a valid [RichTextEffect]. + Example RichTextEffect: + [codeblock] + # effect.gd + class_name MyCustomEffect + extends RichTextEffect + + var bbcode = "my_custom_effect" + + # ... + [/codeblock] + Registering the above effect in RichTextLabel from script: + [codeblock] + # rich_text_label.gd + extends RichTextLabel + + func _ready(): + install_effect(MyCustomEffect.new()) + + # Alternatively, if not using `class_name` in the script that extends RichTextEffect: + install_effect(preload("res://effect.gd").new()) + [/codeblock] From 57fe32f8daaff4e6c2713f49cb651893c1766d45 Mon Sep 17 00:00:00 2001 From: Quincy Wofford Date: Sat, 30 Dec 2023 20:08:19 -0700 Subject: [PATCH 26/35] corrected tooltip information Roll Influence property of VehicleWheel3D (cherry picked from commit c979d02db27acb3e9c6fbd3dfe68d5f78fb55f62) --- doc/classes/VehicleWheel3D.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/classes/VehicleWheel3D.xml b/doc/classes/VehicleWheel3D.xml index c4ebed84c5a..b110eb29210 100644 --- a/doc/classes/VehicleWheel3D.xml +++ b/doc/classes/VehicleWheel3D.xml @@ -81,7 +81,7 @@ This is the distance in meters the wheel is lowered from its origin point. Don't set this to 0.0 and move the wheel into position, instead move the origin point of your wheel (the gizmo in Godot) to the position the wheel will take when bottoming out, then use the rest length to move the wheel down to the position it should be in when the car is in rest. - This value affects the roll of your vehicle. If set to 1.0 for all wheels, your vehicle will be prone to rolling over, while a value of 0.0 will resist body roll. + This value affects the roll of your vehicle. If set to 1.0 for all wheels, your vehicle will resist body roll, while a value of 0.0 will be prone to rolling over. From 329f2ce49be795ee855bbbd824c4a7159677e247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 6 Dec 2023 13:12:18 +0100 Subject: [PATCH 27/35] Style: Mark clang-format 16 as supported for pre-commit hook It only introduced a difference in a .glsl file, which I've worked around by removing an empty line. This keeps formatting consistent between clang-format 15 and 16. Also added a change in the 3-to-4 project converter to fix bogus formatting in clang-format < 17. (cherry picked from commit 49f4860ce3e4122e17c869229701f7d86aa6956c) --- drivers/gles3/shaders/scene.glsl | 3 +- editor/project_converter_3_to_4.cpp | 193 ++++++++++++++-------------- misc/hooks/README.md | 2 +- misc/hooks/pre-commit-clang-format | 2 +- 4 files changed, 100 insertions(+), 100 deletions(-) diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index aa68febec8f..69c1982935b 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -434,8 +434,7 @@ layout(std140) uniform GlobalShaderUniformData { //ubo:1 vec4 global_shader_uniforms[MAX_GLOBAL_SHADER_UNIFORMS]; }; - /* Material Uniforms */ - +/* Material Uniforms */ #ifdef MATERIAL_UNIFORMS_USED /* clang-format off */ diff --git a/editor/project_converter_3_to_4.cpp b/editor/project_converter_3_to_4.cpp index d6ed5eb995f..82462866cf6 100644 --- a/editor/project_converter_3_to_4.cpp +++ b/editor/project_converter_3_to_4.cpp @@ -1044,107 +1044,108 @@ bool ProjectConverter3To4::test_conversion(RegExContainer ®_container) { // get_object_of_execution { - { String base = "var roman = kieliszek."; - String expected = "kieliszek."; - String got = get_object_of_execution(base); - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + String base = "var roman = kieliszek."; + String expected = "kieliszek."; + String got = get_object_of_execution(base); + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); } - valid = valid && (got == expected); -} -{ - String base = "r."; - String expected = "r."; - String got = get_object_of_execution(base); - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + { + String base = "r."; + String expected = "r."; + String got = get_object_of_execution(base); + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); } - valid = valid && (got == expected); -} -{ - String base = "mortadela("; - String expected = ""; - String got = get_object_of_execution(base); - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + { + String base = "mortadela("; + String expected = ""; + String got = get_object_of_execution(base); + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); } - valid = valid && (got == expected); -} -{ - String base = "var node = $world/ukraine/lviv."; - String expected = "$world/ukraine/lviv."; - String got = get_object_of_execution(base); - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + { + String base = "var node = $world/ukraine/lviv."; + String expected = "$world/ukraine/lviv."; + String got = get_object_of_execution(base); + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); } - valid = valid && (got == expected); -} -} -// get_starting_space -{ - String base = "\t\t\t var roman = kieliszek."; - String expected = "\t\t\t"; - String got = get_starting_space(base); - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); - } - valid = valid && (got == expected); -} -// Parse Arguments -{ - String line = "( )"; - Vector got_vector = parse_arguments(line); - String got = ""; - String expected = ""; - for (String &part : got_vector) { - got += part + "|||"; - } - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); - } - valid = valid && (got == expected); -} -{ - String line = "(a , b , c)"; - Vector got_vector = parse_arguments(line); - String got = ""; - String expected = "a|||b|||c|||"; - for (String &part : got_vector) { - got += part + "|||"; - } - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); - } - valid = valid && (got == expected); -} -{ - String line = "(a , \"b,\" , c)"; - Vector got_vector = parse_arguments(line); - String got = ""; - String expected = "a|||\"b,\"|||c|||"; - for (String &part : got_vector) { - got += part + "|||"; - } - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); - } - valid = valid && (got == expected); -} -{ - String line = "(a , \"(,),,,,\" , c)"; - Vector got_vector = parse_arguments(line); - String got = ""; - String expected = "a|||\"(,),,,,\"|||c|||"; - for (String &part : got_vector) { - got += part + "|||"; - } - if (got != expected) { - ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); - } - valid = valid && (got == expected); -} -return valid; + // get_starting_space + { + String base = "\t\t\t var roman = kieliszek."; + String expected = "\t\t\t"; + String got = get_starting_space(base); + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from get_object_of_execution. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", base, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); + } + + // Parse Arguments + { + String line = "( )"; + Vector got_vector = parse_arguments(line); + String got = ""; + String expected = ""; + for (String &part : got_vector) { + got += part + "|||"; + } + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); + } + { + String line = "(a , b , c)"; + Vector got_vector = parse_arguments(line); + String got = ""; + String expected = "a|||b|||c|||"; + for (String &part : got_vector) { + got += part + "|||"; + } + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); + } + { + String line = "(a , \"b,\" , c)"; + Vector got_vector = parse_arguments(line); + String got = ""; + String expected = "a|||\"b,\"|||c|||"; + for (String &part : got_vector) { + got += part + "|||"; + } + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); + } + { + String line = "(a , \"(,),,,,\" , c)"; + Vector got_vector = parse_arguments(line); + String got = ""; + String expected = "a|||\"(,),,,,\"|||c|||"; + for (String &part : got_vector) { + got += part + "|||"; + } + if (got != expected) { + ERR_PRINT(vformat("Failed to get proper data from parse_arguments. \"%s\" should return \"%s\"(%d), got \"%s\"(%d), instead.", line, expected, expected.size(), got, got.size())); + } + valid = valid && (got == expected); + } + + return valid; } // Validate in all arrays if names don't do cyclic renames "Node" -> "Node2D" | "Node2D" -> "2DNode" diff --git a/misc/hooks/README.md b/misc/hooks/README.md index 0aaeff8ae32..573f8fe350b 100644 --- a/misc/hooks/README.md +++ b/misc/hooks/README.md @@ -29,7 +29,7 @@ so they should work out of the box on Linux/macOS. ##### clang-format - Download LLVM for Windows (version 13 or later) from - + - Make sure LLVM is added to the `PATH` during installation ##### black diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format index fd0213c175e..e5cf0c4aa23 100755 --- a/misc/hooks/pre-commit-clang-format +++ b/misc/hooks/pre-commit-clang-format @@ -80,7 +80,7 @@ fi # To get consistent formatting, we recommend contributors to use the same # clang-format version as CI. RECOMMENDED_CLANG_FORMAT_MAJOR_MIN="13" -RECOMMENDED_CLANG_FORMAT_MAJOR_MAX="15" +RECOMMENDED_CLANG_FORMAT_MAJOR_MAX="16" if [ ! -x "$CLANG_FORMAT" ] ; then message="Error: clang-format executable not found. Please install clang-format $RECOMMENDED_CLANG_FORMAT_MAJOR_MAX." From c02fcb4edef7be2a05f3be05bb55065ac91521eb Mon Sep 17 00:00:00 2001 From: Micky Date: Sat, 6 Jan 2024 19:06:48 +0100 Subject: [PATCH 28/35] Add missing descriptions to TextServer's constants (cherry picked from commit d3150c9c8f83d1f6ca3adeb6cbdda32600c4457d) --- doc/classes/TextServer.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml index 17805f259cd..8bf12e8ea4f 100644 --- a/doc/classes/TextServer.xml +++ b/doc/classes/TextServer.xml @@ -1647,6 +1647,7 @@ Vertical BGR subpixel layout. + Represents the size of the [enum FontLCDSubpixelLayout] enum. Text direction is determined based on contents and current locale. @@ -1770,6 +1771,7 @@ Determines whether the ellipsis at the end of the text is enforced and may not be hidden. + Accounts for the text being justified before attempting to trim it (see [enum JustificationFlag]). Grapheme is supported by the font, and can be drawn. @@ -1908,6 +1910,7 @@ Spacing at the bottom of the line. + Represents the size of the [enum SpacingType] enum. Font is bold. From ffed9d36b5468a9e6ea6994d378760ed65b79cde Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 31 Jan 2023 17:28:04 +0100 Subject: [PATCH 29/35] Make the rendering method dropdown also affect mobile if compatible This prevents visual discrepancies between desktop and mobile platforms after switching rendering methods using this dropdown. The restart dialog now displays which rendering methods will be used, and the dropdown tooltip also lists caveats related to specific platforms. (cherry picked from commit 57f3bdb1e5f775f43b67386b1f625cc7ad414d07) --- editor/editor_node.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 75a56ba2668..3fabe36bd36 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2925,6 +2925,16 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } break; case SET_RENDERER_NAME_SAVE_AND_RESTART: { ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method", renderer_request); + if (renderer_request == "mobile" || renderer_request == "gl_compatibility") { + // Also change the mobile override if changing to a compatible rendering method. + // This prevents visual discrepancies between desktop and mobile platforms. + ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", renderer_request); + } else if (renderer_request == "forward_plus") { + // Use the equivalent mobile rendering method. This prevents the rendering method from staying + // on its old choice if moving from `gl_compatibility` to `forward_plus`. + ProjectSettings::get_singleton()->set("rendering/renderer/rendering_method.mobile", "mobile"); + } + ProjectSettings::get_singleton()->save(); save_all_scenes(); @@ -6571,6 +6581,9 @@ void EditorNode::_renderer_selected(int p_which) { } renderer_request = rendering_method; + video_restart_dialog->set_text( + vformat(TTR("Changing the renderer requires restarting the editor.\n\nChoosing Save & Restart will change the rendering method to:\n- Desktop platforms: %s\n- Mobile platforms: %s\n- Web platform: gl_compatibility"), + renderer_request, renderer_request.replace("forward_plus", "mobile"))); video_restart_dialog->popup_centered(); renderer->select(renderer_current); _update_renderer_color(); @@ -7583,7 +7596,7 @@ EditorNode::EditorNode() { renderer->connect("item_selected", callable_mp(this, &EditorNode::_renderer_selected)); renderer->add_theme_font_override("font", gui_base->get_theme_font(SNAME("bold"), SNAME("EditorFonts"))); renderer->add_theme_font_size_override("font_size", gui_base->get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"))); - renderer->set_tooltip_text(TTR("Choose a renderer.")); + renderer->set_tooltip_text(TTR("Choose a rendering method.\n\nNotes:\n- On mobile platforms, the Mobile rendering method is used if Forward+ is selected here.\n- On the web platform, the Compatibility rendering method is always used.")); right_menu_hb->add_child(renderer); @@ -7628,7 +7641,6 @@ EditorNode::EditorNode() { _update_renderer_color(); video_restart_dialog = memnew(ConfirmationDialog); - video_restart_dialog->set_text(TTR("Changing the renderer requires restarting the editor.")); video_restart_dialog->set_ok_button_text(TTR("Save & Restart")); video_restart_dialog->connect("confirmed", callable_mp(this, &EditorNode::_menu_option).bind(SET_RENDERER_NAME_SAVE_AND_RESTART)); gui_base->add_child(video_restart_dialog); From 45fc8a3b4399d2e8568d2ce880157a41a0e57a39 Mon Sep 17 00:00:00 2001 From: Micky Date: Tue, 9 Jan 2024 13:28:19 +0100 Subject: [PATCH 30/35] Add missing descriptions for Image's documentation (cherry picked from commit e01b91777a742c5dd562b3c3b9241ee0d9620d8f) --- doc/classes/Image.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 0a5281f1d05..bae44d8c75e 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -18,6 +18,7 @@ + Adjusts this image's [param brightness], [param contrast], and [param saturation] by the given values. Does not work if the image is compressed (see [method is_compressed]). @@ -162,6 +163,7 @@ + Returns the color channels used by this image, as one of the [enum UsedChannels] constants. If the image is compressed, the original [param source] must be specified. @@ -572,6 +574,7 @@ OpenGL texture format [code]RGBA[/code] with four components, each with a bitdepth of 4. + OpenGL texture format [code]RGB[/code] with three components. Red and blue have a bitdepth of 5, and green has a bitdepth of 6. OpenGL texture format [code]GL_R32F[/code] where there's one component, a 32-bit floating-point value. @@ -656,8 +659,10 @@ [b]Note:[/b] When creating an [ImageTexture], an sRGB to linear color space conversion is performed. + [url=https://en.wikipedia.org/wiki/Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression format 2[/url] ([code]RGBA8[/code] variant), which compresses RA data and interprets it as two channels (red and green). See also [constant FORMAT_ETC2_RGBA8]. + The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] texture format also known as Block Compression 3 or BC3, which compresses RA data and interprets it as two channels (red and green). See also [constant FORMAT_DXT5]. [url=https://en.wikipedia.org/wiki/Adaptive_scalable_texture_compression]Adaptive Scalable Texutre Compression[/url]. This implements the 4x4 (high quality) mode. @@ -721,16 +726,22 @@ Represents the size of the [enum CompressMode] enum. + The image only uses one channel for luminance (grayscale). + The image uses two channels for luminance and alpha, respectively. + The image only uses the red channel. + The image uses two channels for red and green. + The image uses three channels for red, green, and blue. + The image uses four channels for red, green, blue, and alpha. Source texture (before compression) is a regular texture. Default for all textures. From f5c7a0e8327d425f7c1fd673b5e71b42fd805d7a Mon Sep 17 00:00:00 2001 From: jsjtxietian Date: Wed, 10 Jan 2024 11:14:57 +0800 Subject: [PATCH 31/35] Mention CollisionPolygon2D.polygon is local to the given CollisionPolygon2D (cherry picked from commit f5409dc132ae81c2819f30882a88fd3205fc046f) --- doc/classes/CollisionPolygon2D.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index f7dd2498564..3735526fe14 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -25,6 +25,7 @@ The polygon's list of vertices. Each point will be connected to the next, and the final point will be connected to the first. + [b]Note:[/b] The returned vertices are in the local coordinate space of the given [CollisionPolygon2D]. [b]Warning:[/b] The returned value is a clone of the [PackedVector2Array], not a reference. From 1ec0e4fba106a926c6f0e37684214088de0ba41b Mon Sep 17 00:00:00 2001 From: Micky Date: Sat, 30 Dec 2023 14:42:02 +0100 Subject: [PATCH 32/35] Fixing some reports to String's documentation Closes https://github.com/godotengine/godot-docs/issues/8043 Closes https://github.com/godotengine/godot-docs/issues/8044 Mitigates https://github.com/godotengine/godot-docs/issues/8190 Closes https://github.com/godotengine/godot/issues/86734 (cherry picked from commit 46b0f3e9d6d32ef36662ae749f1cb57f882290da) --- doc/classes/String.xml | 20 +++++++++++++++++--- doc/classes/StringName.xml | 21 ++++++++++++++++++--- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/doc/classes/String.xml b/doc/classes/String.xml index d2493c237b7..702d7298650 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -96,13 +96,14 @@ [gdscript] "move_local_x".capitalize() # Returns "Move Local X" "sceneFile_path".capitalize() # Returns "Scene File Path" + "2D, FPS, PNG".capitalize() # Returns "2d, Fps, Png" [/gdscript] [csharp] "move_local_x".Capitalize(); // Returns "Move Local X" "sceneFile_path".Capitalize(); // Returns "Scene File Path" + "2D, FPS, PNG".Capitalize(); // Returns "2d, Fps, Png" [/csharp] [/codeblocks] - [b]Note:[/b] This method not the same as the default appearance of properties in the Inspector dock, as it does not capitalize acronyms ([code]"2D"[/code], [code]"FPS"[/code], [code]"PNG"[/code], etc.) as you may expect. @@ -943,7 +944,7 @@ - Returns the string converted to lowercase. + Returns the string converted to [code]lowercase[/code]. @@ -956,12 +957,25 @@ Returns the string converted to [code]snake_case[/code]. + [b]Note:[/b] Numbers followed by a [i]single[/i] letter are not separated in the conversion to keep some words (such as "2D") together. + [codeblocks] + [gdscript] + "Node2D".to_snake_case() # Returns "node_2d" + "2nd place".to_snake_case() # Returns "2_nd_place" + "Texture3DAssetFolder".to_snake_case() # Returns "texture_3d_asset_folder" + [/gdscript] + [csharp] + "Node2D".ToSnakeCase(); // Returns "node_2d" + "2nd place".ToSnakeCase(); // Returns "2_nd_place" + "Texture3DAssetFolder".ToSnakeCase(); // Returns "texture_3d_asset_folder" + [/csharp] + [/codeblocks] - Returns the string converted to uppercase. + Returns the string converted to [code]UPPERCASE[/code]. diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index c78039dd349..46f78105b8c 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -8,6 +8,7 @@ You will usually just pass a [String] to methods expecting a [StringName] and it will be automatically converted, but you may occasionally want to construct a [StringName] ahead of time with the [StringName] constructor or, in GDScript, the literal syntax [code]&"example"[/code]. See also [NodePath], which is a similar concept specifically designed to store pre-parsed scene tree paths. All of [String]'s methods are available in this class too. They convert the [StringName] into a string, and they also return a string. This is highly inefficient and should only be used if the string is desired. + [b]Note:[/b] In C#, an explicit conversion to [code]System.String[/code] is required to use the methods listed on this page. Use the [code]ToString()[/code] method to cast a [StringName] to a string, and then use the equivalent methods in [code]System.String[/code] or [code]StringExtensions[/code]. [b]Note:[/b] In a boolean context, a [StringName] will evaluate to [code]false[/code] if it is empty ([code]StringName("")[/code]). Otherwise, a [StringName] will always evaluate to [code]true[/code]. The [code]not[/code] operator cannot be used. Instead, [method is_empty] should be used to check for empty [StringName]s. @@ -90,13 +91,14 @@ [gdscript] "move_local_x".capitalize() # Returns "Move Local X" "sceneFile_path".capitalize() # Returns "Scene File Path" + "2D, FPS, PNG".capitalize() # Returns "2d, Fps, Png" [/gdscript] [csharp] "move_local_x".Capitalize(); // Returns "Move Local X" "sceneFile_path".Capitalize(); // Returns "Scene File Path" + "2D, FPS, PNG".Capitalize(); // Returns "2d, Fps, Png" [/csharp] [/codeblocks] - [b]Note:[/b] This method not the same as the default appearance of properties in the Inspector dock, as it does not capitalize acronyms ([code]"2D"[/code], [code]"FPS"[/code], [code]"PNG"[/code], etc.) as you may expect. @@ -850,7 +852,7 @@ - Returns the string converted to lowercase. + Returns the string converted to [code]lowercase[/code]. @@ -863,12 +865,25 @@ Returns the string converted to [code]snake_case[/code]. + [b]Note:[/b] Numbers followed by a [i]single[/i] letter are not separated in the conversion to keep some words (such as "2D") together. + [codeblocks] + [gdscript] + "Node2D".to_snake_case() # Returns "node_2d" + "2nd place".to_snake_case() # Returns "2_nd_place" + "Texture3DAssetFolder".to_snake_case() # Returns "texture_3d_asset_folder" + [/gdscript] + [csharp] + "Node2D".ToSnakeCase(); // Returns "node_2d" + "2nd place".ToSnakeCase(); // Returns "2_nd_place" + "Texture3DAssetFolder".ToSnakeCase(); // Returns "texture_3d_asset_folder" + [/csharp] + [/codeblocks] - Returns the string converted to uppercase. + Returns the string converted to [code]UPPERCASE[/code]. From e2c96dc711dc17712a23cc5cf524fa36d553935f Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 14 Nov 2023 14:58:28 +0100 Subject: [PATCH 33/35] Document changing the window's resizable status at runtime (cherry picked from commit d6768a17fad24e71667e49c2c4a6bc239e6d622d) --- doc/classes/ProjectSettings.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 5544baa1dc9..8d7671af24d 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -774,7 +774,9 @@ Main window can't be focused. No-focus window will ignore all input, except mouse clicks. - Allows the window to be resizable by default. + If [code]true[/code], allows the window to be resizable by default. + [b]Note:[/b] This property is only read when the project starts. To change whether the window is resizable at runtime, set [member Window.unresizable] instead on the root Window, which can be retrieved using [code]get_viewport().get_window()[/code]. [member Window.unresizable] takes the opposite value of this setting. + [b]Note:[/b] Certain window managers can be configured to ignore the non-resizable status of a window. Do not rely on this setting as a guarantee that the window will [i]never[/i] be resizable. [b]Note:[/b] This setting is ignored on iOS. From 211dd2fb53230308420da031839796802103113d Mon Sep 17 00:00:00 2001 From: ShirenY Date: Sat, 4 Nov 2023 22:09:33 +0800 Subject: [PATCH 34/35] Transform mesh's AABB to skeleton's space when calculate mesh's bounds. (cherry picked from commit 27f71c4e78db2f502d730f5e34a540665c45af27) --- doc/classes/RenderingServer.xml | 8 ++++ drivers/gles3/storage/mesh_storage.cpp | 37 +++++++++++++------ drivers/gles3/storage/mesh_storage.h | 4 ++ scene/2d/polygon_2d.cpp | 30 ++++++++++++++- servers/rendering/renderer_canvas_cull.cpp | 6 +++ servers/rendering/renderer_canvas_cull.h | 2 + .../renderer_rd/storage_rd/mesh_storage.cpp | 37 +++++++++++++------ .../renderer_rd/storage_rd/mesh_storage.h | 4 ++ servers/rendering/rendering_server_default.h | 2 + servers/rendering_server.cpp | 10 +++++ servers/rendering_server.h | 7 ++++ 11 files changed, 122 insertions(+), 25 deletions(-) diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index f2224abc8e9..5c801ba7abf 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -918,6 +918,14 @@ [b]Note:[/b] When using the OpenGL backend or when running in headless mode, this function always returns [code]null[/code]. + + + + + Returns the bounding rectangle for a canvas item in local space, as calculated by the renderer. This bound is used internally for culling. + [b]Warning:[/b] This function is intended for debugging in the editor, and will pass through and return a zero [Rect2] in exported projects. + + diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index a96a491517f..e8a1bf55579 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -248,6 +248,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) s->aabb = p_surface.aabb; s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. + s->mesh_to_skeleton_xform = p_surface.mesh_to_skeleton_xform; if (p_surface.skin_data.size() || mesh->blend_shape_count > 0) { // Size must match the size of the vertex array. @@ -471,6 +472,7 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { } sd.bone_aabbs = s.bone_aabbs; + sd.mesh_to_skeleton_xform = s.mesh_to_skeleton_xform; if (mesh->blend_shape_count) { sd.blend_shape_data = Vector(); @@ -522,15 +524,16 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { for (uint32_t i = 0; i < mesh->surface_count; i++) { AABB laabb; - if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) { - int bs = mesh->surfaces[i]->bone_aabbs.size(); - const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr(); + const Mesh::Surface &surface = *mesh->surfaces[i]; + if ((surface.format & RS::ARRAY_FORMAT_BONES) && surface.bone_aabbs.size()) { + int bs = surface.bone_aabbs.size(); + const AABB *skbones = surface.bone_aabbs.ptr(); int sbs = skeleton->size; ERR_CONTINUE(bs > sbs); const float *baseptr = skeleton->data.ptr(); - bool first = true; + bool found_bone_aabb = false; if (skeleton->use_2d) { for (int j = 0; j < bs; j++) { @@ -550,11 +553,13 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[1][1] = dataptr[5]; mtx.origin.y = dataptr[7]; - AABB baabb = mtx.xform(skbones[j]); + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); - if (first) { + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } @@ -582,21 +587,29 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[2][2] = dataptr[10]; mtx.origin.z = dataptr[11]; - AABB baabb = mtx.xform(skbones[j]); - if (first) { + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); + + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } } } + if (found_bone_aabb) { + // Transform skeleton bounds back to mesh's space if any animated AABB applied. + laabb = surface.mesh_to_skeleton_xform.affine_inverse().xform(laabb); + } + if (laabb.size == Vector3()) { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } } else { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } if (i == 0) { diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index f9122771f9d..a0d7fe88863 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -103,6 +103,10 @@ struct Mesh { Vector bone_aabbs; + // Transform used in runtime bone AABBs compute. + // As bone AABBs are saved in Mesh space, but bones animation is in Skeleton space. + Transform3D mesh_to_skeleton_xform; + struct BlendShape { GLuint vertex_buffer = 0; GLuint vertex_array = 0; diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index ebd83da3770..54e1b1142ef 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -101,7 +101,12 @@ void Polygon2D::_skeleton_bone_setup_changed() { } void Polygon2D::_notification(int p_what) { + if (p_what == NOTIFICATION_TRANSFORM_CHANGED && !Engine::get_singleton()->is_editor_hint()) { + return; // Mesh recreation for NOTIFICATION_TRANSFORM_CHANGED is only needed in editor. + } + switch (p_what) { + case NOTIFICATION_TRANSFORM_CHANGED: case NOTIFICATION_DRAW: { if (polygon.size() < 3) { return; @@ -364,7 +369,30 @@ void Polygon2D::_notification(int p_what) { arr[RS::ARRAY_INDEX] = index_array; - RS::get_singleton()->mesh_add_surface_from_arrays(mesh, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + RS::SurfaceData sd; + + if (skeleton_node) { + // Compute transform between mesh and skeleton for runtime AABB compute. + const Transform2D mesh_transform = get_global_transform(); + const Transform2D skeleton_transform = skeleton_node->get_global_transform(); + const Transform2D mesh_to_sk2d = mesh_transform * skeleton_transform.affine_inverse(); + + // Convert 2d transform to 3d. + sd.mesh_to_skeleton_xform.basis.rows[0][0] = mesh_to_sk2d.columns[0][0]; + sd.mesh_to_skeleton_xform.basis.rows[0][1] = mesh_to_sk2d.columns[0][1]; + sd.mesh_to_skeleton_xform.origin.x = mesh_to_sk2d.get_origin().x; + + sd.mesh_to_skeleton_xform.basis.rows[1][0] = mesh_to_sk2d.columns[1][0]; + sd.mesh_to_skeleton_xform.basis.rows[1][1] = mesh_to_sk2d.columns[1][1]; + sd.mesh_to_skeleton_xform.origin.y = mesh_to_sk2d.get_origin().y; + } + + Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&sd, RS::PRIMITIVE_TRIANGLES, arr, Array(), Dictionary(), RS::ARRAY_FLAG_USE_2D_VERTICES); + if (err != OK) { + return; + } + + RS::get_singleton()->mesh_add_surface(mesh, sd); RS::get_singleton()->canvas_item_add_mesh(get_canvas_item(), mesh, Transform2D(), Color(1, 1, 1), texture.is_valid() ? texture->get_rid() : RID()); } diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 2cb7f32cc30..de4600395ba 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -2030,6 +2030,12 @@ void RendererCanvasCull::update_visibility_notifiers() { } } +Rect2 RendererCanvasCull::_debug_canvas_item_get_rect(RID p_item) { + Item *canvas_item = canvas_item_owner.get_or_null(p_item); + ERR_FAIL_NULL_V(canvas_item, Rect2()); + return canvas_item->get_rect(); +} + bool RendererCanvasCull::free(RID p_rid) { if (canvas_owner.owns(p_rid)) { Canvas *canvas = canvas_owner.get_or_null(p_rid); diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 4f11d2c7b12..fc165628238 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -319,6 +319,8 @@ public: void update_visibility_notifiers(); + Rect2 _debug_canvas_item_get_rect(RID p_item); + bool free(RID p_rid); RendererCanvasCull(); ~RendererCanvasCull(); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 6888af7af91..2401c1105f8 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -389,6 +389,7 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) s->aabb = p_surface.aabb; s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them. + s->mesh_to_skeleton_xform = p_surface.mesh_to_skeleton_xform; if (mesh->blend_shape_count > 0) { s->blend_shape_buffer = RD::get_singleton()->storage_buffer_create(p_surface.blend_shape_data.size(), p_surface.blend_shape_data); @@ -569,6 +570,7 @@ RS::SurfaceData MeshStorage::mesh_get_surface(RID p_mesh, int p_surface) const { } sd.bone_aabbs = s.bone_aabbs; + sd.mesh_to_skeleton_xform = s.mesh_to_skeleton_xform; if (s.blend_shape_buffer.is_valid()) { sd.blend_shape_data = RD::get_singleton()->buffer_get_data(s.blend_shape_buffer); @@ -615,15 +617,16 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { for (uint32_t i = 0; i < mesh->surface_count; i++) { AABB laabb; - if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) { - int bs = mesh->surfaces[i]->bone_aabbs.size(); - const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr(); + const Mesh::Surface &surface = *mesh->surfaces[i]; + if ((surface.format & RS::ARRAY_FORMAT_BONES) && surface.bone_aabbs.size()) { + int bs = surface.bone_aabbs.size(); + const AABB *skbones = surface.bone_aabbs.ptr(); int sbs = skeleton->size; ERR_CONTINUE(bs > sbs); const float *baseptr = skeleton->data.ptr(); - bool first = true; + bool found_bone_aabb = false; if (skeleton->use_2d) { for (int j = 0; j < bs; j++) { @@ -643,11 +646,13 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[1][1] = dataptr[5]; mtx.origin.y = dataptr[7]; - AABB baabb = mtx.xform(skbones[j]); + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); - if (first) { + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } @@ -675,21 +680,29 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { mtx.basis.rows[2][2] = dataptr[10]; mtx.origin.z = dataptr[11]; - AABB baabb = mtx.xform(skbones[j]); - if (first) { + // Transform bounds to skeleton's space before applying animation data. + AABB baabb = surface.mesh_to_skeleton_xform.xform(skbones[j]); + baabb = mtx.xform(baabb); + + if (!found_bone_aabb) { laabb = baabb; - first = false; + found_bone_aabb = true; } else { laabb.merge_with(baabb); } } } + if (found_bone_aabb) { + // Transform skeleton bounds back to mesh's space if any animated AABB applied. + laabb = surface.mesh_to_skeleton_xform.affine_inverse().xform(laabb); + } + if (laabb.size == Vector3()) { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } } else { - laabb = mesh->surfaces[i]->aabb; + laabb = surface.aabb; } if (i == 0) { diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index c23a5b1449c..4e064897643 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -116,6 +116,10 @@ private: Vector bone_aabbs; + // Transform used in runtime bone AABBs compute. + // As bone AABBs are saved in Mesh space, but bones animation is in Skeleton space. + Transform3D mesh_to_skeleton_xform; + RID blend_shape_buffer; RID material; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index 340eb7394b2..e6549f3b765 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -925,6 +925,8 @@ public: FUNC1(canvas_set_shadow_texture_size, int) + FUNC1R(Rect2, _debug_canvas_item_get_rect, RID) + /* GLOBAL SHADER UNIFORMS */ #undef server_name diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 266e3292adb..51687e2e2e3 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1410,6 +1410,14 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su } #endif +Rect2 RenderingServer::debug_canvas_item_get_rect(RID p_item) { +#ifdef TOOLS_ENABLED + return _debug_canvas_item_get_rect(p_item); +#else + return Rect2(); +#endif +} + int RenderingServer::global_shader_uniform_type_get_shader_datatype(GlobalShaderParameterType p_type) { switch (p_type) { case RS::GLOBAL_VAR_TYPE_BOOL: @@ -2636,6 +2644,8 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_set_visibility_notifier", "item", "enable", "area", "enter_callable", "exit_callable"), &RenderingServer::canvas_item_set_visibility_notifier); ClassDB::bind_method(D_METHOD("canvas_item_set_canvas_group_mode", "item", "mode", "clear_margin", "fit_empty", "fit_margin", "blur_mipmaps"), &RenderingServer::canvas_item_set_canvas_group_mode, DEFVAL(5.0), DEFVAL(false), DEFVAL(0.0), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("debug_canvas_item_get_rect", "item"), &RenderingServer::debug_canvas_item_get_rect); + BIND_ENUM_CONSTANT(NINE_PATCH_STRETCH); BIND_ENUM_CONSTANT(NINE_PATCH_TILE); BIND_ENUM_CONSTANT(NINE_PATCH_TILE_FIT); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index deac2a59f92..d391ffe99bc 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -312,6 +312,10 @@ public: Vector lods; Vector bone_aabbs; + // Transforms used in runtime bone AABBs compute. + // Since bone AABBs is saved in Mesh space, but bones is in Skeleton space. + Transform3D mesh_to_skeleton_xform; + Vector blend_shape_data; RID material; @@ -1461,6 +1465,9 @@ public: virtual void canvas_set_shadow_texture_size(int p_size) = 0; + Rect2 debug_canvas_item_get_rect(RID p_item); + virtual Rect2 _debug_canvas_item_get_rect(RID p_item) = 0; + /* GLOBAL SHADER UNIFORMS */ enum GlobalShaderParameterType { From 5b05029b3594d700326b589066762fc7823088b7 Mon Sep 17 00:00:00 2001 From: kleonc <9283098+kleonc@users.noreply.github.com> Date: Wed, 27 Dec 2023 18:46:53 +0100 Subject: [PATCH 35/35] Fix Polygon2D to Skeleton2D transform calculation (cherry picked from commit 41e4f3c215c45bcfaf9b4330f8bce50e911d6be8) --- scene/2d/polygon_2d.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 54e1b1142ef..11f45627bcd 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -375,14 +375,14 @@ void Polygon2D::_notification(int p_what) { // Compute transform between mesh and skeleton for runtime AABB compute. const Transform2D mesh_transform = get_global_transform(); const Transform2D skeleton_transform = skeleton_node->get_global_transform(); - const Transform2D mesh_to_sk2d = mesh_transform * skeleton_transform.affine_inverse(); + const Transform2D mesh_to_sk2d = skeleton_transform.affine_inverse() * mesh_transform; // Convert 2d transform to 3d. sd.mesh_to_skeleton_xform.basis.rows[0][0] = mesh_to_sk2d.columns[0][0]; - sd.mesh_to_skeleton_xform.basis.rows[0][1] = mesh_to_sk2d.columns[0][1]; + sd.mesh_to_skeleton_xform.basis.rows[1][0] = mesh_to_sk2d.columns[0][1]; sd.mesh_to_skeleton_xform.origin.x = mesh_to_sk2d.get_origin().x; - sd.mesh_to_skeleton_xform.basis.rows[1][0] = mesh_to_sk2d.columns[1][0]; + sd.mesh_to_skeleton_xform.basis.rows[0][1] = mesh_to_sk2d.columns[1][0]; sd.mesh_to_skeleton_xform.basis.rows[1][1] = mesh_to_sk2d.columns[1][1]; sd.mesh_to_skeleton_xform.origin.y = mesh_to_sk2d.get_origin().y; }