summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/string/string_name.cpp100
-rw-r--r--core/string/string_name.h11
-rw-r--r--editor/editor_inspector.cpp10
-rw-r--r--editor/editor_inspector.h1
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp16
-rw-r--r--editor/plugins/animation_player_editor_plugin.h2
-rw-r--r--main/main.cpp5
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp59
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp75
9 files changed, 212 insertions, 67 deletions
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 28077fc8c5..0294dbfbbc 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -39,6 +39,30 @@ StaticCString StaticCString::create(const char *p_ptr) {
return scs;
}
+bool StringName::_Data::operator==(const String &p_name) const {
+ if (cname) {
+ return p_name == cname;
+ } else {
+ return name == p_name;
+ }
+}
+
+bool StringName::_Data::operator!=(const String &p_name) const {
+ return !operator==(p_name);
+}
+
+bool StringName::_Data::operator==(const char *p_name) const {
+ if (cname) {
+ return strcmp(cname, p_name) == 0;
+ } else {
+ return name == p_name;
+ }
+}
+
+bool StringName::_Data::operator!=(const char *p_name) const {
+ return !operator==(p_name);
+}
+
StringName _scs_create(const char *p_chr, bool p_static) {
return (p_chr[0] ? StringName(StaticCString::create(p_chr), p_static) : StringName());
}
@@ -139,19 +163,19 @@ void StringName::unref() {
}
bool StringName::operator==(const String &p_name) const {
- if (!_data) {
- return (p_name.length() == 0);
+ if (_data) {
+ return _data->operator==(p_name);
}
- return (_data->get_name() == p_name);
+ return p_name.is_empty();
}
bool StringName::operator==(const char *p_name) const {
- if (!_data) {
- return (p_name[0] == 0);
+ if (_data) {
+ return _data->operator==(p_name);
}
- return (_data->get_name() == p_name);
+ return p_name[0] == 0;
}
bool StringName::operator!=(const String &p_name) const {
@@ -168,9 +192,47 @@ bool StringName::operator!=(const StringName &p_name) const {
return _data != p_name._data;
}
-void StringName::operator=(const StringName &p_name) {
+char32_t StringName::operator[](int p_index) const {
+ if (_data) {
+ if (_data->cname) {
+ CRASH_BAD_INDEX(p_index, static_cast<long>(strlen(_data->cname)));
+ return _data->cname[p_index];
+ } else {
+ return _data->name[p_index];
+ }
+ }
+
+ CRASH_BAD_INDEX(p_index, 0);
+ return 0;
+}
+
+int StringName::length() const {
+ if (_data) {
+ if (_data->cname) {
+ return strlen(_data->cname);
+ } else {
+ return _data->name.length();
+ }
+ }
+
+ return 0;
+}
+
+bool StringName::is_empty() const {
+ if (_data) {
+ if (_data->cname) {
+ return _data->cname[0] == 0;
+ } else {
+ return _data->name.is_empty();
+ }
+ }
+
+ return true;
+}
+
+StringName &StringName::operator=(const StringName &p_name) {
if (this == &p_name) {
- return;
+ return *this;
}
unref();
@@ -178,6 +240,8 @@ void StringName::operator=(const StringName &p_name) {
if (p_name._data && p_name._data->refcount.ref()) {
_data = p_name._data;
}
+
+ return *this;
}
StringName::StringName(const StringName &p_name) {
@@ -216,7 +280,7 @@ StringName::StringName(const char *p_name, bool p_static) {
while (_data) {
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name) {
+ if (_data->hash == hash && _data->operator==(p_name)) {
break;
}
_data = _data->next;
@@ -275,7 +339,7 @@ StringName::StringName(const StaticCString &p_static_string, bool p_static) {
while (_data) {
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_static_string.ptr) {
+ if (_data->hash == hash && _data->operator==(p_static_string.ptr)) {
break;
}
_data = _data->next;
@@ -333,7 +397,7 @@ StringName::StringName(const String &p_name, bool p_static) {
_data = _table[idx];
while (_data) {
- if (_data->hash == hash && _data->get_name() == p_name) {
+ if (_data->hash == hash && _data->operator==(p_name)) {
break;
}
_data = _data->next;
@@ -392,7 +456,7 @@ StringName StringName::search(const char *p_name) {
while (_data) {
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name) {
+ if (_data->hash == hash && _data->operator==(p_name)) {
break;
}
_data = _data->next;
@@ -429,7 +493,7 @@ StringName StringName::search(const char32_t *p_name) {
while (_data) {
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name) {
+ if (_data->hash == hash && _data->operator==(p_name)) {
break;
}
_data = _data->next;
@@ -455,7 +519,7 @@ StringName StringName::search(const String &p_name) {
while (_data) {
// compare hash first
- if (_data->hash == hash && p_name == _data->get_name()) {
+ if (_data->hash == hash && _data->operator==(p_name)) {
break;
}
_data = _data->next;
@@ -474,15 +538,15 @@ StringName StringName::search(const String &p_name) {
}
bool operator==(const String &p_name, const StringName &p_string_name) {
- return p_name == p_string_name.operator String();
+ return p_string_name.operator==(p_name);
}
bool operator!=(const String &p_name, const StringName &p_string_name) {
- return p_name != p_string_name.operator String();
+ return p_string_name.operator!=(p_name);
}
bool operator==(const char *p_name, const StringName &p_string_name) {
- return p_name == p_string_name.operator String();
+ return p_string_name.operator==(p_name);
}
bool operator!=(const char *p_name, const StringName &p_string_name) {
- return p_name != p_string_name.operator String();
+ return p_string_name.operator!=(p_name);
}
diff --git a/core/string/string_name.h b/core/string/string_name.h
index 0eb98cf64b..288e2c7520 100644
--- a/core/string/string_name.h
+++ b/core/string/string_name.h
@@ -60,6 +60,11 @@ class StringName {
uint32_t debug_references = 0;
#endif
String get_name() const { return cname ? String(cname) : name; }
+ bool operator==(const String &p_name) const;
+ bool operator!=(const String &p_name) const;
+ bool operator==(const char *p_name) const;
+ bool operator!=(const char *p_name) const;
+
int idx = 0;
uint32_t hash = 0;
_Data *prev = nullptr;
@@ -99,6 +104,10 @@ public:
bool operator!=(const String &p_name) const;
bool operator!=(const char *p_name) const;
+ char32_t operator[](int p_index) const;
+ int length() const;
+ bool is_empty() const;
+
_FORCE_INLINE_ bool is_node_unique_name() const {
if (!_data) {
return false;
@@ -175,7 +184,7 @@ public:
}
};
- void operator=(const StringName &p_name);
+ StringName &operator=(const StringName &p_name);
StringName(const char *p_name, bool p_static = false);
StringName(const StringName &p_name);
StringName(const String &p_name, bool p_static = false);
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 1e5acce032..a1cae374aa 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -1500,12 +1500,6 @@ void EditorInspectorSection::_notification(int p_what) {
draw_string(font, text_offset, label, text_align, available, font_size, font_color, TextServer::JUSTIFICATION_KASHIDA | TextServer::JUSTIFICATION_CONSTRAIN_ELLIPSIS);
}
- // Draw dropping highlight.
- if (dropping && !vbox->is_visible_in_tree()) {
- Color accent_color = get_theme_color(SNAME("accent_color"), EditorStringName(Editor));
- draw_rect(Rect2(Point2(), get_size()), accent_color, false);
- }
-
// Draw section indentation.
if (section_indent_style.is_valid() && section_indent > 0) {
Rect2 indent_rect = Rect2(Vector2(), Vector2(indent_depth * section_indent_size, get_size().height));
@@ -1527,14 +1521,14 @@ void EditorInspectorSection::_notification(int p_what) {
} break;
case NOTIFICATION_MOUSE_ENTER: {
- if (dropping || dropping_for_unfold) {
+ if (dropping_for_unfold) {
dropping_unfold_timer->start();
}
queue_redraw();
} break;
case NOTIFICATION_MOUSE_EXIT: {
- if (dropping || dropping_for_unfold) {
+ if (dropping_for_unfold) {
dropping_unfold_timer->stop();
}
queue_redraw();
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 29ee234883..fda1443000 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -310,7 +310,6 @@ class EditorInspectorSection : public Container {
int level = 1;
Timer *dropping_unfold_timer = nullptr;
- bool dropping = false;
bool dropping_for_unfold = false;
HashSet<StringName> revertable_properties;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index b882112950..5cb558abbe 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -402,7 +402,17 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
track_editor->set_animation(anim, animation_is_readonly);
Node *root = player->get_node_or_null(player->get_root_node());
- if (root) {
+
+ // Player shouldn't access parent if it's the scene root.
+ if (!root || (player == get_tree()->get_edited_scene_root() && player->get_root_node() == SceneStringName(path_pp))) {
+ NodePath cached_root_path = player->get_path_to(get_cached_root_node());
+ if (player->get_node_or_null(cached_root_path) != nullptr) {
+ player->set_root_node(cached_root_path);
+ } else {
+ player->set_root_node(SceneStringName(path_pp)); // No other choice, preventing crash.
+ }
+ } else {
+ cached_root_node_id = root->get_instance_id(); // Caching as `track_editor` can lose track of player's root node.
track_editor->set_root(root);
}
}
@@ -1886,6 +1896,10 @@ AnimationMixer *AnimationPlayerEditor::fetch_mixer_for_library() const {
return original_node;
}
+Node *AnimationPlayerEditor::get_cached_root_node() const {
+ return Object::cast_to<Node>(ObjectDB::get_instance(cached_root_node_id));
+}
+
bool AnimationPlayerEditor::_validate_tracks(const Ref<Animation> p_anim) {
bool is_valid = true;
if (!p_anim.is_valid()) {
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 860d421b91..e4ca6c17c3 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -52,6 +52,7 @@ class AnimationPlayerEditor : public VBoxContainer {
AnimationPlayerEditorPlugin *plugin = nullptr;
AnimationMixer *original_node = nullptr; // For pinned mark in SceneTree.
AnimationPlayer *player = nullptr; // For AnimationPlayerEditor, could be dummy.
+ ObjectID cached_root_node_id;
bool is_dummy = false;
enum {
@@ -253,6 +254,7 @@ public:
AnimationMixer *get_editing_node() const;
AnimationPlayer *get_player() const;
AnimationMixer *fetch_mixer_for_library() const;
+ Node *get_cached_root_node() const;
static AnimationPlayerEditor *get_singleton() { return singleton; }
diff --git a/main/main.cpp b/main/main.cpp
index f2f71c27a4..db5e6ec398 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -2903,6 +2903,8 @@ Error Main::setup2(bool p_show_boot_logo) {
Error err;
display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, context, err);
if (err != OK || display_server == nullptr) {
+ String last_name = DisplayServer::get_create_function_name(display_driver_idx);
+
// We can't use this display server, try other ones as fallback.
// Skip headless (always last registered) because that's not what users
// would expect if they didn't request it explicitly.
@@ -2910,6 +2912,9 @@ Error Main::setup2(bool p_show_boot_logo) {
if (i == display_driver_idx) {
continue; // Don't try the same twice.
}
+ String name = DisplayServer::get_create_function_name(i);
+ WARN_PRINT(vformat("Display driver %s failed, falling back to %s.", last_name, name));
+
display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, context, err);
if (err == OK && display_server != nullptr) {
break;
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index d1d83fe4ce..c3b31b631e 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -1349,23 +1349,39 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
rendering_driver = p_rendering_driver;
+ bool driver_found = false;
+ String executable_name = OS::get_singleton()->get_executable_path().get_file();
+
#ifdef RD_ENABLED
#ifdef VULKAN_ENABLED
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanWayland);
}
-#endif
+#endif // VULKAN_ENABLED
if (rendering_context) {
if (rendering_context->initialize() != OK) {
- ERR_PRINT(vformat("Could not initialize %s", rendering_driver));
memdelete(rendering_context);
rendering_context = nullptr;
r_error = ERR_CANT_CREATE;
- return;
+
+ if (p_rendering_driver == "vulkan") {
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
+ "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
+ "You can enable the OpenGL 3 driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize Vulkan video driver");
+ }
+
+ ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
}
+
+ driver_found = true;
}
-#endif
+#endif // RD_ENABLED
#ifdef GLES3_ENABLED
if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") {
@@ -1432,26 +1448,53 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else {
r_error = ERR_UNAVAILABLE;
+
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
+ "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
+ "You can enable the Vulkan driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize OpenGL video driver");
+
ERR_FAIL_MSG("Could not initialize OpenGL.");
}
} else {
RasterizerGLES3::make_current(true);
+ driver_found = true;
}
}
if (rendering_driver == "opengl3_es") {
egl_manager = memnew(EGLManagerWaylandGLES);
- if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK) {
+ if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) {
memdelete(egl_manager);
egl_manager = nullptr;
r_error = ERR_CANT_CREATE;
- ERR_FAIL_MSG("Could not initialize GLES3.");
+
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n"
+ "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
+ "You can enable the Vulkan driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize OpenGL ES video driver");
+
+ ERR_FAIL_MSG("Could not initialize OpenGL ES.");
}
RasterizerGLES3::make_current(false);
+ driver_found = true;
}
}
+
+ if (!driver_found) {
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Video driver not found.");
+ }
#endif // GLES3_ENABLED
cursor_set_shape(CURSOR_BUSY);
@@ -1482,12 +1525,12 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
RendererCompositorRD::make_current();
}
-#endif
+#endif // RD_ENABLED
#ifdef DBUS_ENABLED
portal_desktop = memnew(FreeDesktopPortalDesktop);
screensaver = memnew(FreeDesktopScreenSaver);
-#endif
+#endif // DBUS_ENABLED
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index e602963c54..840cadace3 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -5428,25 +5428,6 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error));
- if (r_error != OK) {
- if (p_rendering_driver == "vulkan") {
- String executable_name = OS::get_singleton()->get_executable_path().get_file();
- OS::get_singleton()->alert(
- vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
- "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
- "You can enable the OpenGL 3 driver by starting the engine from the\n"
- "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
- "If you recently updated your video card drivers, try rebooting.",
- executable_name),
- "Unable to initialize Vulkan video driver");
- } else {
- OS::get_singleton()->alert(
- "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
- "If possible, consider updating your video card drivers.\n\n"
- "If you recently updated your video card drivers, try rebooting.",
- "Unable to initialize OpenGL video driver");
- }
- }
return ds;
}
@@ -6160,25 +6141,40 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
rendering_driver = p_rendering_driver;
bool driver_found = false;
+ String executable_name = OS::get_singleton()->get_executable_path().get_file();
+
+ // Initialize context and rendering device.
+
#if defined(RD_ENABLED)
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
rendering_context = memnew(RenderingContextDriverVulkanX11);
}
-#endif
+#endif // VULKAN_ENABLED
if (rendering_context) {
if (rendering_context->initialize() != OK) {
- ERR_PRINT(vformat("Could not initialize %s", rendering_driver));
memdelete(rendering_context);
rendering_context = nullptr;
r_error = ERR_CANT_CREATE;
- return;
+
+ if (p_rendering_driver == "vulkan") {
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required Vulkan version.\n\n"
+ "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n"
+ "You can enable the OpenGL 3 driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize Vulkan video driver");
+ }
+
+ ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver));
}
driver_found = true;
}
-#endif
- // Initialize context and rendering device.
+#endif // RD_ENABLED
+
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") {
if (getenv("DRI_PRIME") == nullptr) {
@@ -6234,6 +6230,16 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else {
r_error = ERR_UNAVAILABLE;
+
+ OS::get_singleton()->alert(
+ vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n"
+ "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n"
+ "You can enable the Vulkan driver by starting the engine from the\n"
+ "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ executable_name),
+ "Unable to initialize OpenGL video driver");
+
ERR_FAIL_MSG("Could not initialize OpenGL.");
}
} else {
@@ -6244,20 +6250,28 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
if (rendering_driver == "opengl3_es") {
gl_manager_egl = memnew(GLManagerEGL_X11);
- if (gl_manager_egl->initialize() != OK) {
+ if (gl_manager_egl->initialize() != OK || gl_manager_egl->open_display(x11_display) != OK) {
memdelete(gl_manager_egl);
gl_manager_egl = nullptr;
r_error = ERR_UNAVAILABLE;
- ERR_FAIL_MSG("Could not initialize OpenGLES.");
+
+ OS::get_singleton()->alert(
+ "Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n"
+ "If possible, consider updating your video card drivers.\n\n"
+ "If you recently updated your video card drivers, try rebooting.",
+ "Unable to initialize OpenGL ES video driver");
+
+ ERR_FAIL_MSG("Could not initialize OpenGL ES.");
}
driver_found = true;
RasterizerGLES3::make_current(false);
}
-#endif
+#endif // GLES3_ENABLED
+
if (!driver_found) {
r_error = ERR_UNAVAILABLE;
- ERR_FAIL_MSG("Video driver not found");
+ ERR_FAIL_MSG("Video driver not found.");
}
Point2i window_position;
@@ -6298,7 +6312,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
RendererCompositorRD::make_current();
}
-#endif
+#endif // RD_ENABLED
{
//set all event master mask
@@ -6451,7 +6465,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
portal_desktop = memnew(FreeDesktopPortalDesktop);
-#endif
+#endif // DBUS_ENABLED
+
XSetErrorHandler(&default_window_error_handler);
r_error = OK;