summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp2
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp16
-rw-r--r--modules/gdscript/gdscript_analyzer.h2
-rw-r--r--modules/gdscript/gdscript_compiler.cpp1
-rw-r--r--modules/gdscript/gdscript_editor.cpp124
-rw-r--r--modules/gdscript/gdscript_parser.cpp2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd6
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out2
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd9
-rw-r--r--modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs2
-rw-r--r--modules/multiplayer/editor/replication_editor.cpp2
-rw-r--r--modules/navigation/nav_link.h4
-rw-r--r--modules/theora/SCsub7
-rw-r--r--modules/webp/webp_common.cpp50
-rw-r--r--modules/webp/webp_common.h2
-rw-r--r--modules/webxr/native/library_godot_webxr.js4
17 files changed, 130 insertions, 107 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 420401cb79..0ebdbf090d 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -322,7 +322,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
String word = str.substr(j, to - j);
- Color col = Color();
+ Color col;
if (global_functions.has(word)) {
// "assert" and "preload" are reserved, so highlight even if not followed by a bracket.
if (word == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::ASSERT) || word == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::PRELOAD)) {
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 8da77b9e5b..3d248e3da7 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -32,6 +32,7 @@
#include "core/config/engine.h"
#include "core/config/project_settings.h"
+#include "core/core_string_names.h"
#include "core/io/file_access.h"
#include "core/io/resource_loader.h"
#include "core/object/class_db.h"
@@ -132,7 +133,7 @@ static GDScriptParser::DataType make_builtin_meta_type(Variant::Type p_type) {
return type;
}
-bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName &p_member_name, const GDScriptParser::ClassNode *p_class) {
+bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName &p_member_name, const GDScriptParser::ClassNode *p_class, const GDScriptParser::Node *p_member) {
if (p_class->members_indices.has(p_member_name)) {
int index = p_class->members_indices[p_member_name];
const GDScriptParser::ClassNode::Member *member = &p_class->members[index];
@@ -145,6 +146,9 @@ bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName
member->type == GDScriptParser::ClassNode::Member::SIGNAL) {
return true;
}
+ if (p_member->type != GDScriptParser::Node::FUNCTION && member->type == GDScriptParser::ClassNode::Member::FUNCTION) {
+ return true;
+ }
}
return false;
@@ -160,6 +164,9 @@ bool GDScriptAnalyzer::has_member_name_conflict_in_native_type(const StringName
if (ClassDB::has_integer_constant(p_native_type_string, p_member_name)) {
return true;
}
+ if (p_member_name == CoreStringNames::get_singleton()->_script) {
+ return true;
+ }
return false;
}
@@ -187,14 +194,15 @@ Error GDScriptAnalyzer::check_class_member_name_conflict(const GDScriptParser::C
const GDScriptParser::DataType *current_data_type = &p_class_node->base_type;
while (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::CLASS) {
GDScriptParser::ClassNode *current_class_node = current_data_type->class_type;
- if (has_member_name_conflict_in_script_class(p_member_name, current_class_node)) {
- push_error(vformat(R"(The member "%s" already exists in a parent class.)", p_member_name),
+ if (has_member_name_conflict_in_script_class(p_member_name, current_class_node, p_member_node)) {
+ push_error(vformat(R"(The member "%s" already exists in parent class %s.)", p_member_name, current_class_node->identifier->name),
p_member_node);
return ERR_PARSE_ERROR;
}
current_data_type = &current_class_node->base_type;
}
+ // No need for native class recursion because Node exposes all Object's properties.
if (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::NATIVE) {
if (current_data_type->native_type != StringName()) {
return check_native_member_name_conflict(
@@ -2912,7 +2920,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
base_class = base_class->base_type.class_type;
}
- // Check native members.
+ // Check native members. No need for native class recursion because Node exposes all Object's properties.
const StringName &native = base.native_type;
if (class_exists(native)) {
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index 217a856ce0..23a3ad39a5 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -45,7 +45,7 @@ class GDScriptAnalyzer {
List<GDScriptParser::LambdaNode *> lambda_stack;
// Tests for detecting invalid overloading of script members
- static _FORCE_INLINE_ bool has_member_name_conflict_in_script_class(const StringName &p_name, const GDScriptParser::ClassNode *p_current_class_node);
+ static _FORCE_INLINE_ bool has_member_name_conflict_in_script_class(const StringName &p_name, const GDScriptParser::ClassNode *p_current_class_node, const GDScriptParser::Node *p_member);
static _FORCE_INLINE_ bool has_member_name_conflict_in_native_type(const StringName &p_name, const StringName &p_native_type_string);
Error check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string);
Error check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node);
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index aa1356d8c0..824625b745 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -133,6 +133,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
if (script.is_null()) {
_set_error(vformat(R"(Could not find class "%s" in "%s".)", p_datatype.class_type->fqcn, p_datatype.script_path), nullptr);
+ return GDScriptDataType();
} else {
// Only hold a strong reference if the owner of the element qualified with this type is not local, to avoid cyclic references (leaks).
// TODO: Might lead to use after free if script_type is a subclass and is used after its parent is freed.
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 68508b20da..48a6e3fb51 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -2511,6 +2511,57 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
}
}
+static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, const GDScriptParser::SubscriptNode *p_subscript, GDScriptParser::DataType &r_base_type, Variant *r_base = nullptr) {
+ if (p_subscript->base->type == GDScriptParser::Node::IDENTIFIER) {
+ const GDScriptParser::GetNodeNode *get_node = nullptr;
+ const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base);
+
+ switch (identifier_node->source) {
+ case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
+ if (p_context.current_class != nullptr) {
+ const StringName &member_name = identifier_node->name;
+ const GDScriptParser::ClassNode *current_class = p_context.current_class;
+
+ if (current_class->has_member(member_name)) {
+ const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
+
+ if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
+ const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
+
+ if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
+ get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
+ }
+ }
+ }
+ }
+ } break;
+ case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
+ if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
+ get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
+ }
+ } break;
+ default:
+ break;
+ }
+
+ if (get_node != nullptr) {
+ const Object *node = p_context.base->call("get_node_or_null", NodePath(get_node->full_path));
+ if (node != nullptr) {
+ if (r_base != nullptr) {
+ *r_base = node;
+ }
+ r_base_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+ r_base_type.kind = GDScriptParser::DataType::NATIVE;
+ r_base_type.native_type = node->get_class_name();
+ r_base_type.builtin_type = Variant::OBJECT;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
if (p_call->type == GDScriptParser::Node::PRELOAD) {
if (p_argidx == 0 && bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) {
@@ -2561,13 +2612,17 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
}
}
- if (subscript->is_attribute) {
- GDScriptCompletionIdentifier ci;
- if (_guess_expression_type(p_context, subscript->base, ci)) {
- base_type = ci.type;
- base = ci.value;
- } else {
- return;
+ if (p_context.base != nullptr && subscript->is_attribute) {
+ bool found_type = _get_subscript_type(p_context, subscript, base_type, &base);
+
+ if (!found_type) {
+ GDScriptCompletionIdentifier ci;
+ if (_guess_expression_type(p_context, subscript->base, ci)) {
+ base_type = ci.type;
+ base = ci.value;
+ } else {
+ return;
+ }
}
_static = base_type.is_meta_type;
@@ -2765,60 +2820,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node);
if (attr->base) {
GDScriptCompletionIdentifier base;
- bool found_type = false;
-
- if (p_owner != nullptr && attr->base->type == GDScriptParser::Node::IDENTIFIER) {
- const GDScriptParser::GetNodeNode *get_node = nullptr;
- const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(attr->base);
-
- switch (identifier_node->source) {
- case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: {
- if (completion_context.current_class != nullptr) {
- const StringName &member_name = identifier_node->name;
- const GDScriptParser::ClassNode *current_class = completion_context.current_class;
-
- if (current_class->has_member(member_name)) {
- const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name);
-
- if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) {
- const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable);
-
- if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) {
- get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer);
- }
- }
- }
- }
- } break;
- case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: {
- if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) {
- get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next);
- }
- } break;
- default:
- break;
- }
-
- if (get_node != nullptr) {
- const Object *node = p_owner->call("get_node_or_null", NodePath(get_node->full_path));
- if (node != nullptr) {
- found_type = true;
-
- GDScriptParser::DataType type;
- type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
- type.kind = GDScriptParser::DataType::NATIVE;
- type.native_type = node->get_class_name();
- type.builtin_type = Variant::OBJECT;
-
- base.type = type;
- }
-
- if (!found_type) {
- break;
- }
- }
- }
-
+ bool found_type = _get_subscript_type(completion_context, attr, base.type);
if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) {
break;
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 71cedb4f38..053d81893d 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -230,7 +230,7 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_
warning.leftmost_column = p_source->leftmost_column;
warning.rightmost_column = p_source->rightmost_column;
- if (warn_level == GDScriptWarning::WarnLevel::ERROR) {
+ if (warn_level == GDScriptWarning::WarnLevel::ERROR || bool(GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors"))) {
push_error(warning.get_message(), p_source);
return;
}
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd
new file mode 100644
index 0000000000..5c8b9fa4ae
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.gd
@@ -0,0 +1,6 @@
+extends Node
+
+var script: int
+
+func test():
+ pass
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out
new file mode 100644
index 0000000000..8454aaa404
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/overload_script_variable.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+Member "script" redefined (original in native class 'Node')
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd
new file mode 100644
index 0000000000..28561ff94b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.gd
@@ -0,0 +1,9 @@
+func test():
+ pass
+
+class A:
+ func overload_me():
+ pass
+
+class B extends A:
+ var overload_me
diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out
new file mode 100644
index 0000000000..32357f9f6a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_overloads_superclass_function.out
@@ -0,0 +1,2 @@
+GDTEST_ANALYZER_ERROR
+The member "overload_me" already exists in parent class A.
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index d77baab24b..f511233fcc 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -229,7 +229,6 @@ namespace Godot
sb.Replace("\v", "\\v");
sb.Replace("\'", "\\'");
sb.Replace("\"", "\\\"");
- sb.Replace("?", "\\?");
return sb.ToString();
}
@@ -253,7 +252,6 @@ namespace Godot
sb.Replace("\\v", "\v");
sb.Replace("\\'", "\'");
sb.Replace("\\\"", "\"");
- sb.Replace("\\?", "?");
sb.Replace("\\\\", "\\");
return sb.ToString();
diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp
index 4ba9cd14f0..ccde9fed22 100644
--- a/modules/multiplayer/editor/replication_editor.cpp
+++ b/modules/multiplayer/editor/replication_editor.cpp
@@ -202,7 +202,7 @@ ReplicationEditor::ReplicationEditor() {
add_pick_button = memnew(Button);
add_pick_button->connect("pressed", callable_mp(this, &ReplicationEditor::_pick_new_property));
- add_pick_button->set_text(TTR("Add property to sync.."));
+ add_pick_button->set_text(TTR("Add property to sync..."));
hb->add_child(add_pick_button);
VSeparator *vs = memnew(VSeparator);
vs->set_custom_minimum_size(Size2(30 * EDSCALE, 0));
diff --git a/modules/navigation/nav_link.h b/modules/navigation/nav_link.h
index 8d57f076c0..8f51a63951 100644
--- a/modules/navigation/nav_link.h
+++ b/modules/navigation/nav_link.h
@@ -37,8 +37,8 @@
class NavLink : public NavBase {
NavMap *map = nullptr;
bool bidirectional = true;
- Vector3 start_location = Vector3();
- Vector3 end_location = Vector3();
+ Vector3 start_location;
+ Vector3 end_location;
bool link_dirty = true;
diff --git a/modules/theora/SCsub b/modules/theora/SCsub
index 6038ea086a..ca666050dd 100644
--- a/modules/theora/SCsub
+++ b/modules/theora/SCsub
@@ -15,7 +15,7 @@ if env["builtin_libtheora"]:
# "analyze.c",
# "apiwrapper.c",
"bitpack.c",
- "cpu.c",
+ # "collect.c",
# "decapiwrapper.c",
"decinfo.c",
"decode.c",
@@ -47,8 +47,12 @@ if env["builtin_libtheora"]:
"x86/mmxfrag.c",
"x86/mmxidct.c",
"x86/mmxstate.c",
+ # "x86/sse2encfrag.c",
# "x86/sse2fdct.c",
+ "x86/sse2idct.c",
+ "x86/x86cpu.c",
# "x86/x86enc.c",
+ # "x86/x86enquant.c"
"x86/x86state.c",
]
@@ -58,6 +62,7 @@ if env["builtin_libtheora"]:
"x86_vc/mmxfrag.c",
"x86_vc/mmxidct.c",
"x86_vc/mmxstate.c",
+ "x86_vc/x86cpu.c",
# "x86_vc/x86enc.c",
"x86_vc/x86state.c",
]
diff --git a/modules/webp/webp_common.cpp b/modules/webp/webp_common.cpp
index af98788420..572a33653e 100644
--- a/modules/webp/webp_common.cpp
+++ b/modules/webp/webp_common.cpp
@@ -41,40 +41,21 @@ namespace WebPCommon {
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
- Ref<Image> img = p_image->duplicate();
- if (img->detect_alpha()) {
- img->convert(Image::FORMAT_RGBA8);
- } else {
- img->convert(Image::FORMAT_RGB8);
- }
-
- Size2 s(img->get_width(), img->get_height());
- Vector<uint8_t> data = img->get_data();
- const uint8_t *r = data.ptr();
-
- uint8_t *dst_buff = nullptr;
- size_t dst_size = 0;
- if (img->get_format() == Image::FORMAT_RGB8) {
- dst_size = WebPEncodeRGB(r, s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff);
- } else {
- dst_size = WebPEncodeRGBA(r, s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), &dst_buff);
- }
-
- ERR_FAIL_COND_V(dst_size == 0, Vector<uint8_t>());
- Vector<uint8_t> dst;
- dst.resize(dst_size);
- uint8_t *w = dst.ptrw();
- memcpy(w, dst_buff, dst_size);
- WebPFree(dst_buff);
-
- return dst;
+ return _webp_packer(p_image, CLAMP(p_quality * 100.0f, 0.0f, 100.0f), false);
}
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) {
ERR_FAIL_COND_V(p_image.is_null() || p_image->is_empty(), Vector<uint8_t>());
- int compression_level = GLOBAL_GET("rendering/textures/lossless_compression/webp_compression_level");
- compression_level = CLAMP(compression_level, 0, 9);
+ float compression_factor = GLOBAL_GET("rendering/textures/webp_compression/lossless_compression_factor");
+ compression_factor = CLAMP(compression_factor, 0.0f, 100.0f);
+
+ return _webp_packer(p_image, compression_factor, true);
+}
+
+Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless) {
+ int compression_method = GLOBAL_GET("rendering/textures/webp_compression/compression_method");
+ compression_method = CLAMP(compression_method, 0, 6);
Ref<Image> img = p_image->duplicate();
if (img->detect_alpha()) {
@@ -87,16 +68,21 @@ Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image) {
Vector<uint8_t> data = img->get_data();
const uint8_t *r = data.ptr();
- // we need to use the more complex API in order to access the 'exact' flag...
+ // we need to use the more complex API in order to access specific flags...
WebPConfig config;
WebPPicture pic;
- if (!WebPConfigInit(&config) || !WebPConfigLosslessPreset(&config, compression_level) || !WebPPictureInit(&pic)) {
+ if (!WebPConfigInit(&config) || !WebPPictureInit(&pic)) {
ERR_FAIL_V(Vector<uint8_t>());
}
WebPMemoryWriter wrt;
- config.exact = 1;
+ if (p_lossless) {
+ config.lossless = 1;
+ config.exact = 1;
+ }
+ config.method = compression_method;
+ config.quality = p_quality;
pic.use_argb = 1;
pic.width = s.width;
pic.height = s.height;
diff --git a/modules/webp/webp_common.h b/modules/webp/webp_common.h
index 11bef40256..23b433ad79 100644
--- a/modules/webp/webp_common.h
+++ b/modules/webp/webp_common.h
@@ -37,6 +37,8 @@ namespace WebPCommon {
// Given an image, pack this data into a WebP file.
Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality);
Vector<uint8_t> _webp_lossless_pack(const Ref<Image> &p_image);
+// Helper function for those above.
+Vector<uint8_t> _webp_packer(const Ref<Image> &p_image, float p_quality, bool p_lossless);
// Given a WebP file, unpack it into an image.
Ref<Image> _webp_unpack(const Vector<uint8_t> &p_buffer);
Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len);
diff --git a/modules/webxr/native/library_godot_webxr.js b/modules/webxr/native/library_godot_webxr.js
index c476a54c59..714768347c 100644
--- a/modules/webxr/native/library_godot_webxr.js
+++ b/modules/webxr/native/library_godot_webxr.js
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
const GodotWebXR = {
- $GodotWebXR__deps: ['$Browser', '$GL', '$GodotRuntime'],
+ $GodotWebXR__deps: ['$Browser', '$GL', '$GodotRuntime', '$runtimeKeepalivePush', '$runtimeKeepalivePop'],
$GodotWebXR: {
gl: null,
@@ -69,7 +69,9 @@ const GodotWebXR = {
// gets picked up automatically, however, in the Oculus Browser
// on the Quest, we need to pause and resume the main loop.
Browser.mainLoop.pause();
+ runtimeKeepalivePush(); // eslint-disable-line no-undef
window.setTimeout(function () {
+ runtimeKeepalivePop(); // eslint-disable-line no-undef
Browser.mainLoop.resume();
}, 0);
},