From 22f93bccb463cebbcf6e2fd47ca9f0a3902a79d7 Mon Sep 17 00:00:00 2001 From: Ibrahn Sahir Date: Wed, 27 Oct 2021 15:14:19 +0100 Subject: [PATCH 01/11] Fix MIDI input with ALSA. Reworked the handling of ALSA RawMidi input to support: - Running Status. - RealTime Category messages arriving during other messages data. - Multiple connected RawMidi interfaces. (cherry picked from commit 81575174cbd99b4d1cedbe763d1df7cbc7e641c6) --- drivers/alsamidi/midi_driver_alsamidi.cpp | 182 ++++++++++++++-------- drivers/alsamidi/midi_driver_alsamidi.h | 38 ++++- 2 files changed, 153 insertions(+), 67 deletions(-) diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp index 73f6a2eaa72..fa192e01d1f 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.cpp +++ b/drivers/alsamidi/midi_driver_alsamidi.cpp @@ -37,85 +37,135 @@ #include -static int get_message_size(uint8_t message) { - switch (message & 0xF0) { - case 0x80: // note off - case 0x90: // note on - case 0xA0: // aftertouch - case 0xB0: // continuous controller - case 0xE0: // pitch bend - case 0xF2: // song position pointer - return 3; +MIDIDriverALSAMidi::MessageCategory MIDIDriverALSAMidi::msg_category(uint8_t msg_part) { + if (msg_part >= 0xf8) { + return MessageCategory::RealTime; + } else if (msg_part >= 0xf0) { + // System Exclusive begin/end are specified as System Common Category messages, + // but we separate them here and give them their own categories as their + // behaviour is significantly different. + if (msg_part == 0xf0) { + return MessageCategory::SysExBegin; + } else if (msg_part == 0xf7) { + return MessageCategory::SysExEnd; + } + return MessageCategory::SystemCommon; + } else if (msg_part >= 0x80) { + return MessageCategory::Voice; + } + return MessageCategory::Data; +} - case 0xC0: // patch change - case 0xD0: // channel pressure - case 0xF1: // time code quarter frame - case 0xF3: // song select +size_t MIDIDriverALSAMidi::msg_expected_data(uint8_t status_byte) { + if (msg_category(status_byte) == MessageCategory::Voice) { + // Voice messages have a channel number in the status byte, mask it out. + status_byte &= 0xf0; + } + + switch (status_byte) { + case 0x80: // Note Off + case 0x90: // Note On + case 0xA0: // Polyphonic Key Pressure (Aftertouch) + case 0xB0: // Control Change (CC) + case 0xE0: // Pitch Bend Change + case 0xF2: // Song Position Pointer return 2; - case 0xF0: // SysEx start - case 0xF4: // reserved - case 0xF5: // reserved - case 0xF6: // tune request - case 0xF7: // SysEx end - case 0xF8: // timing clock - case 0xF9: // reserved - case 0xFA: // start - case 0xFB: // continue - case 0xFC: // stop - case 0xFD: // reserved - case 0xFE: // active sensing - case 0xFF: // reset + case 0xC0: // Program Change + case 0xD0: // Channel Pressure (Aftertouch) + case 0xF1: // MIDI Time Code Quarter Frame + case 0xF3: // Song Select return 1; } - return 256; + return 0; +} + +void MIDIDriverALSAMidi::InputConnection::parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver, + uint64_t timestamp) { + switch (msg_category(byte)) { + case MessageCategory::RealTime: + // Real-Time messages are single byte messages that can + // occur at any point. + // We pass them straight through. + driver.receive_input_packet(timestamp, &byte, 1); + break; + + case MessageCategory::Data: + // We don't currently forward System Exclusive messages so skip their data. + // Collect any expected data for other message types. + if (!skipping_sys_ex && expected_data > received_data) { + buffer[received_data + 1] = byte; + received_data++; + + // Forward a complete message and reset relevant state. + if (received_data == expected_data) { + driver.receive_input_packet(timestamp, buffer, received_data + 1); + received_data = 0; + + if (msg_category(buffer[0]) != MessageCategory::Voice) { + // Voice Category messages can be sent with "running status". + // This means they don't resend the status byte until it changes. + // For other categories, we reset expected data, to require a new status byte. + expected_data = 0; + } + } + } + break; + + case MessageCategory::SysExBegin: + buffer[0] = byte; + skipping_sys_ex = true; + break; + + case MessageCategory::SysExEnd: + expected_data = 0; + skipping_sys_ex = false; + break; + + case MessageCategory::Voice: + case MessageCategory::SystemCommon: + buffer[0] = byte; + received_data = 0; + expected_data = msg_expected_data(byte); + skipping_sys_ex = false; + if (expected_data == 0) { + driver.receive_input_packet(timestamp, &byte, 1); + } + break; + } +} + +int MIDIDriverALSAMidi::InputConnection::read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp) { + int ret; + do { + uint8_t byte = 0; + ret = snd_rawmidi_read(rawmidi_ptr, &byte, 1); + + if (ret < 0) { + if (ret != -EAGAIN) { + ERR_PRINT("snd_rawmidi_read error: " + String(snd_strerror(ret))); + } + } else { + parse_byte(byte, driver, timestamp); + } + } while (ret > 0); + + return ret; } void MIDIDriverALSAMidi::thread_func(void *p_udata) { MIDIDriverALSAMidi *md = (MIDIDriverALSAMidi *)p_udata; uint64_t timestamp = 0; - uint8_t buffer[256]; - int expected_size = 255; - int bytes = 0; while (!md->exit_thread.is_set()) { - int ret; - md->lock(); - for (int i = 0; i < md->connected_inputs.size(); i++) { - snd_rawmidi_t *midi_in = md->connected_inputs[i]; - do { - uint8_t byte = 0; - ret = snd_rawmidi_read(midi_in, &byte, 1); - if (ret < 0) { - if (ret != -EAGAIN) { - ERR_PRINT("snd_rawmidi_read error: " + String(snd_strerror(ret))); - } - } else { - if (byte & 0x80) { - // Flush previous packet if there is any - if (bytes) { - md->receive_input_packet(timestamp, buffer, bytes); - bytes = 0; - } - expected_size = get_message_size(byte); - // After a SysEx start, all bytes are data until a SysEx end, so - // we're going to end the command at the SES, and let the common - // driver ignore the following data bytes. - } + InputConnection *connections = md->connected_inputs.ptrw(); + size_t connection_count = md->connected_inputs.size(); - if (bytes < 256) { - buffer[bytes++] = byte; - // If we know the size of the current packet receive it if it reached the expected size - if (bytes >= expected_size) { - md->receive_input_packet(timestamp, buffer, bytes); - bytes = 0; - } - } - } - } while (ret > 0); + for (size_t i = 0; i < connection_count; i++) { + connections[i].read_in(*md, timestamp); } md->unlock(); @@ -139,7 +189,7 @@ Error MIDIDriverALSAMidi::open() { snd_rawmidi_t *midi_in; int ret = snd_rawmidi_open(&midi_in, nullptr, name, SND_RAWMIDI_NONBLOCK); if (ret >= 0) { - connected_inputs.insert(i++, midi_in); + connected_inputs.insert(i++, InputConnection(midi_in)); } } @@ -160,7 +210,7 @@ void MIDIDriverALSAMidi::close() { thread.wait_to_finish(); for (int i = 0; i < connected_inputs.size(); i++) { - snd_rawmidi_t *midi_in = connected_inputs[i]; + snd_rawmidi_t *midi_in = connected_inputs[i].rawmidi_ptr; snd_rawmidi_close(midi_in); } connected_inputs.clear(); @@ -179,7 +229,7 @@ PoolStringArray MIDIDriverALSAMidi::get_connected_inputs() { lock(); for (int i = 0; i < connected_inputs.size(); i++) { - snd_rawmidi_t *midi_in = connected_inputs[i]; + snd_rawmidi_t *midi_in = connected_inputs[i].rawmidi_ptr; snd_rawmidi_info_t *info; snd_rawmidi_info_malloc(&info); diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h index 96554f462d8..0891ce48043 100644 --- a/drivers/alsamidi/midi_driver_alsamidi.h +++ b/drivers/alsamidi/midi_driver_alsamidi.h @@ -46,12 +46,48 @@ class MIDIDriverALSAMidi : public MIDIDriver { Thread thread; Mutex mutex; - Vector connected_inputs; + class InputConnection { + public: + InputConnection() = default; + InputConnection(snd_rawmidi_t *midi_in) : + rawmidi_ptr{ midi_in } {} + + // Read in and parse available data, forwarding any complete messages through the driver. + int read_in(MIDIDriverALSAMidi &driver, uint64_t timestamp); + + snd_rawmidi_t *rawmidi_ptr = nullptr; + + private: + static const size_t MSG_BUFFER_SIZE = 3; + uint8_t buffer[MSG_BUFFER_SIZE] = { 0 }; + size_t expected_data = 0; + size_t received_data = 0; + bool skipping_sys_ex = false; + void parse_byte(uint8_t byte, MIDIDriverALSAMidi &driver, uint64_t timestamp); + }; + + Vector connected_inputs; SafeFlag exit_thread; static void thread_func(void *p_udata); + enum class MessageCategory { + Data, + Voice, + SysExBegin, + SystemCommon, // excluding System Exclusive Begin/End + SysExEnd, + RealTime, + }; + + // If the passed byte is a status byte, return the associated message category, + // else return MessageCategory::Data. + static MessageCategory msg_category(uint8_t msg_part); + + // Return the number of data bytes expected for the provided status byte. + static size_t msg_expected_data(uint8_t status_byte); + void lock() const; void unlock() const; From 3f8bb6fb531a7fa841a701f19f6f207512137b1e Mon Sep 17 00:00:00 2001 From: kobewi Date: Sat, 1 Jan 2022 13:51:42 +0100 Subject: [PATCH 02/11] Improvements to EditorResourcePicker (cherry picked from commit 9568789a9d7845a7224cadea996d009463e87125) --- editor/editor_resource_picker.cpp | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index e766c0a3a57..caf94e68c86 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -51,6 +51,7 @@ void EditorResourcePicker::_update_resource() { if (edited_resource == RES()) { assign_button->set_icon(Ref()); assign_button->set_text(TTR("[empty]")); + assign_button->set_tooltip(""); } else { assign_button->set_icon(EditorNode::get_singleton()->get_object_icon(edited_resource.operator->(), "Object")); @@ -58,14 +59,15 @@ void EditorResourcePicker::_update_resource() { assign_button->set_text(edited_resource->get_name()); } else if (edited_resource->get_path().is_resource_file()) { assign_button->set_text(edited_resource->get_path().get_file()); - assign_button->set_tooltip(edited_resource->get_path()); } else { assign_button->set_text(edited_resource->get_class()); } + String resource_path; if (edited_resource->get_path().is_resource_file()) { - assign_button->set_tooltip(edited_resource->get_path()); + resource_path = edited_resource->get_path() + "\n"; } + assign_button->set_tooltip(resource_path + TTR("Type:") + " " + edited_resource->get_class()); // Preview will override the above, so called at the end. EditorResourcePreview::get_singleton()->queue_edited_resource_preview(edited_resource, this, "_update_resource_preview", edited_resource->get_instance_id()); @@ -520,6 +522,8 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set * p_vector->insert("Texture"); } else if (base == "ShaderMaterial") { p_vector->insert("Shader"); + } else if (base == "Texture") { + p_vector->insert("Image"); } } } @@ -638,18 +642,35 @@ void EditorResourcePicker::drop_data_fw(const Point2 &p_point, const Variant &p_ String at = E->get().strip_edges(); if (at == "SpatialMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Texture")) { - Ref mat = memnew(SpatialMaterial); + // Use existing resource if possible and only replace its data. + Ref mat = edited_resource; + if (mat.is_null()) { + mat.instance(); + } mat->set_texture(SpatialMaterial::TextureParam::TEXTURE_ALBEDO, dropped_resource); dropped_resource = mat; break; } if (at == "ShaderMaterial" && ClassDB::is_parent_class(dropped_resource->get_class(), "Shader")) { - Ref mat = memnew(ShaderMaterial); + Ref mat = edited_resource; + if (mat.is_null()) { + mat.instance(); + } mat->set_shader(dropped_resource); dropped_resource = mat; break; } + + if (at == "Texture" && ClassDB::is_parent_class(dropped_resource->get_class(), "Image")) { + Ref texture = edited_resource; + if (texture.is_null()) { + texture.instance(); + } + texture->create_from_image(dropped_resource); + dropped_resource = texture; + break; + } } } From df1a0b25ea3c39cb6ae171d13fee9632887bdb87 Mon Sep 17 00:00:00 2001 From: Hakim Date: Tue, 9 Aug 2022 19:39:58 +0200 Subject: [PATCH 03/11] Prevent AnimationPlayer from being added on GLTF import if the option is unchecked. Fixes #63954 (cherry picked from commit 805ffdfbf6841ac19c6fdbf3425a6ff15115bed7) --- modules/gltf/doc_classes/GLTFState.xml | 2 ++ modules/gltf/gltf_state.cpp | 11 +++++++++++ modules/gltf/gltf_state.h | 4 ++++ modules/gltf/packed_scene_gltf.cpp | 3 ++- 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/modules/gltf/doc_classes/GLTFState.xml b/modules/gltf/doc_classes/GLTFState.xml index 2436a73d0d7..5eb7be2e5b8 100644 --- a/modules/gltf/doc_classes/GLTFState.xml +++ b/modules/gltf/doc_classes/GLTFState.xml @@ -208,6 +208,8 @@ + + diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index ed5de983cd8..bf4453fadf0 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -81,6 +81,8 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("set_skeletons", "skeletons"), &GLTFState::set_skeletons); ClassDB::bind_method(D_METHOD("get_skeleton_to_node"), &GLTFState::get_skeleton_to_node); ClassDB::bind_method(D_METHOD("set_skeleton_to_node", "skeleton_to_node"), &GLTFState::set_skeleton_to_node); + ClassDB::bind_method(D_METHOD("get_create_animations"), &GLTFState::get_create_animations); + ClassDB::bind_method(D_METHOD("set_create_animations", "create_animations"), &GLTFState::set_create_animations); ClassDB::bind_method(D_METHOD("get_animations"), &GLTFState::get_animations); ClassDB::bind_method(D_METHOD("set_animations", "animations"), &GLTFState::set_animations); ClassDB::bind_method(D_METHOD("get_scene_node", "idx"), &GLTFState::get_scene_node); @@ -108,6 +110,7 @@ void GLTFState::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "unique_animation_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_unique_animation_names", "get_unique_animation_names"); // Set ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "skeletons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeletons", "get_skeletons"); // Vector> ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "skeleton_to_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeleton_to_node", "get_skeleton_to_node"); // Map> } @@ -295,6 +298,14 @@ void GLTFState::set_skeleton_to_node(Dictionary p_skeleton_to_node) { GLTFTemplateConvert::set_from_dict(skeleton_to_node, p_skeleton_to_node); } +bool GLTFState::get_create_animations() { + return create_animations; +} + +void GLTFState::set_create_animations(bool p_create_animations) { + create_animations = p_create_animations; +} + Array GLTFState::get_animations() { return GLTFTemplateConvert::to_array(animations); } diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 3087a77751e..cd1ba2bf428 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -59,6 +59,7 @@ class GLTFState : public Resource { bool use_khr_texture_transform = false; bool use_legacy_names = false; uint32_t compress_flags = 0; + bool create_animations = true; Vector> nodes; Vector> buffers; @@ -166,6 +167,9 @@ public: Dictionary get_skeleton_to_node(); void set_skeleton_to_node(Dictionary p_skeleton_to_node); + bool get_create_animations(); + void set_create_animations(bool p_create_animations); + Array get_animations(); void set_animations(Array p_animations); diff --git a/modules/gltf/packed_scene_gltf.cpp b/modules/gltf/packed_scene_gltf.cpp index 409d938831e..a7f94b114ce 100644 --- a/modules/gltf/packed_scene_gltf.cpp +++ b/modules/gltf/packed_scene_gltf.cpp @@ -67,6 +67,7 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags, r_state->use_legacy_names = p_flags & EditorSceneImporter::IMPORT_USE_LEGACY_NAMES; r_state->compress_flags = p_compress_flags; + r_state->set_create_animations(p_flags & EditorSceneImporter::IMPORT_ANIMATION); Ref gltf_document; gltf_document.instance(); @@ -84,7 +85,7 @@ Node *PackedSceneGLTF::import_scene(const String &p_path, uint32_t p_flags, gltf_document->_generate_scene_node(r_state, root, root, r_state->root_nodes[root_i]); } gltf_document->_process_mesh_instances(r_state, root); - if (r_state->animations.size()) { + if (r_state->get_create_animations() && r_state->animations.size()) { AnimationPlayer *ap = memnew(AnimationPlayer); root->add_child(ap); ap->set_owner(root); From da3b8b324d0fdbf6d8fac97850274a757d72e0b7 Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Mon, 12 Sep 2022 21:04:46 +0200 Subject: [PATCH 04/11] Add 16-bits TGA support (cherry picked from commit 200f6ac0894982b31c59acc11cd5f8d4f8971219) --- modules/tga/image_loader_tga.cpp | 25 +++++++++++++++++++++++-- modules/tga/image_loader_tga.h | 2 ++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index a05664f475b..938d3ad6dda 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -100,7 +100,7 @@ Error ImageLoaderTGA::convert_to_image(Ref p_image, const uint8_t *p_buff uint32_t width = p_header.image_width; uint32_t height = p_header.image_height; tga_origin_e origin = static_cast((p_header.image_descriptor & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT); - + uint8_t alpha_bits = p_header.image_descriptor & TGA_IMAGE_DESCRIPTOR_ALPHA_MASK; uint32_t x_start; int32_t x_step; uint32_t x_end; @@ -184,6 +184,27 @@ Error ImageLoaderTGA::convert_to_image(Ref p_image, const uint8_t *p_buff y += y_step; } } + } else if (p_header.pixel_depth == 16) { + while (y != y_end) { + while (x != x_end) { + if (i + 1 >= p_input_size) { + return ERR_PARSE_ERROR; + } + + // Always stored as RGBA5551 + uint8_t r = (p_buffer[i + 1] & 0x7c) << 1; + uint8_t g = ((p_buffer[i + 1] & 0x03) << 6) | ((p_buffer[i + 0] & 0xe0) >> 2); + uint8_t b = (p_buffer[i + 0] & 0x1f) << 3; + uint8_t a = (p_buffer[i + 1] & 0x80) ? 0xff : 0; + + TGA_PUT_PIXEL(r, g, b, alpha_bits ? a : 0xff); + + x += x_step; + i += 2; + } + x = x_start; + y += y_step; + } } else if (p_header.pixel_depth == 24) { while (y != y_end) { while (x != x_end) { @@ -286,7 +307,7 @@ Error ImageLoaderTGA::load_image(Ref p_image, FileAccess *f, bool p_force err = FAILED; } - if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) { + if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 16 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) { err = FAILED; } diff --git a/modules/tga/image_loader_tga.h b/modules/tga/image_loader_tga.h index 05957c1b303..475ea228d1d 100644 --- a/modules/tga/image_loader_tga.h +++ b/modules/tga/image_loader_tga.h @@ -36,6 +36,8 @@ /** @author SaracenOne */ +#define TGA_IMAGE_DESCRIPTOR_ALPHA_MASK 0xf + class ImageLoaderTGA : public ImageFormatLoader { enum tga_type_e { TGA_TYPE_NO_DATA = 0, From 2ef00521130bd354a5cd052ee4d9e8f4c8ea5e49 Mon Sep 17 00:00:00 2001 From: lawnjelly Date: Thu, 22 Sep 2022 16:06:25 +0100 Subject: [PATCH 05/11] Fix array-bounds warning in BVH Provides a workaround to prevent tripping a compiler warning. (cherry picked from commit 91d252c69795cdfc53e71c553edcff665636ea16) --- core/math/bvh_structs.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/math/bvh_structs.inc b/core/math/bvh_structs.inc index b0d9ae36157..7b5cc2c3508 100644 --- a/core/math/bvh_structs.inc +++ b/core/math/bvh_structs.inc @@ -88,7 +88,11 @@ public: num_items++; return id; } +#ifdef DEV_ENABLED return -1; +#else + ERR_FAIL_V_MSG(0, "BVH request_item error."); +#endif } }; From b18ef4dc836e4f0f0d2778b2202aa9679773e0be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Fri, 23 Sep 2022 13:55:00 +0200 Subject: [PATCH 06/11] SCons: Remove redundant `-fomit-frame-pointer` and `-ftree-vectorize` - `-fomit-frame-pointer` is included automatically by both GCC and Clang in `-O1` and above. - `-ftree-vectorize` is included automatically by GCC in `-O2` and beyond, and seems always enabled by Clang. Closes #66296. See that issue for a detailed investigation. (cherry picked from commit c5c3d13dc0dbbf95a2350f57d69e7cdc546d395d) --- platform/android/detect.py | 3 +-- platform/iphone/detect.py | 4 ++-- platform/osx/detect.py | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/platform/android/detect.py b/platform/android/detect.py index 274181a7d18..cbf76257852 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -126,11 +126,10 @@ def configure(env): # `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces # when using `target=release_debug`. opt = "-O3" if env["target"] == "release" else "-O2" - env.Append(CCFLAGS=[opt, "-fomit-frame-pointer"]) + env.Append(CCFLAGS=[opt]) elif env["optimize"] == "size": # optimize for size env.Append(CCFLAGS=["-Oz"]) env.Append(CPPDEFINES=["NDEBUG"]) - env.Append(CCFLAGS=["-ftree-vectorize"]) elif env["target"] == "debug": env.Append(LINKFLAGS=["-O0"]) env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"]) diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index 4652f4772b8..2b81fe5cbde 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -54,10 +54,10 @@ def configure(env): # `-O2` is more friendly to debuggers than `-O3`, leading to better crash backtraces # when using `target=release_debug`. opt = "-O3" if env["target"] == "release" else "-O2" - env.Append(CCFLAGS=[opt, "-ftree-vectorize", "-fomit-frame-pointer"]) + env.Append(CCFLAGS=[opt]) env.Append(LINKFLAGS=[opt]) elif env["optimize"] == "size": # optimize for size - env.Append(CCFLAGS=["-Os", "-ftree-vectorize"]) + env.Append(CCFLAGS=["-Os"]) env.Append(LINKFLAGS=["-Os"]) elif env["target"] == "debug": diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 89662e23f93..5a3517ef369 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -43,9 +43,9 @@ def configure(env): if env["target"] == "release": if env["optimize"] == "speed": # optimize for speed (default) - env.Prepend(CCFLAGS=["-O3", "-fomit-frame-pointer", "-ftree-vectorize"]) + env.Prepend(CCFLAGS=["-O3"]) elif env["optimize"] == "size": # optimize for size - env.Prepend(CCFLAGS=["-Os", "-ftree-vectorize"]) + env.Prepend(CCFLAGS=["-Os"]) if env["arch"] != "arm64": env.Prepend(CCFLAGS=["-msse2"]) From aa8c63f8afb4c2d427b93d521da88bdd4a0d7eb9 Mon Sep 17 00:00:00 2001 From: Zak Grumbles Date: Fri, 23 Sep 2022 16:55:19 -0500 Subject: [PATCH 07/11] Add note regarding RefCounted to EditorScript docs (cherry picked from commit e5dc2ed98278575ca6d0cae68228995bbc386ada) --- doc/classes/EditorScript.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml index 5fa00a6f6cc..29ea87a358f 100644 --- a/doc/classes/EditorScript.xml +++ b/doc/classes/EditorScript.xml @@ -15,6 +15,7 @@ print("Hello from the Godot Editor!") [/codeblock] [b]Note:[/b] The script is run in the Editor context, which means the output is visible in the console window started with the Editor (stdout) instead of the usual Godot [b]Output[/b] dock. + [b]Note:[/b] EditorScript is reference counted, meaning it is destroyed when nothing references it. This can cause errors during asynchronous operations if there are no references to the script. From 9a0a9bbaec4141b68827297c1dc332a37993544d Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 7 Oct 2022 22:47:41 +0200 Subject: [PATCH 08/11] Document `Array.sort()` and `sort_custom()` using unstable sorting (cherry picked from commit 85b617a6a3a17f05b8e111220daec6eb769a81e8) --- doc/classes/Array.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml index 5e9f692dadb..63d7e39c83f 100644 --- a/doc/classes/Array.xml +++ b/doc/classes/Array.xml @@ -353,6 +353,7 @@ Sorts the array. + [b]Note:[/b] The sorting algorithm used is not [url=https://en.wikipedia.org/wiki/Sorting_algorithm#Stability]stable[/url]. This means that values considered equal may have their order changed when using [method sort]. [b]Note:[/b] Strings are sorted in alphabetical order (as opposed to natural order). This may lead to unexpected behavior when sorting an array of strings ending with a sequence of numbers. Consider the following example: [codeblock] var strings = ["string1", "string2", "string10", "string11"] @@ -367,7 +368,8 @@ Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code]. For two elements [code]a[/code] and [code]b[/code], if the given method returns [code]true[/code], element [code]b[/code] will be after element [code]a[/code] in the array. - [b]Note:[/b] You cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior. + [b]Note:[/b] The sorting algorithm used is not [url=https://en.wikipedia.org/wiki/Sorting_algorithm#Stability]stable[/url]. This means that values considered equal may have their order changed when using [method sort_custom]. + [b]Note:[/b] You cannot randomize the return value as the heapsort algorithm expects a deterministic result. Randomizing the return value will result in unexpected behavior. [codeblock] class MyCustomSorter: static func sort_ascending(a, b): From bf54ed91240643b884fba8ec5ddccc3c47f8a288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ignacio=20Rold=C3=A1n=20Etcheverry?= Date: Thu, 13 Oct 2022 18:58:27 +0200 Subject: [PATCH 09/11] Add JetBrains Fleet folder to gitignore (cherry picked from commit 166d86ca84460650b79da6672eb46f278c6214f8) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 539003ca6b9..f1e173c5b21 100644 --- a/.gitignore +++ b/.gitignore @@ -154,6 +154,7 @@ gmon.out # Jetbrains IDEs .idea/ +.fleet/ # Kate *.kate-swp From cbc8ccbe206cd43b74795de29e73b2e9f1676c52 Mon Sep 17 00:00:00 2001 From: alex-pahdo <109116583+alex-pahdo@users.noreply.github.com> Date: Mon, 24 Oct 2022 13:30:37 -0700 Subject: [PATCH 10/11] Add more info to WAV import errors Print mismatched header contents and file size, which can provide more clues to users when debugging. (cherry picked from commit f5d256b118914817e2c7ac5c35421e2767fc1e79) --- editor/import/resource_importer_wav.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 56826671cde..2e6d359f466 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -104,9 +104,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s file->get_buffer((uint8_t *)&riff, 4); //RIFF if (riff[0] != 'R' || riff[1] != 'I' || riff[2] != 'F' || riff[3] != 'F') { + uint64_t length = file->get_len(); file->close(); memdelete(file); - ERR_FAIL_V(ERR_FILE_UNRECOGNIZED); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Not a WAV file. File should start with 'RIFF', but found '%s', in file of size %d bytes", riff, length)); } /* GET FILESIZE */ @@ -114,14 +115,15 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s /* CHECK WAVE */ - char wave[4]; - - file->get_buffer((uint8_t *)&wave, 4); //RIFF + char wave[5]; + wave[4] = 0; + file->get_buffer((uint8_t *)&wave, 4); //WAVE if (wave[0] != 'W' || wave[1] != 'A' || wave[2] != 'V' || wave[3] != 'E') { + uint64_t length = file->get_len(); file->close(); memdelete(file); - ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Not a WAV file (no WAVE RIFF header)."); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Not a WAV file. Header should contain 'WAVE', but found '%s', in file of size %d bytes", wave, length)); } // Let users override potential loop points from the WAV. From 1a452686398887842cbc98d7a56fc0337256f279 Mon Sep 17 00:00:00 2001 From: Silc Renew Date: Fri, 2 Dec 2022 14:05:04 +0900 Subject: [PATCH 11/11] Fix animation signal caches_cleared firing timing (cherry picked from commit 962b6a3e8f9d91f92f2547e2da6ba8dbd5a661dc) --- scene/animation/animation_player.cpp | 3 ++- scene/animation/animation_tree.cpp | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 44d568407d8..4bfed54122b 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -1337,7 +1337,6 @@ float AnimationPlayer::get_current_animation_length() const { void AnimationPlayer::_animation_changed() { clear_caches(); - emit_signal("caches_cleared"); if (is_playing()) { playback.seeked = true; //need to restart stuff, like audio } @@ -1376,6 +1375,8 @@ void AnimationPlayer::clear_caches() { cache_update_size = 0; cache_update_prop_size = 0; cache_update_bezier_size = 0; + + emit_signal("caches_cleared"); } void AnimationPlayer::set_active(bool p_active) { diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index f371824c029..b333b780d7c 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -713,7 +713,6 @@ void AnimationTree::_clear_caches() { memdelete(track_cache[*K]); } playing_caches.clear(); - track_cache.clear(); cache_valid = false; }