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

Cherry-picks for the 3.5 branch (future 3.5.3) - 3rd batch
This commit is contained in:
Rémi Verschelde 2023-09-06 16:38:57 +02:00 committed by GitHub
commit fc32e066af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 180 additions and 73 deletions

View File

@ -1,5 +1,6 @@
name: 🤖 Android Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -17,7 +18,7 @@ jobs:
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
# Azure repositories are not reliable, we need to prevent azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories

View File

@ -1,5 +1,6 @@
name: 🍏 iOS Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -17,7 +18,7 @@ jobs:
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache

View File

@ -1,5 +1,6 @@
name: 🌐 JavaScript Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -19,7 +20,7 @@ jobs:
name: Template (target=release, tools=no)
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Emscripten latest
uses: mymindstorm/setup-emsdk@v12

View File

@ -1,5 +1,6 @@
name: 🐧 Linux Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -48,7 +49,7 @@ jobs:
artifact: true
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Linux dependencies
shell: bash

View File

@ -1,5 +1,6 @@
name: 🍎 macOS Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -31,7 +32,7 @@ jobs:
tools: false
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache

46
.github/workflows/runner.yml vendored Normal file
View File

@ -0,0 +1,46 @@
name: 🔗 GHA
on: [push, pull_request]
concurrency:
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-runner
cancel-in-progress: true
jobs:
static-checks:
name: 📊 Static
uses: ./.github/workflows/static_checks.yml
android-build:
name: 🤖 Android
needs: static-checks
uses: ./.github/workflows/android_builds.yml
ios-build:
name: 🍏 iOS
needs: static-checks
uses: ./.github/workflows/ios_builds.yml
javascript-build:
name: 🌐 JavaScript
needs: static-checks
uses: ./.github/workflows/javascript_builds.yml
linux-build:
name: 🐧 Linux
needs: static-checks
uses: ./.github/workflows/linux_builds.yml
macos-build:
name: 🍎 macOS
needs: static-checks
uses: ./.github/workflows/macos_builds.yml
server-build:
name: ☁ Server
needs: static-checks
uses: ./.github/workflows/server_builds.yml
windows-build:
name: 🏁 Windows
needs: static-checks
uses: ./.github/workflows/windows_builds.yml

View File

@ -1,5 +1,6 @@
name: ☁ Server Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
env:
@ -30,7 +31,7 @@ jobs:
tools: false
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Linux dependencies
shell: bash

View File

@ -1,5 +1,6 @@
name: 📊 Static Checks
on: [push, pull_request]
on:
workflow_call:
concurrency:
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
@ -11,7 +12,7 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
# Azure repositories are not reliable, we need to prevent Azure giving us packages.
- name: Make apt sources.list use the default Ubuntu repositories

View File

@ -1,5 +1,6 @@
name: 🏁 Windows Builds
on: [push, pull_request]
on:
workflow_call:
# Global Settings
# SCONS_CACHE for windows must be set in the build environment
@ -34,7 +35,7 @@ jobs:
tools: false
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Godot build cache
uses: ./.github/actions/godot-cache

27
.gitignore vendored
View File

@ -131,23 +131,9 @@ cppcheck-cppcheck-build-dir/
*.pydevproject
*.launch
# Gcov and Lcov code coverage
*.gcno
# GCOV code coverage
*.gcda
*.gcov.html
*.func.html
*.func-sort-c.html
*index-sort-f.html
*index-sort-l.html
*index.html
godot.info
amber.png
emerald.png
glass.png
ruby.png
snow.png
updown.png
gcov.css
*.gcno
# Geany
*.geany
@ -246,9 +232,6 @@ xcuserdata/
x64/
x86/
# Do not ignore x86 folders anywhere under thirdparty libraries
!thirdparty/**/x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
@ -258,6 +241,12 @@ bld/
[Ll]og/
[Ll]ogs/
# Do not ignore arch-specific folders anywhere under thirdparty libraries
!thirdparty/**/x64/
!thirdparty/**/x86/
!thirdparty/**/arm/
!thirdparty/**/arm64/
# Visual Studio 2015/2017 cache/options directory
.vs/

View File

@ -170,6 +170,7 @@ public:
template <class T>
static void register_class() {
GLOBAL_LOCK_FUNCTION;
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
@ -182,6 +183,7 @@ public:
template <class T>
static void register_virtual_class() {
GLOBAL_LOCK_FUNCTION;
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);
@ -198,6 +200,7 @@ public:
template <class T>
static void register_custom_instance_class() {
GLOBAL_LOCK_FUNCTION;
static_assert(TypesAreSame<typename T::self_type, T>::value, "Class not declared properly, please use GDCLASS.");
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
ERR_FAIL_COND(!t);

View File

@ -2477,6 +2477,9 @@ void Image::_repeat_pixel_over_subsequent_memory(uint8_t *p_pixel, int p_pixel_s
}
void Image::fill(const Color &p_color) {
if (data.size() == 0) {
return;
}
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill in compressed or custom image formats.");
lock();
@ -2495,6 +2498,9 @@ void Image::fill(const Color &p_color) {
}
void Image::fill_rect(const Rect2 &p_rect, const Color &p_color) {
if (data.size() == 0) {
return;
}
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot fill rect in compressed or custom image formats.");
Rect2i r = Rect2i(0, 0, width, height).clip(p_rect.abs());

View File

@ -267,6 +267,7 @@ private:
friend class ClassDB; \
\
public: \
typedef m_class self_type; \
virtual String get_class() const { \
return String(#m_class); \
} \
@ -405,6 +406,8 @@ class ObjectRC;
class Object {
public:
typedef Object self_type;
enum ConnectFlags {
CONNECT_DEFERRED = 1,

View File

@ -1532,7 +1532,7 @@ static String rtos_fix(double p_value) {
}
}
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count) {
switch (p_variant.get_type()) {
case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null");
@ -1649,6 +1649,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::OBJECT: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "null");
return OK;
}
p_recursion_count++;
Object *obj = p_variant;
if (!obj) {
@ -1698,7 +1705,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
}
}
@ -1707,6 +1714,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::DICTIONARY: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "{}");
return OK;
}
p_recursion_count++;
Dictionary dict = p_variant;
List<Variant> keys;
@ -1719,9 +1733,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (!_check_type(dict[E->get()]))
continue;
*/
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
p_store_string_func(p_store_string_ud, ": ");
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n");
} else {
@ -1733,6 +1747,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::ARRAY: {
if (unlikely(p_recursion_count > MAX_RECURSION)) {
ERR_PRINT("Max recursion reached");
p_store_string_func(p_store_string_ud, "[]");
return OK;
}
p_recursion_count++;
p_store_string_func(p_store_string_ud, "[ ");
Array array = p_variant;
int len = array.size();
@ -1740,7 +1761,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
}
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud, p_recursion_count);
}
p_store_string_func(p_store_string_ud, " ]");
@ -1871,6 +1892,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, " )");
} break;
default: {
}
}

View File

@ -141,7 +141,7 @@ public:
typedef Error (*StoreStringFunc)(void *ud, const String &p_string);
typedef String (*EncodeResourceFunc)(void *ud, const RES &p_resource);
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud);
static Error write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud, int p_recursion_count = 0);
static Error write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func = nullptr, void *p_encode_res_ud = nullptr);
};

View File

@ -787,6 +787,9 @@ def generate_vs_project(env, num_jobs):
if env["custom_modules"]:
common_build_postfix.append("custom_modules=%s" % env["custom_modules"])
if env["incremental_link"]:
common_build_postfix.append("incremental_link=yes")
result = " ^& ".join(common_build_prefix + [" ".join([commands] + common_build_postfix)])
return result

View File

@ -0,0 +1 @@
!/debug

View File

@ -108,6 +108,12 @@ def configure(env):
env.Append(CCFLAGS=["-flto=full"])
env.Append(LINKFLAGS=["-flto=full"])
if env["use_thinlto"] or env["use_lto"]:
# Workaround https://github.com/emscripten-core/emscripten/issues/19781.
cc_semver = tuple(get_compiler_version(env))
if cc_semver >= (3, 1, 42):
env.Append(LINKFLAGS=["-Wl,-u,scalbnf"])
# Sanitizers
if env["use_ubsan"]:
env.Append(CCFLAGS=["-fsanitize=undefined"])

View File

@ -205,7 +205,9 @@ const GodotJSWrapper = {
return;
}
const args = Array.from(arguments);
func(p_ref, GodotJSWrapper.get_proxied(args), args.length);
const argsProxy = new GodotJSWrapper.MyProxy(args);
func(p_ref, argsProxy.get_id(), args.length);
argsProxy.unref();
};
id = GodotJSWrapper.get_proxied(cb);
return id;

View File

@ -73,6 +73,7 @@ def get_opts():
BoolVariable("use_thinlto", "Use ThinLTO", False),
BoolVariable("use_static_cpp", "Link MinGW/MSVC C++ runtime libraries statically", True),
BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
]
@ -216,8 +217,9 @@ def configure_msvc(env, manual_msvc_config):
else:
env.AppendUnique(CCFLAGS=["/MD"])
# MSVC incremental linking is broken and _increases_ link time (GH-77968).
env.Append(LINKFLAGS=["/INCREMENTAL:NO"])
# MSVC incremental linking is broken and may _increase_ link time (GH-77968).
if not env["incremental_link"]:
env.Append(LINKFLAGS=["/INCREMENTAL:NO"])
env.AppendUnique(CCFLAGS=["/Gd", "/GR", "/nologo"])
env.AppendUnique(CCFLAGS=["/utf-8"]) # Force to use Unicode encoding.

View File

@ -33,9 +33,19 @@
#include "core/input_map.h"
#include "core/os/input.h"
#include "core/os/os.h"
#include "scene/scene_string_names.h"
void TouchScreenButton::set_texture(const Ref<Texture> &p_texture) {
if (texture == p_texture) {
return;
}
if (texture.is_valid()) {
texture->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
}
texture = p_texture;
if (texture.is_valid()) {
texture->connect(SceneStringNames::get_singleton()->changed, this, "update", varray(), CONNECT_REFERENCE_COUNTED);
}
update();
}
@ -44,7 +54,16 @@ Ref<Texture> TouchScreenButton::get_texture() const {
}
void TouchScreenButton::set_texture_pressed(const Ref<Texture> &p_texture_pressed) {
if (texture_pressed == p_texture_pressed) {
return;
}
if (texture_pressed.is_valid()) {
texture_pressed->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
}
texture_pressed = p_texture_pressed;
if (texture_pressed.is_valid()) {
texture_pressed->connect(SceneStringNames::get_singleton()->changed, this, "update", varray(), CONNECT_REFERENCE_COUNTED);
}
update();
}
@ -61,16 +80,16 @@ Ref<BitMap> TouchScreenButton::get_bitmask() const {
}
void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) {
if (shape.is_valid()) {
shape->disconnect("changed", this, "update");
if (shape == p_shape) {
return;
}
if (shape.is_valid()) {
shape->disconnect(SceneStringNames::get_singleton()->changed, this, "update");
}
shape = p_shape;
if (shape.is_valid()) {
shape->connect("changed", this, "update");
shape->connect(SceneStringNames::get_singleton()->changed, this, "update");
}
update();
}

View File

@ -67,11 +67,6 @@ bool AudioEffectRecordInstance::process_silence() const {
void AudioEffectRecordInstance::_io_thread_process() {
while (is_recording) {
//Check: The current recording has been requested to stop
if (!base->recording_active) {
is_recording = false;
}
_update_buffer();
if (is_recording) {
@ -119,6 +114,7 @@ void AudioEffectRecordInstance::init() {
}
void AudioEffectRecordInstance::finish() {
is_recording = false;
#ifdef NO_THREADS
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
#else
@ -126,14 +122,9 @@ void AudioEffectRecordInstance::finish() {
#endif
}
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
finish();
}
Ref<AudioEffectInstance> AudioEffectRecord::instance() {
Ref<AudioEffectRecordInstance> ins;
ins.instance();
ins->base = Ref<AudioEffectRecord>(this);
ins->is_recording = false;
//Re-using the buffer size calculations from audio_effect_delay.cpp
@ -159,16 +150,19 @@ Ref<AudioEffectInstance> AudioEffectRecord::instance() {
ins->ring_buffer_read_pos = 0;
ensure_thread_stopped();
current_instance = ins;
if (recording_active) {
bool is_currently_recording = false;
if (current_instance != nullptr) {
is_currently_recording = current_instance->is_recording;
}
if (is_currently_recording) {
ins->init();
}
current_instance = ins;
return ins;
}
void AudioEffectRecord::ensure_thread_stopped() {
recording_active = false;
if (current_instance != nullptr) {
current_instance->finish();
}
@ -178,20 +172,24 @@ void AudioEffectRecord::set_recording_active(bool p_record) {
if (p_record) {
if (current_instance == nullptr) {
WARN_PRINT("Recording should not be set as active before Godot has initialized.");
recording_active = false;
return;
}
ensure_thread_stopped();
recording_active = true;
current_instance->init();
} else {
recording_active = false;
if (current_instance != nullptr) {
current_instance->is_recording = false;
}
}
}
bool AudioEffectRecord::is_recording_active() const {
return recording_active;
if (current_instance != nullptr) {
return current_instance->is_recording;
} else {
return false;
}
}
void AudioEffectRecord::set_format(AudioStreamSample::Format p_format) {
@ -289,5 +287,8 @@ void AudioEffectRecord::_bind_methods() {
AudioEffectRecord::AudioEffectRecord() {
format = AudioStreamSample::FORMAT_16_BITS;
recording_active = false;
}
AudioEffectRecord::~AudioEffectRecord() {
ensure_thread_stopped();
}

View File

@ -45,7 +45,6 @@ class AudioEffectRecord;
class AudioEffectRecordInstance : public AudioEffectInstance {
GDCLASS(AudioEffectRecordInstance, AudioEffectInstance);
friend class AudioEffectRecord;
Ref<AudioEffectRecord> base;
bool is_recording;
Thread io_thread;
@ -68,9 +67,6 @@ public:
void finish();
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
virtual bool process_silence() const;
AudioEffectRecordInstance() {}
~AudioEffectRecordInstance();
};
class AudioEffectRecord : public AudioEffect {
@ -82,7 +78,6 @@ class AudioEffectRecord : public AudioEffect {
IO_BUFFER_SIZE_MS = 1500
};
bool recording_active;
Ref<AudioEffectRecordInstance> current_instance;
AudioStreamSample::Format format;
@ -101,6 +96,7 @@ public:
Ref<AudioStreamSample> get_recording() const;
AudioEffectRecord();
~AudioEffectRecord();
};
#endif // AUDIO_EFFECT_RECORD_H