diff options
| -rw-r--r-- | core/string/string_name.cpp | 100 | ||||
| -rw-r--r-- | core/string/string_name.h | 11 | ||||
| -rw-r--r-- | editor/editor_inspector.cpp | 10 | ||||
| -rw-r--r-- | editor/editor_inspector.h | 1 | ||||
| -rw-r--r-- | editor/plugins/animation_player_editor_plugin.cpp | 16 | ||||
| -rw-r--r-- | editor/plugins/animation_player_editor_plugin.h | 2 | ||||
| -rw-r--r-- | main/main.cpp | 5 | ||||
| -rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.cpp | 59 | ||||
| -rw-r--r-- | platform/linuxbsd/x11/display_server_x11.cpp | 75 |
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; |
