diff options
55 files changed, 487 insertions, 357 deletions
diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 6073856747..9c1d08331d 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -33,10 +33,22 @@ #ifdef EGL_ENABLED #if defined(EGL_STATIC) -#define KHRONOS_STATIC 1 + #define GLAD_EGL_VERSION_1_5 true + +#ifdef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 1 +#endif + +#define KHRONOS_STATIC 1 extern "C" EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); +extern "C" EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list); #undef KHRONOS_STATIC + +#endif // defined(EGL_STATIC) + +#ifndef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 0 #endif // Creates and caches a GLDisplay. Returns -1 on error. @@ -56,10 +68,23 @@ int EGLManager::_get_gldisplay_id(void *p_display) { if (GLAD_EGL_VERSION_1_5) { Vector<EGLAttrib> attribs = _get_platform_display_attributes(); new_gldisplay.egl_display = eglGetPlatformDisplay(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); + } else if (GLAD_EGL_EXT_platform_base) { +#ifdef EGL_EXT_platform_base + // eglGetPlatformDisplayEXT wants its attributes as EGLint, so we'll truncate + // what we already have. It's a bit naughty but I'm really not sure what else + // we could do here. + Vector<EGLint> attribs; + for (const EGLAttrib &attrib : _get_platform_display_attributes()) { + attribs.push_back((EGLint)attrib); + } + + new_gldisplay.egl_display = eglGetPlatformDisplayEXT(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); +#endif // EGL_EXT_platform_base } else { NativeDisplayType *native_display_type = (NativeDisplayType *)new_gldisplay.display; new_gldisplay.egl_display = eglGetDisplay(*native_display_type); } + ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, -1); ERR_FAIL_COND_V_MSG(new_gldisplay.egl_display == EGL_NO_DISPLAY, -1, "Can't create an EGL display."); @@ -326,30 +351,51 @@ EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) { return display.egl_context; } -Error EGLManager::initialize() { +Error EGLManager::initialize(void *p_native_display) { #if defined(GLAD_ENABLED) && !defined(EGL_STATIC) - // Passing a null display loads just the bare minimum to create one. We'll have - // to create a temporary test display and reload EGL with it to get a good idea - // of what version is supported on this machine. Currently we're looking for - // 1.5, the latest at the time of writing, which is actually pretty old. - if (!gladLoaderLoadEGL(nullptr)) { + // Loading EGL with a new display gets us just the bare minimum API. We'll then + // have to temporarily get a proper display and reload EGL once again to + // initialize everything else. + if (!gladLoaderLoadEGL(EGL_NO_DISPLAY)) { ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); } - // NOTE: EGL_DEFAULT_DISPLAY returns whatever the O.S. deems suitable. I have - // no idea if this may cause problems with multiple display servers and if we - // should handle different EGL contexts in another way. - EGLDisplay tmp_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - ERR_FAIL_COND_V(tmp_display == EGL_NO_DISPLAY, ERR_UNAVAILABLE); + EGLDisplay tmp_display = EGL_NO_DISPLAY; + + if (GLAD_EGL_EXT_platform_base) { +#ifdef EGL_EXT_platform_base + // eglGetPlatformDisplayEXT wants its attributes as EGLint. + Vector<EGLint> attribs; + for (const EGLAttrib &attrib : _get_platform_display_attributes()) { + attribs.push_back((EGLint)attrib); + } + tmp_display = eglGetPlatformDisplayEXT(_get_platform_extension_enum(), p_native_display, attribs.ptr()); +#endif // EGL_EXT_platform_base + } else { + WARN_PRINT("EGL: EGL_EXT_platform_base not found during init, using default platform."); + EGLNativeDisplayType *native_display_type = (EGLNativeDisplayType *)p_native_display; + tmp_display = eglGetDisplay(*native_display_type); + } + + if (tmp_display == EGL_NO_DISPLAY) { + eglTerminate(tmp_display); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't get a valid initial EGL display."); + } eglInitialize(tmp_display, nullptr, nullptr); int version = gladLoaderLoadEGL(tmp_display); + if (!version) { + eglTerminate(tmp_display); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); + } + + int major = GLAD_VERSION_MAJOR(version); + int minor = GLAD_VERSION_MINOR(version); - ERR_FAIL_COND_V_MSG(!version, ERR_UNAVAILABLE, "Can't load EGL."); - print_verbose(vformat("Loaded EGL %d.%d", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version))); + print_verbose(vformat("Loaded EGL %d.%d", major, minor)); - ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_4, ERR_UNAVAILABLE, "EGL version is too old!"); + ERR_FAIL_COND_V_MSG(!GLAD_EGL_VERSION_1_4, ERR_UNAVAILABLE, vformat("EGL version is too old! %d.%d < 1.4", major, minor)); eglTerminate(tmp_display); #endif @@ -378,13 +424,14 @@ Error EGLManager::initialize() { } #endif - String extensions_string = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - // The above method should always work. If it doesn't, something's very wrong. - ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, ERR_BUG); + String client_extensions_string = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - const char *platform = _get_platform_extension_name(); - if (!extensions_string.split(" ").has(platform)) { - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + // If the above method fails, we don't support client extensions, so there's nothing to check. + if (eglGetError() == EGL_SUCCESS) { + const char *platform = _get_platform_extension_name(); + if (!client_extensions_string.split(" ").has(platform)) { + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + } } return OK; diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h index 83779349f0..a4502c0687 100644 --- a/drivers/egl/egl_manager.h +++ b/drivers/egl/egl_manager.h @@ -107,7 +107,7 @@ public: EGLContext get_context(DisplayServer::WindowID p_window_id); - Error initialize(); + Error initialize(void *p_native_display = nullptr); EGLManager(); virtual ~EGLManager(); diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 993197e371..071765a03c 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -195,9 +195,9 @@ void RasterizerGLES3::initialize() { Engine::get_singleton()->print_header(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name())); // FLIP XY Bug: Are more devices affected? - // Confirmed so far: all Adreno 3xx + // Confirmed so far: all Adreno 3xx with old driver (until 2018) // ok on some tested Adreno devices: 4xx, 5xx and 6xx - flip_xy_bugfix = GLES3::Config::get_singleton()->adreno_3xx_compatibility; + flip_xy_workaround = GLES3::Config::get_singleton()->flip_xy_workaround; } void RasterizerGLES3::finalize() { @@ -411,7 +411,7 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display // Adreno (TM) 3xx devices have a bug that create wrong Landscape rotation of 180 degree // Reversing both the X and Y axis is equivalent to rotating 180 degrees bool flip_x = false; - if (flip_xy_bugfix && screen_rect_end.x > screen_rect_end.y) { + if (flip_xy_workaround && screen_rect_end.x > screen_rect_end.y) { flip_y = !flip_y; flip_x = !flip_x; } diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 09d3c7bd52..0d0c26016d 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -56,7 +56,7 @@ private: float delta = 0; double time_total = 0.0; - bool flip_xy_bugfix = false; + bool flip_xy_workaround = false; static bool gles_over_gl; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 2b372cb88d..be7a6aba57 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1523,6 +1523,9 @@ void main() { #CODE : FRAGMENT } + // Keep albedo values in positive number range as negative values "wraparound" into positive numbers resulting in wrong colors + albedo = max(albedo, vec3(0.0)); + #ifdef LIGHT_VERTEX_USED vertex = light_vertex; #ifdef USE_MULTIVIEW diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 6b5e227782..07e6d04cb7 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -169,8 +169,31 @@ Config::Config() { //Adreno 3xx Compatibility const String rendering_device_name = String::utf8((const char *)glGetString(GL_RENDERER)); - //TODO: Check the number between 300 and 399(?) - adreno_3xx_compatibility = (rendering_device_name.left(13) == "Adreno (TM) 3"); + if (rendering_device_name.left(13) == "Adreno (TM) 3") { + flip_xy_workaround = true; + disable_particles_workaround = true; + + // ignore driver version 331+ + const String gl_version = String::utf8((const char *)glGetString(GL_VERSION)); + // Adreno 3xx examples (https://opengles.gpuinfo.org/listreports.php): + // =========================================================================== + // OpenGL ES 3.0 V@84.0 AU@ (CL@) + // OpenGL ES 3.0 V@127.0 AU@ (GIT@I96aee987eb) + // OpenGL ES 3.0 V@140.0 AU@ (GIT@Ifd751822f5) + // OpenGL ES 3.0 V@251.0 AU@08.00.00.312.030 (GIT@Ie4790512f3) + // OpenGL ES 3.0 V@269.0 AU@ (GIT@I109c45a694) + // OpenGL ES 3.0 V@331.0 (GIT@35e467f, Ice9844a736) (Date:04/15/19) + // OpenGL ES 3.0 V@415.0 (GIT@d39f783, I79de86aa2c, 1591296226) (Date:06/04/20) + // OpenGL ES 3.0 V@0502.0 (GIT@09fef447e8, I1fe547a144, 1661493934) (Date:08/25/22) + String driver_version = gl_version.get_slice("V@", 1).get_slice(" ", 0); + if (driver_version.is_valid_float() && driver_version.to_float() >= 331.0) { + flip_xy_workaround = false; + + //TODO: also 'GPUParticles'? + //https://github.com/godotengine/godot/issues/92662#issuecomment-2161199477 + //disable_particles_workaround = false; + } + } } Config::~Config() { diff --git a/drivers/gles3/storage/config.h b/drivers/gles3/storage/config.h index c3ab65f0bc..ee7b1b26ed 100644 --- a/drivers/gles3/storage/config.h +++ b/drivers/gles3/storage/config.h @@ -91,7 +91,9 @@ public: bool rt_msaa_multiview_supported = false; bool multiview_supported = false; - bool adreno_3xx_compatibility = false; + // Adreno 3XX compatibility + bool disable_particles_workaround = false; // set to 'true' to disable 'GPUParticles' + bool flip_xy_workaround = false; #ifdef ANDROID_ENABLED PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVRPROC eglFramebufferTextureMultiviewOVR = nullptr; diff --git a/drivers/gles3/storage/particles_storage.cpp b/drivers/gles3/storage/particles_storage.cpp index fee90599e0..b600681280 100644 --- a/drivers/gles3/storage/particles_storage.cpp +++ b/drivers/gles3/storage/particles_storage.cpp @@ -122,7 +122,7 @@ void ParticlesStorage::particles_set_mode(RID p_particles, RS::ParticlesMode p_m } void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) { - ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->adreno_3xx_compatibility, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead."); + ERR_FAIL_COND_MSG(GLES3::Config::get_singleton()->disable_particles_workaround, "Due to driver bugs, GPUParticles are not supported on Adreno 3XX devices. Please use CPUParticles instead."); Particles *particles = particles_owner.get_or_null(p_particles); ERR_FAIL_NULL(particles); @@ -131,7 +131,7 @@ void ParticlesStorage::particles_set_emitting(RID p_particles, bool p_emitting) } bool ParticlesStorage::particles_get_emitting(RID p_particles) { - if (GLES3::Config::get_singleton()->adreno_3xx_compatibility) { + if (GLES3::Config::get_singleton()->disable_particles_workaround) { return false; } diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 58dd659e86..d45f1d7a78 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -2934,7 +2934,7 @@ void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) { } if (selected || editor->is_selection_active()) { AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (!player->has_animation(SceneStringName(RESET)) || animation != player->get_animation(SceneStringName(RESET))) { + if ((!player->has_animation(SceneStringName(RESET)) || animation != player->get_animation(SceneStringName(RESET))) && editor->can_add_reset_key()) { menu->add_icon_item(get_editor_theme_icon(SNAME("Reload")), TTR("Add RESET Value(s)"), MENU_KEY_ADD_RESET); } @@ -4529,6 +4529,16 @@ bool AnimationTrackEditor::is_snap_enabled() const { return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL); } +bool AnimationTrackEditor::can_add_reset_key() const { + for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { + const Animation::TrackType track_type = animation->track_get_type(E.key.track); + if (track_type != Animation::TYPE_ANIMATION && track_type != Animation::TYPE_AUDIO && track_type != Animation::TYPE_METHOD) { + return true; + } + } + return false; +} + void AnimationTrackEditor::_update_tracks() { int selected = _get_track_selected(); @@ -6621,6 +6631,11 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) { for (const KeyValue<SelectedKey, KeyInfo> &E : selection) { const SelectedKey &sk = E.key; + const Animation::TrackType track_type = animation->track_get_type(E.key.track); + if (track_type == Animation::TYPE_ANIMATION || track_type == Animation::TYPE_AUDIO || track_type == Animation::TYPE_METHOD) { + continue; + } + // Only add one key per track. if (tracks_added.has(sk.track)) { continue; diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 09f751c8dd..1498a948f5 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -727,6 +727,7 @@ public: bool is_key_clipboard_active() const; bool is_moving_selection() const; bool is_snap_enabled() const; + bool can_add_reset_key() const; float get_moving_selection_offset() const; float snap_time(float p_value, bool p_relative = false); bool is_grouping_tracks(); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 33f460e23d..7f21bb9ca8 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -88,17 +88,17 @@ Size2 EditorProperty::get_minimum_size() const { if (keying) { Ref<Texture2D> key = get_editor_theme_icon(SNAME("Key")); - ms.width += key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + ms.width += key->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); } if (deletable) { Ref<Texture2D> key = get_editor_theme_icon(SNAME("Close")); - ms.width += key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + ms.width += key->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); } if (checkable) { Ref<Texture2D> check = get_theme_icon(SNAME("checked"), SNAME("CheckBox")); - ms.width += check->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("CheckBox")) + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + ms.width += check->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); } if (bottom_editor != nullptr && bottom_editor->is_visible()) { @@ -179,9 +179,9 @@ void EditorProperty::_notification(int p_what) { key = get_editor_theme_icon(SNAME("Key")); } - rect.size.x -= key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + rect.size.x -= key->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); if (is_layout_rtl()) { - rect.position.x += key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + rect.position.x += key->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); } if (no_children) { @@ -194,16 +194,27 @@ void EditorProperty::_notification(int p_what) { close = get_editor_theme_icon(SNAME("Close")); - rect.size.x -= close->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + rect.size.x -= close->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); if (is_layout_rtl()) { - rect.position.x += close->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + rect.position.x += close->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); } if (no_children) { text_size -= close->get_width() + 4 * EDSCALE; } } + + // Account for the space needed on the outer side + // when any of the icons are visible. + if (keying || deletable) { + int separation = get_theme_constant(SNAME("h_separation"), SNAME("Tree")); + rect.size.x -= separation; + + if (is_layout_rtl()) { + rect.position.x += separation; + } + } } //set children @@ -291,7 +302,7 @@ void EditorProperty::_notification(int p_what) { } else { draw_texture(checkbox, check_rect.position, color2); } - int check_ofs = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) + checkbox->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("CheckBox")); + int check_ofs = checkbox->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); ofs += check_ofs; text_limit -= check_ofs; } else { @@ -300,7 +311,7 @@ void EditorProperty::_notification(int p_what) { if (can_revert && !is_read_only()) { Ref<Texture2D> reload_icon = get_editor_theme_icon(SNAME("ReloadSmall")); - text_limit -= reload_icon->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2; + text_limit -= reload_icon->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); revert_rect = Rect2(ofs + text_limit, (size.height - reload_icon->get_height()) / 2, reload_icon->get_width(), reload_icon->get_height()); Color color2(1, 1, 1); @@ -320,7 +331,7 @@ void EditorProperty::_notification(int p_what) { if (!pin_hidden && pinned) { Ref<Texture2D> pinned_icon = get_editor_theme_icon(SNAME("Pin")); - int margin_w = get_theme_constant(SNAME("hseparator"), SNAME("Tree")) * 2; + int margin_w = get_theme_constant(SNAME("h_separation"), SNAME("Tree")); int total_icon_w = margin_w + pinned_icon->get_width(); int text_w = font->get_string_size(label, rtl ? HORIZONTAL_ALIGNMENT_RIGHT : HORIZONTAL_ALIGNMENT_LEFT, text_limit - total_icon_w, font_size).x; int y = (size.height - pinned_icon->get_height()) / 2; @@ -350,7 +361,7 @@ void EditorProperty::_notification(int p_what) { key = get_editor_theme_icon(SNAME("Key")); } - ofs -= key->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + ofs -= key->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); Color color2(1, 1, 1); if (keying_hover) { @@ -374,7 +385,7 @@ void EditorProperty::_notification(int p_what) { close = get_editor_theme_icon(SNAME("Close")); - ofs -= close->get_width() + get_theme_constant(SNAME("hseparator"), SNAME("Tree")); + ofs -= close->get_width() + get_theme_constant(SNAME("h_separation"), SNAME("Tree")); Color color2(1, 1, 1); if (delete_hover) { diff --git a/editor/gui/editor_object_selector.cpp b/editor/gui/editor_object_selector.cpp index 0985753430..434aef1419 100644 --- a/editor/gui/editor_object_selector.cpp +++ b/editor/gui/editor_object_selector.cpp @@ -239,6 +239,7 @@ EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) { current_object_label = memnew(Label); current_object_label->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS); current_object_label->set_h_size_flags(SIZE_EXPAND_FILL); + current_object_label->set_vertical_alignment(VERTICAL_ALIGNMENT_CENTER); current_object_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); main_hb->add_child(current_object_label); diff --git a/editor/icons/Key.svg b/editor/icons/Key.svg index fdf51fd72d..d0838b68cd 100644 --- a/editor/icons/Key.svg +++ b/editor/icons/Key.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 4v2h1v2h3V6h2.133a4 4 0 1 0 0-2zm10-1a2 2 0 0 1 0 4 2 2 0 0 1 0-4z" fill="#e0e0e0"/></svg> +<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path fill="#e0e0e0" d="M1 7v2h1v2h3V9h2.133a4 4 0 1 0 0-2zm10-1a2 2 0 0 1 0 4 2 2 0 0 1 0-4z"/></svg>
\ No newline at end of file diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp index a5717c3bb3..ccb4e4921b 100644 --- a/editor/plugins/path_2d_editor_plugin.cpp +++ b/editor/plugins/path_2d_editor_plugin.cpp @@ -155,15 +155,16 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } } + if (action != ACTION_NONE && mb->is_pressed() && mb->get_button_index() == MouseButton::RIGHT) { + _cancel_current_action(); + return true; + } + // Check for point creation. if (mb->is_pressed() && mb->get_button_index() == MouseButton::LEFT && ((mb->is_command_or_control_pressed() && mode == MODE_EDIT) || mode == MODE_CREATE)) { Ref<Curve2D> curve = node->get_curve(); curve->add_point(cpoint); - - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->create_action(TTR("Add Point to Curve")); - undo_redo->add_do_method(curve.ptr(), "add_point", cpoint); - undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count() - 1); + moving_from = cpoint; action = ACTION_MOVING_NEW_POINT; action_point = curve->get_point_count() - 1; @@ -235,9 +236,12 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) { } break; case ACTION_MOVING_NEW_POINT: { + undo_redo->create_action(TTR("Add Point to Curve")); + undo_redo->add_do_method(curve.ptr(), "add_point", cpoint); undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint); - undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); undo_redo->add_do_method(canvas_item_editor, "update_viewport"); + undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count() - 1); + undo_redo->add_undo_method(canvas_item_editor, "update_viewport"); undo_redo->commit_action(false); } break; @@ -447,6 +451,10 @@ void Path2DEditor::edit(Node *p_path2d) { canvas_item_editor = CanvasItemEditor::get_singleton(); } + if (action != ACTION_NONE) { + _cancel_current_action(); + } + if (p_path2d) { node = Object::cast_to<Path2D>(p_path2d); @@ -551,6 +559,38 @@ void Path2DEditor::_handle_option_pressed(int p_option) { } } +void Path2DEditor::_cancel_current_action() { + ERR_FAIL_NULL(node); + Ref<Curve2D> curve = node->get_curve(); + ERR_FAIL_COND(curve.is_null()); + + switch (action) { + case ACTION_MOVING_POINT: { + curve->set_point_position(action_point, moving_from); + } break; + + case ACTION_MOVING_NEW_POINT: { + curve->remove_point(curve->get_point_count() - 1); + } break; + + case ACTION_MOVING_IN: { + curve->set_point_in(action_point, moving_from); + curve->set_point_out(action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_out_length)); + } break; + + case ACTION_MOVING_OUT: { + curve->set_point_out(action_point, moving_from); + curve->set_point_in(action_point, mirror_handle_length ? -moving_from : (-moving_from.normalized() * orig_in_length)); + } break; + + default: { + } + } + + canvas_item_editor->update_viewport(); + action = ACTION_NONE; +} + void Path2DEditor::_confirm_clear_points() { if (!node || node->get_curve().is_null()) { return; @@ -598,14 +638,6 @@ void Path2DEditor::_restore_curve_points(Path2D *p_path2d, const PackedVector2Ar } Path2DEditor::Path2DEditor() { - canvas_item_editor = nullptr; - mirror_handle_angle = true; - mirror_handle_length = true; - on_edge = false; - - mode = MODE_EDIT; - action = ACTION_NONE; - curve_edit = memnew(Button); curve_edit->set_theme_type_variation("FlatButton"); curve_edit->set_toggle_mode(true); diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h index 7d1a64160b..a2857fddb7 100644 --- a/editor/plugins/path_2d_editor_plugin.h +++ b/editor/plugins/path_2d_editor_plugin.h @@ -57,7 +57,7 @@ class Path2DEditor : public HBoxContainer { MODE_CLEAR_POINTS, }; - Mode mode; + Mode mode = MODE_EDIT; Button *curve_clear_points = nullptr; Button *curve_close = nullptr; Button *curve_create = nullptr; @@ -68,9 +68,9 @@ class Path2DEditor : public HBoxContainer { ConfirmationDialog *clear_points_dialog = nullptr; - bool mirror_handle_angle; - bool mirror_handle_length; - bool on_edge; + bool mirror_handle_angle = true; + bool mirror_handle_length = true; + bool on_edge = false; enum HandleOption { HANDLE_OPTION_ANGLE, @@ -85,7 +85,7 @@ class Path2DEditor : public HBoxContainer { ACTION_MOVING_OUT, }; - Action action; + Action action = ACTION_NONE; int action_point = 0; Point2 moving_from; Point2 moving_screen_from; @@ -96,6 +96,7 @@ class Path2DEditor : public HBoxContainer { void _mode_selected(int p_mode); void _handle_option_pressed(int p_option); + void _cancel_current_action(); void _node_visibility_changed(); diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp index ae6ec0f702..d1da61e5fc 100644 --- a/editor/plugins/sprite_frames_editor_plugin.cpp +++ b/editor/plugins/sprite_frames_editor_plugin.cpp @@ -1476,8 +1476,8 @@ void SpriteFramesEditor::edit(Ref<SpriteFrames> p_frames) { _fetch_sprite_node(); // Fetch node after set frames. } -bool SpriteFramesEditor::is_editing() const { - return frames.is_valid(); +Ref<SpriteFrames> SpriteFramesEditor::get_sprite_frames() const { + return frames; } Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) { @@ -2337,7 +2337,11 @@ bool SpriteFramesEditorPlugin::handles(Object *p_object) const { if (animated_sprite_3d && *animated_sprite_3d->get_sprite_frames()) { return true; } - return !frames_editor->is_editing() && Object::cast_to<SpriteFrames>(p_object); + SpriteFrames *frames = Object::cast_to<SpriteFrames>(p_object); + if (frames && (frames_editor->get_sprite_frames().is_null() || frames_editor->get_sprite_frames() == frames)) { + return true; + } + return false; } void SpriteFramesEditorPlugin::make_visible(bool p_visible) { diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h index 0e26a793a7..9b6aaf98fe 100644 --- a/editor/plugins/sprite_frames_editor_plugin.h +++ b/editor/plugins/sprite_frames_editor_plugin.h @@ -269,7 +269,7 @@ protected: public: void edit(Ref<SpriteFrames> p_frames); - bool is_editing() const; + Ref<SpriteFrames> get_sprite_frames() const; SpriteFramesEditor(); }; diff --git a/main/main.cpp b/main/main.cpp index 44201522af..1cbd732747 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2896,7 +2896,7 @@ Error Main::setup2() { MAIN_PRINT("Main: Setup Logo"); -#if !defined(TOOLS_ENABLED) && (defined(WEB_ENABLED) || defined(ANDROID_ENABLED)) +#if !defined(TOOLS_ENABLED) && defined(WEB_ENABLED) bool show_logo = false; #else bool show_logo = true; diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index eebef3f969..ad00659257 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -212,11 +212,6 @@ static const char *android_perms[] = { static const char *MISMATCHED_VERSIONS_MESSAGE = "Android build version mismatch:\n| Template installed: %s\n| Requested version: %s\nPlease reinstall Android build template from 'Project' menu."; -static const char *SPLASH_IMAGE_EXPORT_PATH = "res/drawable-nodpi/splash.png"; -static const char *LEGACY_BUILD_SPLASH_IMAGE_EXPORT_PATH = "res/drawable-nodpi-v4/splash.png"; -static const char *SPLASH_BG_COLOR_PATH = "res/drawable-nodpi/splash_bg_color.png"; -static const char *LEGACY_BUILD_SPLASH_BG_COLOR_PATH = "res/drawable-nodpi-v4/splash_bg_color.png"; -static const char *SPLASH_CONFIG_PATH = "res/drawable/splash_drawable.xml"; static const char *GDEXTENSION_LIBS_PATH = "libs/gdextensionlibs.json"; static const int icon_densities_count = 6; @@ -1642,67 +1637,6 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n } } -String EditorExportPlatformAndroid::load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) { - bool scale_splash = GLOBAL_GET("application/boot_splash/fullsize"); - bool apply_filter = GLOBAL_GET("application/boot_splash/use_filter"); - bool show_splash_image = GLOBAL_GET("application/boot_splash/show_image"); - String project_splash_path = GLOBAL_GET("application/boot_splash/image"); - - // Setup the splash bg color. - bool bg_color_valid = false; - Color bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color", &bg_color_valid); - if (!bg_color_valid) { - bg_color = boot_splash_bg_color; - } - - if (show_splash_image) { - if (!project_splash_path.is_empty()) { - splash_image.instantiate(); - print_verbose("Loading splash image: " + project_splash_path); - const Error err = ImageLoader::load_image(project_splash_path, splash_image); - if (err) { - if (OS::get_singleton()->is_stdout_verbose()) { - print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")"); - } - splash_image.unref(); - } - } - } else { - splash_image.instantiate(); - splash_image->initialize_data(1, 1, false, Image::FORMAT_RGBA8); - splash_image->set_pixel(0, 0, bg_color); - } - - if (splash_image.is_null()) { - // Use the default - print_verbose("Using default splash image."); - splash_image = Ref<Image>(memnew(Image(boot_splash_png))); - } - - if (scale_splash) { - Size2 screen_size = Size2(GLOBAL_GET("display/window/size/viewport_width"), GLOBAL_GET("display/window/size/viewport_height")); - int width, height; - if (screen_size.width > screen_size.height) { - // scale horizontally - height = screen_size.height; - width = splash_image->get_width() * screen_size.height / splash_image->get_height(); - } else { - // scale vertically - width = screen_size.width; - height = splash_image->get_height() * screen_size.width / splash_image->get_width(); - } - splash_image->resize(width, height); - } - - print_verbose("Creating splash background color image."); - splash_bg_color_image.instantiate(); - splash_bg_color_image->initialize_data(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format()); - splash_bg_color_image->fill(bg_color); - - String processed_splash_config_xml = vformat(SPLASH_CONFIG_XML_CONTENT, bool_to_string(apply_filter)); - return processed_splash_config_xml; -} - void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) { String project_icon_path = GLOBAL_GET("application/config/icon"); @@ -1739,61 +1673,34 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> & } void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, - const String &processed_splash_config_xml, - const Ref<Image> &splash_image, - const Ref<Image> &splash_bg_color_image, - const Ref<Image> &main_image, - const Ref<Image> &foreground, - const Ref<Image> &background) { + const Ref<Image> &p_main_image, + const Ref<Image> &p_foreground, + const Ref<Image> &p_background) { String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset); - // Store the splash configuration - if (!processed_splash_config_xml.is_empty()) { - print_verbose("Storing processed splash configuration: " + String("\n") + processed_splash_config_xml); - store_string_at_path(gradle_build_dir.path_join(SPLASH_CONFIG_PATH), processed_splash_config_xml); - } - - // Store the splash image - if (splash_image.is_valid() && !splash_image->is_empty()) { - String splash_export_path = gradle_build_dir.path_join(SPLASH_IMAGE_EXPORT_PATH); - print_verbose("Storing splash image in " + splash_export_path); - Vector<uint8_t> data; - _load_image_data(splash_image, data); - store_file_at_path(splash_export_path, data); - } - - // Store the splash bg color image - if (splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) { - String splash_bg_color_path = gradle_build_dir.path_join(SPLASH_BG_COLOR_PATH); - print_verbose("Storing splash background image in " + splash_bg_color_path); - Vector<uint8_t> data; - _load_image_data(splash_bg_color_image, data); - store_file_at_path(splash_bg_color_path, data); - } - // Prepare images to be resized for the icons. If some image ends up being uninitialized, // the default image from the export template will be used. for (int i = 0; i < icon_densities_count; ++i) { - if (main_image.is_valid() && !main_image->is_empty()) { + if (p_main_image.is_valid() && !p_main_image->is_empty()) { print_verbose("Processing launcher icon for dimension " + itos(launcher_icons[i].dimensions) + " into " + launcher_icons[i].export_path); Vector<uint8_t> data; - _process_launcher_icons(launcher_icons[i].export_path, main_image, launcher_icons[i].dimensions, data); + _process_launcher_icons(launcher_icons[i].export_path, p_main_image, launcher_icons[i].dimensions, data); store_file_at_path(gradle_build_dir.path_join(launcher_icons[i].export_path), data); } - if (foreground.is_valid() && !foreground->is_empty()) { - print_verbose("Processing launcher adaptive icon foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path); + if (p_foreground.is_valid() && !p_foreground->is_empty()) { + print_verbose("Processing launcher adaptive icon p_foreground for dimension " + itos(launcher_adaptive_icon_foregrounds[i].dimensions) + " into " + launcher_adaptive_icon_foregrounds[i].export_path); Vector<uint8_t> data; - _process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, foreground, + _process_launcher_icons(launcher_adaptive_icon_foregrounds[i].export_path, p_foreground, launcher_adaptive_icon_foregrounds[i].dimensions, data); store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_foregrounds[i].export_path), data); } - if (background.is_valid() && !background->is_empty()) { - print_verbose("Processing launcher adaptive icon background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path); + if (p_background.is_valid() && !p_background->is_empty()) { + print_verbose("Processing launcher adaptive icon p_background for dimension " + itos(launcher_adaptive_icon_backgrounds[i].dimensions) + " into " + launcher_adaptive_icon_backgrounds[i].export_path); Vector<uint8_t> data; - _process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, background, + _process_launcher_icons(launcher_adaptive_icon_backgrounds[i].export_path, p_background, launcher_adaptive_icon_backgrounds[i].dimensions, data); store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data); } @@ -3093,10 +3000,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP print_verbose("- include filter: " + p_preset->get_include_filter()); print_verbose("- exclude filter: " + p_preset->get_exclude_filter()); - Ref<Image> splash_image; - Ref<Image> splash_bg_color_image; - String processed_splash_config_xml = load_splash_refs(splash_image, splash_bg_color_image); - Ref<Image> main_image; Ref<Image> foreground; Ref<Image> background; @@ -3172,7 +3075,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name.")); } // Copies the project icon files into the appropriate Gradle project directory. - _copy_icons_to_gradle_project(p_preset, processed_splash_config_xml, splash_image, splash_bg_color_image, main_image, foreground, background); + _copy_icons_to_gradle_project(p_preset, main_image, foreground, background); // Write an AndroidManifest.xml file into the Gradle project directory. _write_tmp_manifest(p_preset, p_give_internet, p_debug); @@ -3486,16 +3389,6 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP _fix_resources(p_preset, data); } - // Process the splash image - if ((file == SPLASH_IMAGE_EXPORT_PATH || file == LEGACY_BUILD_SPLASH_IMAGE_EXPORT_PATH) && splash_image.is_valid() && !splash_image->is_empty()) { - _load_image_data(splash_image, data); - } - - // Process the splash bg color image - if ((file == SPLASH_BG_COLOR_PATH || file == LEGACY_BUILD_SPLASH_BG_COLOR_PATH) && splash_bg_color_image.is_valid() && !splash_bg_color_image->is_empty()) { - _load_image_data(splash_bg_color_image, data); - } - if (file.ends_with(".png") && file.contains("mipmap")) { for (int i = 0; i < icon_densities_count; ++i) { if (main_image.is_valid() && !main_image->is_empty()) { diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 679afdc50f..97bbd0c7bc 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -39,18 +39,6 @@ #include "core/os/os.h" #include "editor/export/editor_export_platform.h" -const String SPLASH_CONFIG_XML_CONTENT = R"SPLASH(<?xml version="1.0" encoding="utf-8"?> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:drawable="@drawable/splash_bg_color" /> - <item> - <bitmap - android:gravity="center" - android:filter="%s" - android:src="@drawable/splash" /> - </item> -</layer-list> -)SPLASH"; - // Optional environment variables for defining confidential information. If any // of these is set, they will override the values set in the credentials file. const String ENV_ANDROID_KEYSTORE_DEBUG_PATH = "GODOT_ANDROID_KEYSTORE_DEBUG_PATH"; @@ -179,17 +167,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data); - String load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image); - void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background); void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, - const String &processed_splash_config_xml, - const Ref<Image> &splash_image, - const Ref<Image> &splash_bg_color_image, - const Ref<Image> &main_image, - const Ref<Image> &foreground, - const Ref<Image> &background); + const Ref<Image> &p_main_image, + const Ref<Image> &p_foreground, + const Ref<Image> &p_background); static void _create_editor_debug_keystore_if_needed(); diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index bde6a93c86..01d5d9ef92 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -32,6 +32,7 @@ configurations { dependencies { implementation "androidx.fragment:fragment:$versions.fragmentVersion" + implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion" if (rootProject.findProject(":lib")) { implementation project(":lib") diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index c404af34d8..01759a1b2f 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -11,7 +11,8 @@ ext.versions = [ nexusPublishVersion: '1.3.0', javaVersion : JavaVersion.VERSION_17, // Also update 'platform/android/detect.py#get_ndk_version()' when this is updated. - ndkVersion : '23.2.8568313' + ndkVersion : '23.2.8568313', + splashscreenVersion: '1.0.1' ] diff --git a/platform/android/java/app/res/drawable-nodpi/splash.png b/platform/android/java/app/res/drawable-nodpi/splash.png Binary files differdeleted file mode 100644 index 7bddd4325a..0000000000 --- a/platform/android/java/app/res/drawable-nodpi/splash.png +++ /dev/null diff --git a/platform/android/java/app/res/drawable-nodpi/splash_bg_color.png b/platform/android/java/app/res/drawable-nodpi/splash_bg_color.png Binary files differdeleted file mode 100644 index 004b6fd508..0000000000 --- a/platform/android/java/app/res/drawable-nodpi/splash_bg_color.png +++ /dev/null diff --git a/platform/android/java/app/res/drawable/splash_drawable.xml b/platform/android/java/app/res/drawable/splash_drawable.xml deleted file mode 100644 index 30627b998c..0000000000 --- a/platform/android/java/app/res/drawable/splash_drawable.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> - - <item android:drawable="@drawable/splash_bg_color" /> - - <item> - <bitmap - android:gravity="center" - android:filter="false" - android:src="@drawable/splash" /> - </item> -</layer-list> diff --git a/platform/android/java/app/res/values/themes.xml b/platform/android/java/app/res/values/themes.xml index d64b50ca45..3ab8401928 100644 --- a/platform/android/java/app/res/values/themes.xml +++ b/platform/android/java/app/res/values/themes.xml @@ -3,8 +3,17 @@ <style name="GodotAppMainTheme" parent="@android:style/Theme.Black.NoTitleBar"/> - <style name="GodotAppSplashTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen"> - <item name="android:windowBackground">@drawable/splash_drawable</item> - <item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item> + <style name="GodotAppSplashTheme" parent="Theme.SplashScreen"> + <!-- Set the splash screen background, animated icon, and animation + duration. --> + <item name="android:windowSplashScreenBackground">@mipmap/icon_background</item> + + <!-- Use windowSplashScreenAnimatedIcon to add a drawable or an animated + drawable. One of these is required. --> + <item name="windowSplashScreenAnimatedIcon">@mipmap/icon_foreground</item> + + <!-- Set the theme of the Activity that directly follows your splash + screen. This is required. --> + <item name="postSplashScreenTheme">@style/GodotAppMainTheme</item> </style> </resources> diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java index 9142d767b4..22e617f6e7 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -34,6 +34,8 @@ import org.godotengine.godot.GodotActivity; import android.os.Bundle; +import androidx.core.splashscreen.SplashScreen; + /** * Template activity for Godot Android builds. * Feel free to extend and modify this class for your custom logic. @@ -41,7 +43,7 @@ import android.os.Bundle; public class GodotApp extends GodotActivity { @Override public void onCreate(Bundle savedInstanceState) { - setTheme(R.style.GodotAppMainTheme); + SplashScreen.installSplashScreen(this); super.onCreate(savedInstanceState); } } diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index c5ef086152..55fe2a22fe 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -10,6 +10,8 @@ dependencies { implementation project(":lib") implementation "androidx.window:window:1.2.0" + implementation "androidx.core:core-splashscreen:$versions.splashscreenVersion" + implementation "androidx.constraintlayout:constraintlayout:2.1.4" } ext { @@ -92,6 +94,10 @@ android { targetSdkVersion versions.targetSdk missingDimensionStrategy 'products', 'editor' + manifestPlaceholders += [ + editorAppName: "Godot Editor 4", + editorBuildSuffix: "" + ] } base { @@ -124,11 +130,13 @@ android { dev { initWith debug applicationIdSuffix ".dev" + manifestPlaceholders += [editorBuildSuffix: " (dev)"] } debug { initWith release applicationIdSuffix ".debug" + manifestPlaceholders += [editorBuildSuffix: " (debug)"] signingConfig signingConfigs.debug } diff --git a/platform/android/java/editor/src/debug/res/values/strings.xml b/platform/android/java/editor/src/debug/res/values/strings.xml deleted file mode 100644 index 09ee2d77e1..0000000000 --- a/platform/android/java/editor/src/debug/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_editor_name_string">Godot Editor 4 (debug)</string> -</resources> diff --git a/platform/android/java/editor/src/dev/res/values/strings.xml b/platform/android/java/editor/src/dev/res/values/strings.xml deleted file mode 100644 index 215f2c7d0a..0000000000 --- a/platform/android/java/editor/src/dev/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_editor_name_string">Godot Editor 4 (dev)</string> -</resources> diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index f646ef3f51..c7d14a3f49 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -13,12 +13,15 @@ android:glEsVersion="0x00030000" android:required="true" /> - <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" + <uses-permission + android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" /> - <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" - android:maxSdkVersion="29"/> - <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" - android:maxSdkVersion="29"/> + <uses-permission + android:name="android.permission.WRITE_EXTERNAL_STORAGE" + android:maxSdkVersion="29" /> + <uses-permission + android:name="android.permission.READ_EXTERNAL_STORAGE" + android:maxSdkVersion="29" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.VIBRATE" /> @@ -26,39 +29,44 @@ <application android:allowBackup="false" android:icon="@mipmap/icon" - android:label="@string/godot_editor_name_string" - tools:ignore="GoogleAppIndexingWarning" - android:theme="@style/GodotEditorTheme" - android:requestLegacyExternalStorage="true"> + android:label="${editorAppName}${editorBuildSuffix}" + android:requestLegacyExternalStorage="true" + android:theme="@style/GodotEditorSplashScreenTheme" + tools:ignore="GoogleAppIndexingWarning"> + <profileable + android:shell="true" + android:enabled="true" + tools:targetApi="29" /> <activity android:name=".GodotEditor" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" + android:exported="true" android:launchMode="singleTask" - android:screenOrientation="userLandscape" - android:exported="true"> - <layout android:defaultHeight="@dimen/editor_default_window_height" - android:defaultWidth="@dimen/editor_default_window_width" /> + android:screenOrientation="userLandscape"> + <layout + android:defaultWidth="@dimen/editor_default_window_width" + android:defaultHeight="@dimen/editor_default_window_height" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - <activity android:name=".GodotGame" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" + android:exported="false" android:label="@string/godot_project_name_string" - android:process=":GodotGame" android:launchMode="singleTask" - android:exported="false" + android:process=":GodotGame" android:screenOrientation="userLandscape"> - <layout android:defaultHeight="@dimen/editor_default_window_height" - android:defaultWidth="@dimen/editor_default_window_width" /> + <layout + android:defaultWidth="@dimen/editor_default_window_width" + android:defaultHeight="@dimen/editor_default_window_height" /> </activity> - </application> </manifest> diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt index 52acd63674..5515347bd6 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt @@ -38,8 +38,10 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.* import android.util.Log +import android.view.View import android.widget.Toast import androidx.annotation.CallSuper +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.window.layout.WindowMetricsCalculator import org.godotengine.godot.GodotActivity import org.godotengine.godot.GodotLib @@ -88,8 +90,13 @@ open class GodotEditor : GodotActivity() { } private val commandLineParams = ArrayList<String>() + private val editorLoadingIndicator: View? by lazy { findViewById(R.id.editor_loading_indicator) } + + override fun getGodotAppLayout() = R.layout.godot_editor_layout override fun onCreate(savedInstanceState: Bundle?) { + installSplashScreen() + // We exclude certain permissions from the set we request at startup, as they'll be // requested on demand based on use-cases. PermissionsUtil.requestManifestPermissions(this, setOf(Manifest.permission.RECORD_AUDIO)) @@ -121,6 +128,14 @@ open class GodotEditor : GodotActivity() { } } + override fun onGodotMainLoopStarted() { + super.onGodotMainLoopStarted() + runOnUiThread { + // Hide the loading indicator + editorLoadingIndicator?.visibility = View.GONE + } + } + /** * Check for project permissions to enable */ diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt index aa4d02b5b2..8e4e089211 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt @@ -34,6 +34,9 @@ package org.godotengine.editor * Drives the 'run project' window of the Godot Editor. */ class GodotGame : GodotEditor() { + + override fun getGodotAppLayout() = org.godotengine.godot.R.layout.godot_app_layout + override fun overrideOrientationRequest() = false override fun enableLongPressGestures() = false diff --git a/platform/android/java/editor/src/main/res/layout/godot_editor_layout.xml b/platform/android/java/editor/src/main/res/layout/godot_editor_layout.xml new file mode 100644 index 0000000000..431a468f29 --- /dev/null +++ b/platform/android/java/editor/src/main/res/layout/godot_editor_layout.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <FrameLayout + android:id="@+id/godot_fragment_container" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <ProgressBar + style="@android:style/Widget.Holo.ProgressBar.Large" + android:id="@+id/editor_loading_indicator" + android:layout_width="80dp" + android:layout_height="80dp" + android:indeterminate="true" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintVertical_bias="0.80"/> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml index 216d02d9c7..909711ab18 100644 --- a/platform/android/java/editor/src/main/res/values/strings.xml +++ b/platform/android/java/editor/src/main/res/values/strings.xml @@ -1,6 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="godot_editor_name_string">Godot Editor 4</string> - <string name="denied_storage_permission_error_msg">Missing storage access permission!</string> </resources> diff --git a/platform/android/java/editor/src/main/res/values/themes.xml b/platform/android/java/editor/src/main/res/values/themes.xml index fda04d6dc7..2b352247db 100644 --- a/platform/android/java/editor/src/main/res/values/themes.xml +++ b/platform/android/java/editor/src/main/res/values/themes.xml @@ -2,4 +2,10 @@ <resources> <style name="GodotEditorTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen"> </style> + + <style name="GodotEditorSplashScreenTheme" parent="Theme.SplashScreen.IconBackground"> + <!-- Set the theme of the Activity that directly follows your splash + screen. This is required. --> + <item name="postSplashScreenTheme">@style/GodotEditorTheme</item> + </style> </resources> diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt index 7b8fad8952..4c5e857b7a 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt @@ -36,6 +36,7 @@ import android.content.pm.PackageManager import android.os.Bundle import android.util.Log import androidx.annotation.CallSuper +import androidx.annotation.LayoutRes import androidx.fragment.app.FragmentActivity import org.godotengine.godot.utils.PermissionsUtil import org.godotengine.godot.utils.ProcessPhoenix @@ -65,7 +66,7 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.godot_app_layout) + setContentView(getGodotAppLayout()) handleStartIntent(intent, true) @@ -80,6 +81,9 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { } } + @LayoutRes + protected open fun getGodotAppLayout() = R.layout.godot_app_layout + override fun onDestroy() { Log.v(TAG, "Destroying Godot app...") super.onDestroy() diff --git a/platform/linuxbsd/wayland/detect_prime_egl.cpp b/platform/linuxbsd/wayland/detect_prime_egl.cpp index 4c97a80039..e24c03c869 100644 --- a/platform/linuxbsd/wayland/detect_prime_egl.cpp +++ b/platform/linuxbsd/wayland/detect_prime_egl.cpp @@ -38,15 +38,6 @@ #include <stdlib.h> -#ifdef GLAD_ENABLED -#include "thirdparty/glad/glad/egl.h" -#include "thirdparty/glad/glad/gl.h" -#else -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <GL/glcorearb.h> -#endif // GLAD_ENABLED - #include <cstring> #include <sys/types.h> @@ -57,7 +48,7 @@ #undef glGetString // Runs inside a child. Exiting will not quit the engine. -void DetectPrimeEGL::create_context() { +void DetectPrimeEGL::create_context(EGLenum p_platform_enum) { #if defined(GLAD_ENABLED) if (!gladLoaderLoadEGL(nullptr)) { print_verbose("Unable to load EGL, GPU detection skipped."); @@ -65,7 +56,18 @@ void DetectPrimeEGL::create_context() { } #endif - EGLDisplay egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + EGLDisplay egl_display = EGL_NO_DISPLAY; + + if (GLAD_EGL_VERSION_1_5) { + egl_display = eglGetPlatformDisplay(p_platform_enum, nullptr, nullptr); + } else if (GLAD_EGL_EXT_platform_base) { +#ifdef EGL_EXT_platform_base + egl_display = eglGetPlatformDisplayEXT(p_platform_enum, nullptr, nullptr); +#endif + } else { + egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + } + EGLConfig egl_config; EGLContext egl_context = EGL_NO_CONTEXT; @@ -110,7 +112,7 @@ void DetectPrimeEGL::create_context() { eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context); } -int DetectPrimeEGL::detect_prime() { +int DetectPrimeEGL::detect_prime(EGLenum p_platform_enum) { pid_t p; int priorities[4] = {}; String vendors[4]; @@ -168,7 +170,7 @@ int DetectPrimeEGL::detect_prime() { setenv("DRI_PRIME", itos(i).utf8().ptr(), 1); - create_context(); + create_context(p_platform_enum); PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)eglGetProcAddress("glGetString"); const char *vendor = (const char *)glGetString(GL_VENDOR); diff --git a/platform/linuxbsd/wayland/detect_prime_egl.h b/platform/linuxbsd/wayland/detect_prime_egl.h index 26351b0dce..3391e020d8 100644 --- a/platform/linuxbsd/wayland/detect_prime_egl.h +++ b/platform/linuxbsd/wayland/detect_prime_egl.h @@ -34,6 +34,30 @@ #ifdef GLES3_ENABLED #ifdef EGL_ENABLED +#ifdef GLAD_ENABLED +#include "thirdparty/glad/glad/egl.h" +#include "thirdparty/glad/glad/gl.h" +#else +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GL/glcorearb.h> + +#define GLAD_EGL_VERSION_1_5 1 + +#ifdef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 1 +#endif + +#define KHRONOS_STATIC 1 +extern "C" EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list); +#undef KHRONOS_STATIC + +#endif // GLAD_ENABLED + +#ifndef EGL_EXT_platform_base +#define GLAD_EGL_EXT_platform_base 0 +#endif + class DetectPrimeEGL { private: struct Vendor { @@ -53,10 +77,10 @@ private: { nullptr, 0 } }; - static void create_context(); + static void create_context(EGLenum p_platform_enum); public: - static int detect_prime(); + static int detect_prime(EGLenum p_platform_enum); }; #endif // GLES3_ENABLED diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index aff83ddeee..c231dc0f90 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1342,7 +1342,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (prime_idx == -1) { print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); - prime_idx = DetectPrimeEGL::detect_prime(); + prime_idx = DetectPrimeEGL::detect_prime(EGL_PLATFORM_WAYLAND_KHR); } if (prime_idx) { @@ -1355,7 +1355,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (rendering_driver == "opengl3") { egl_manager = memnew(EGLManagerWayland); - if (egl_manager->initialize() != OK || egl_manager->open_display(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; @@ -1375,7 +1375,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (rendering_driver == "opengl3_es") { egl_manager = memnew(EGLManagerWaylandGLES); - if (egl_manager->initialize() != OK) { + if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK) { memdelete(egl_manager); egl_manager = nullptr; r_error = ERR_CANT_CREATE; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 01a4fbf96e..838beddac2 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -5595,52 +5595,57 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win HMODULE nt_lib = LoadLibraryW(L"ntdll.dll"); if (nt_lib) { - RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(nt_lib, "RtlGetVersion"); - if (RtlGetVersion) { - RtlGetVersion(&os_ver); + WineGetVersionPtr wine_get_version = (WineGetVersionPtr)GetProcAddress(nt_lib, "wine_get_version"); // Do not read Windows build number under Wine, it can be set to arbitrary value. + if (!wine_get_version) { + RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(nt_lib, "RtlGetVersion"); + if (RtlGetVersion) { + RtlGetVersion(&os_ver); + } } FreeLibrary(nt_lib); } - // Load UXTheme. - HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll"); - if (ux_theme_lib) { - ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132)); - GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95)); - GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96)); - GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98)); - if (os_ver.dwBuildNumber >= 17763) { - AllowDarkModeForAppPtr AllowDarkModeForApp = nullptr; - SetPreferredAppModePtr SetPreferredAppMode = nullptr; - FlushMenuThemesPtr FlushMenuThemes = nullptr; - if (os_ver.dwBuildNumber < 18362) { - AllowDarkModeForApp = (AllowDarkModeForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135)); - } else { - SetPreferredAppMode = (SetPreferredAppModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135)); - FlushMenuThemes = (FlushMenuThemesPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136)); - } - RefreshImmersiveColorPolicyStatePtr RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStatePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(104)); - if (ShouldAppsUseDarkMode) { - bool dark_mode = ShouldAppsUseDarkMode(); - if (SetPreferredAppMode) { - SetPreferredAppMode(dark_mode ? APPMODE_ALLOWDARK : APPMODE_DEFAULT); - } else if (AllowDarkModeForApp) { - AllowDarkModeForApp(dark_mode); + // Load UXTheme, available on Windows 10+ only. + if (os_ver.dwBuildNumber >= 10240) { + HMODULE ux_theme_lib = LoadLibraryW(L"uxtheme.dll"); + if (ux_theme_lib) { + ShouldAppsUseDarkMode = (ShouldAppsUseDarkModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(132)); + GetImmersiveColorFromColorSetEx = (GetImmersiveColorFromColorSetExPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(95)); + GetImmersiveColorTypeFromName = (GetImmersiveColorTypeFromNamePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(96)); + GetImmersiveUserColorSetPreference = (GetImmersiveUserColorSetPreferencePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(98)); + if (os_ver.dwBuildNumber >= 17763) { // Windows 10 Redstone 5 (1809)+ only. + AllowDarkModeForAppPtr AllowDarkModeForApp = nullptr; + SetPreferredAppModePtr SetPreferredAppMode = nullptr; + FlushMenuThemesPtr FlushMenuThemes = nullptr; + if (os_ver.dwBuildNumber < 18362) { // Windows 10 Redstone 5 (1809) and 19H1 (1903) only. + AllowDarkModeForApp = (AllowDarkModeForAppPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135)); + } else { // Windows 10 19H2 (1909)+ only. + SetPreferredAppMode = (SetPreferredAppModePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(135)); + FlushMenuThemes = (FlushMenuThemesPtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(136)); } - if (RefreshImmersiveColorPolicyState) { - RefreshImmersiveColorPolicyState(); - } - if (FlushMenuThemes) { - FlushMenuThemes(); + RefreshImmersiveColorPolicyStatePtr RefreshImmersiveColorPolicyState = (RefreshImmersiveColorPolicyStatePtr)GetProcAddress(ux_theme_lib, MAKEINTRESOURCEA(104)); + if (ShouldAppsUseDarkMode) { + bool dark_mode = ShouldAppsUseDarkMode(); + if (SetPreferredAppMode) { + SetPreferredAppMode(dark_mode ? APPMODE_ALLOWDARK : APPMODE_DEFAULT); + } else if (AllowDarkModeForApp) { + AllowDarkModeForApp(dark_mode); + } + if (RefreshImmersiveColorPolicyState) { + RefreshImmersiveColorPolicyState(); + } + if (FlushMenuThemes) { + FlushMenuThemes(); + } } } - } - ux_theme_available = ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference; - if (os_ver.dwBuildNumber >= 18363) { - dark_title_available = true; - if (os_ver.dwBuildNumber < 19041) { - use_legacy_dark_mode_before_20H1 = true; + ux_theme_available = ShouldAppsUseDarkMode && GetImmersiveColorFromColorSetEx && GetImmersiveColorTypeFromName && GetImmersiveUserColorSetPreference; + if (os_ver.dwBuildNumber >= 18363) { + dark_title_available = true; + if (os_ver.dwBuildNumber < 19041) { + use_legacy_dark_mode_before_20H1 = true; + } } } } diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 0f649b76d7..382f18c239 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -162,6 +162,7 @@ enum PreferredAppMode { APPMODE_MAX = 4 }; +typedef const char *(CDECL *WineGetVersionPtr)(void); typedef bool(WINAPI *ShouldAppsUseDarkModePtr)(); typedef DWORD(WINAPI *GetImmersiveColorFromColorSetExPtr)(UINT dwImmersiveColorSet, UINT dwImmersiveColorType, bool bIgnoreHighContrast, UINT dwHighContrastCacheMode); typedef int(WINAPI *GetImmersiveColorTypeFromNamePtr)(const WCHAR *name); diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 55ca5fc3ee..4e738216de 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -487,6 +487,8 @@ Size2 Button::_fit_icon_size(const Size2 &p_size) const { } Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Texture2D> p_icon) const { + // Do not include `_internal_margin`, it's already added in the `get_minimum_size` overrides. + Ref<TextParagraph> paragraph; if (p_text.is_empty()) { paragraph = text_buf; @@ -500,21 +502,6 @@ Size2 Button::get_minimum_size_for_text_and_icon(const String &p_text, Ref<Textu minsize.width = 0; } - float left_internal_margin_with_h_separation = _internal_margin[SIDE_LEFT]; - float right_internal_margin_with_h_separation = _internal_margin[SIDE_RIGHT]; - { // The width reserved for internal element in derived classes (and h_separation if needed). - - if (_internal_margin[SIDE_LEFT] > 0.0f) { - left_internal_margin_with_h_separation += theme_cache.h_separation; - } - - if (_internal_margin[SIDE_RIGHT] > 0.0f) { - right_internal_margin_with_h_separation += theme_cache.h_separation; - } - - minsize.width += left_internal_margin_with_h_separation + right_internal_margin_with_h_separation; // The size after the internal element is stripped. - } - if (!expand_icon && p_icon.is_valid()) { Size2 icon_size = _fit_icon_size(p_icon->get_size()); if (vertical_icon_alignment == VERTICAL_ALIGNMENT_CENTER) { diff --git a/scene/resources/2d/tile_set.cpp b/scene/resources/2d/tile_set.cpp index 6c3356a205..d124577d25 100644 --- a/scene/resources/2d/tile_set.cpp +++ b/scene/resources/2d/tile_set.cpp @@ -6489,18 +6489,16 @@ Ref<NavigationPolygon> TileData::get_navigation_polygon(int p_layer_id, bool p_f PackedVector2Array new_points = get_transformed_vertices(layer_tile_data.navigation_polygon->get_vertices(), p_flip_h, p_flip_v, p_transpose); transformed_polygon->set_vertices(new_points); + int num_polygons = layer_tile_data.navigation_polygon->get_polygon_count(); + for (int i = 0; i < num_polygons; ++i) { + transformed_polygon->add_polygon(layer_tile_data.navigation_polygon->get_polygon(i)); + } + for (int i = 0; i < layer_tile_data.navigation_polygon->get_outline_count(); i++) { PackedVector2Array new_outline = get_transformed_vertices(layer_tile_data.navigation_polygon->get_outline(i), p_flip_h, p_flip_v, p_transpose); transformed_polygon->add_outline(new_outline); } - PackedInt32Array indices; - indices.resize(new_points.size()); - int *w = indices.ptrw(); - for (int i = 0; i < new_points.size(); i++) { - w[i] = i; - } - transformed_polygon->add_polygon(indices); layer_tile_data.transformed_navigation_polygon[key] = transformed_polygon; return transformed_polygon; } else { diff --git a/tests/core/io/test_image.h b/tests/core/io/test_image.h index 7a0cbb13f9..1b51286a9f 100644 --- a/tests/core/io/test_image.h +++ b/tests/core/io/test_image.h @@ -78,8 +78,8 @@ TEST_CASE("[Image] Instantiation") { TEST_CASE("[Image] Saving and loading") { Ref<Image> image = memnew(Image(4, 4, false, Image::FORMAT_RGBA8)); - const String save_path_png = OS::get_singleton()->get_cache_path().path_join("image.png"); - const String save_path_exr = OS::get_singleton()->get_cache_path().path_join("image.exr"); + const String save_path_png = TestUtils::get_temp_path("image.png"); + const String save_path_exr = TestUtils::get_temp_path("image.exr"); // Save PNG Error err; diff --git a/tests/core/io/test_pck_packer.h b/tests/core/io/test_pck_packer.h index fc4534a949..7ef9451963 100644 --- a/tests/core/io/test_pck_packer.h +++ b/tests/core/io/test_pck_packer.h @@ -42,7 +42,7 @@ namespace TestPCKPacker { TEST_CASE("[PCKPacker] Pack an empty PCK file") { PCKPacker pck_packer; - const String output_pck_path = OS::get_singleton()->get_cache_path().path_join("output_empty.pck"); + const String output_pck_path = TestUtils::get_temp_path("output_empty.pck"); CHECK_MESSAGE( pck_packer.pck_start(output_pck_path) == OK, "Starting a PCK file should return an OK error code."); @@ -66,7 +66,7 @@ TEST_CASE("[PCKPacker] Pack an empty PCK file") { TEST_CASE("[PCKPacker] Pack empty with zero alignment invalid") { PCKPacker pck_packer; - const String output_pck_path = OS::get_singleton()->get_cache_path().path_join("output_empty.pck"); + const String output_pck_path = TestUtils::get_temp_path("output_empty.pck"); ERR_PRINT_OFF; CHECK_MESSAGE(pck_packer.pck_start(output_pck_path, 0) != OK, "PCK with zero alignment should fail."); ERR_PRINT_ON; @@ -74,7 +74,7 @@ TEST_CASE("[PCKPacker] Pack empty with zero alignment invalid") { TEST_CASE("[PCKPacker] Pack empty with invalid key") { PCKPacker pck_packer; - const String output_pck_path = OS::get_singleton()->get_cache_path().path_join("output_empty.pck"); + const String output_pck_path = TestUtils::get_temp_path("output_empty.pck"); ERR_PRINT_OFF; CHECK_MESSAGE(pck_packer.pck_start(output_pck_path, 32, "") != OK, "PCK with invalid key should fail."); ERR_PRINT_ON; @@ -82,7 +82,7 @@ TEST_CASE("[PCKPacker] Pack empty with invalid key") { TEST_CASE("[PCKPacker] Pack a PCK file with some files and directories") { PCKPacker pck_packer; - const String output_pck_path = OS::get_singleton()->get_cache_path().path_join("output_with_files.pck"); + const String output_pck_path = TestUtils::get_temp_path("output_with_files.pck"); CHECK_MESSAGE( pck_packer.pck_start(output_pck_path) == OK, "Starting a PCK file should return an OK error code."); diff --git a/tests/core/io/test_resource.h b/tests/core/io/test_resource.h index a83e7f88ba..cb1fa290b3 100644 --- a/tests/core/io/test_resource.h +++ b/tests/core/io/test_resource.h @@ -76,8 +76,8 @@ TEST_CASE("[Resource] Saving and loading") { Ref<Resource> child_resource = memnew(Resource); child_resource->set_name("I'm a child resource"); resource->set_meta("other_resource", child_resource); - const String save_path_binary = OS::get_singleton()->get_cache_path().path_join("resource.res"); - const String save_path_text = OS::get_singleton()->get_cache_path().path_join("resource.tres"); + const String save_path_binary = TestUtils::get_temp_path("resource.res"); + const String save_path_text = TestUtils::get_temp_path("resource.tres"); ResourceSaver::save(resource, save_path_binary); ResourceSaver::save(resource, save_path_text); @@ -123,8 +123,8 @@ TEST_CASE("[Resource] Breaking circular references on save") { resource_b->set_meta("next", resource_c); resource_c->set_meta("next", resource_b); - const String save_path_binary = OS::get_singleton()->get_cache_path().path_join("resource.res"); - const String save_path_text = OS::get_singleton()->get_cache_path().path_join("resource.tres"); + const String save_path_binary = TestUtils::get_temp_path("resource.res"); + const String save_path_text = TestUtils::get_temp_path("resource.tres"); ResourceSaver::save(resource_a, save_path_binary); // Suppress expected errors caused by the resources above being uncached. ERR_PRINT_OFF; diff --git a/tests/scene/test_audio_stream_wav.h b/tests/scene/test_audio_stream_wav.h index ed1697929e..e8f3c9e8f5 100644 --- a/tests/scene/test_audio_stream_wav.h +++ b/tests/scene/test_audio_stream_wav.h @@ -115,7 +115,7 @@ Vector<uint8_t> gen_pcm16_test(float wav_rate, int wav_count, bool stereo) { } void run_test(String file_name, AudioStreamWAV::Format data_format, bool stereo, float wav_rate, float wav_count) { - String save_path = OS::get_singleton()->get_cache_path().path_join(file_name); + String save_path = TestUtils::get_temp_path(file_name); Vector<uint8_t> test_data; if (data_format == AudioStreamWAV::FORMAT_8_BITS) { @@ -200,7 +200,7 @@ TEST_CASE("[AudioStreamWAV] Alternate mix rate") { } TEST_CASE("[AudioStreamWAV] save_to_wav() adds '.wav' file extension automatically") { - String save_path = OS::get_singleton()->get_cache_path().path_join("test_wav_extension"); + String save_path = TestUtils::get_temp_path("test_wav_extension"); Vector<uint8_t> test_data = gen_pcm8_test(WAV_RATE, WAV_COUNT, false); Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); stream->set_data(test_data); @@ -230,7 +230,7 @@ TEST_CASE("[AudioStreamWAV] Save empty file") { } TEST_CASE("[AudioStreamWAV] Saving IMA ADPCM is not supported") { - String save_path = OS::get_singleton()->get_cache_path().path_join("test_adpcm.wav"); + String save_path = TestUtils::get_temp_path("test_adpcm.wav"); Ref<AudioStreamWAV> stream = memnew(AudioStreamWAV); stream->set_format(AudioStreamWAV::FORMAT_IMA_ADPCM); ERR_PRINT_OFF; diff --git a/tests/scene/test_instance_placeholder.h b/tests/scene/test_instance_placeholder.h index 8e8cf7c9df..d915c5d961 100644 --- a/tests/scene/test_instance_placeholder.h +++ b/tests/scene/test_instance_placeholder.h @@ -350,7 +350,7 @@ TEST_CASE("[SceneTree][InstancePlaceholder] Instance a PackedScene containing an Error err = internal_scene->pack(internal); REQUIRE(err == OK); - const String internal_path = OS::get_singleton()->get_cache_path().path_join("instance_placeholder_test_internal.tscn"); + const String internal_path = TestUtils::get_temp_path("instance_placeholder_test_internal.tscn"); err = ResourceSaver::save(internal_scene, internal_path); REQUIRE(err == OK); @@ -379,7 +379,7 @@ TEST_CASE("[SceneTree][InstancePlaceholder] Instance a PackedScene containing an err = main_scene->pack(root); REQUIRE(err == OK); - const String main_path = OS::get_singleton()->get_cache_path().path_join("instance_placeholder_test_main.tscn"); + const String main_path = TestUtils::get_temp_path("instance_placeholder_test_main.tscn"); err = ResourceSaver::save(main_scene, main_path); REQUIRE(err == OK); @@ -439,7 +439,7 @@ TEST_CASE("[SceneTree][InstancePlaceholder] Instance a PackedScene containing an Error err = internal_scene->pack(internal); REQUIRE(err == OK); - const String internal_path = OS::get_singleton()->get_cache_path().path_join("instance_placeholder_test_internal_override.tscn"); + const String internal_path = TestUtils::get_temp_path("instance_placeholder_test_internal_override.tscn"); err = ResourceSaver::save(internal_scene, internal_path); REQUIRE(err == OK); @@ -480,7 +480,7 @@ TEST_CASE("[SceneTree][InstancePlaceholder] Instance a PackedScene containing an err = main_scene->pack(root); REQUIRE(err == OK); - const String main_path = OS::get_singleton()->get_cache_path().path_join("instance_placeholder_test_main_override.tscn"); + const String main_path = TestUtils::get_temp_path("instance_placeholder_test_main_override.tscn"); err = ResourceSaver::save(main_scene, main_path); REQUIRE(err == OK); diff --git a/tests/scene/test_node.h b/tests/scene/test_node.h index 2b14be76e2..93ef3fe728 100644 --- a/tests/scene/test_node.h +++ b/tests/scene/test_node.h @@ -518,7 +518,7 @@ TEST_CASE("[SceneTree][Node]Exported node checks") { ps.instantiate(); ps->pack(node); - String scene_path = OS::get_singleton()->get_cache_path().path_join("test_scene.tscn"); + String scene_path = TestUtils::get_temp_path("test_scene.tscn"); ps->set_path(scene_path); Node *root = memnew(Node); @@ -531,7 +531,7 @@ TEST_CASE("[SceneTree][Node]Exported node checks") { ps2.instantiate(); ps2->pack(root); - scene_path = OS::get_singleton()->get_cache_path().path_join("new_test_scene.tscn"); + scene_path = TestUtils::get_temp_path("new_test_scene.tscn"); ResourceSaver::save(ps2, scene_path); memdelete(root); diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp index cbd6d1ffbb..9d41e74020 100644 --- a/tests/test_utils.cpp +++ b/tests/test_utils.cpp @@ -30,6 +30,7 @@ #include "tests/test_utils.h" +#include "core/io/dir_access.h" #include "core/os/os.h" String TestUtils::get_data_path(const String &p_file) { @@ -40,3 +41,9 @@ String TestUtils::get_data_path(const String &p_file) { String TestUtils::get_executable_dir() { return OS::get_singleton()->get_executable_path().get_base_dir(); } + +String TestUtils::get_temp_path(const String &p_suffix) { + const String temp_base = OS::get_singleton()->get_cache_path().path_join("godot_test"); + DirAccess::make_dir_absolute(temp_base); // Ensure the directory exists. + return temp_base.path_join(p_suffix); +} diff --git a/tests/test_utils.h b/tests/test_utils.h index 48abe75c06..876a59ee7b 100644 --- a/tests/test_utils.h +++ b/tests/test_utils.h @@ -37,6 +37,7 @@ namespace TestUtils { String get_data_path(const String &p_file); String get_executable_dir(); +String get_temp_path(const String &p_suffix); } // namespace TestUtils #endif // TEST_UTILS_H diff --git a/thirdparty/glad/EGL/eglplatform.h b/thirdparty/glad/EGL/eglplatform.h index 99362a23de..6786afd90b 100644 --- a/thirdparty/glad/EGL/eglplatform.h +++ b/thirdparty/glad/EGL/eglplatform.h @@ -64,6 +64,12 @@ typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; +#elif defined(__QNX__) + +typedef khronos_uintptr_t EGLNativeDisplayType; +typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */ +typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */ + #elif defined(__EMSCRIPTEN__) typedef int EGLNativeDisplayType; diff --git a/thirdparty/glad/egl.c b/thirdparty/glad/egl.c index e120ea6b2c..c88d6c17cd 100644 --- a/thirdparty/glad/egl.c +++ b/thirdparty/glad/egl.c @@ -30,6 +30,7 @@ int GLAD_EGL_VERSION_1_3 = 0; int GLAD_EGL_VERSION_1_4 = 0; int GLAD_EGL_VERSION_1_5 = 0; int GLAD_EGL_ANDROID_blob_cache = 0; +int GLAD_EGL_EXT_platform_base = 0; int GLAD_EGL_KHR_platform_wayland = 0; int GLAD_EGL_KHR_platform_x11 = 0; @@ -46,7 +47,9 @@ PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer = PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface = NULL; PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface = NULL; PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface = NULL; +PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT = NULL; PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface = NULL; +PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT = NULL; PFNEGLCREATESYNCPROC glad_eglCreateSync = NULL; PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface = NULL; PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext = NULL; @@ -61,6 +64,7 @@ PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface = NULL; PFNEGLGETDISPLAYPROC glad_eglGetDisplay = NULL; PFNEGLGETERRORPROC glad_eglGetError = NULL; PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay = NULL; +PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT = NULL; PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress = NULL; PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib = NULL; PFNEGLINITIALIZEPROC glad_eglInitialize = NULL; @@ -145,6 +149,12 @@ static void glad_egl_load_EGL_ANDROID_blob_cache( GLADuserptrloadfunc load, void if(!GLAD_EGL_ANDROID_blob_cache) return; glad_eglSetBlobCacheFuncsANDROID = (PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) load(userptr, "eglSetBlobCacheFuncsANDROID"); } +static void glad_egl_load_EGL_EXT_platform_base( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_platform_base) return; + glad_eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) load(userptr, "eglCreatePlatformPixmapSurfaceEXT"); + glad_eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) load(userptr, "eglCreatePlatformWindowSurfaceEXT"); + glad_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) load(userptr, "eglGetPlatformDisplayEXT"); +} @@ -183,6 +193,7 @@ static int glad_egl_find_extensions_egl(EGLDisplay display) { if (!glad_egl_get_extensions(display, &extensions)) return 0; GLAD_EGL_ANDROID_blob_cache = glad_egl_has_extension(extensions, "EGL_ANDROID_blob_cache"); + GLAD_EGL_EXT_platform_base = glad_egl_has_extension(extensions, "EGL_EXT_platform_base"); GLAD_EGL_KHR_platform_wayland = glad_egl_has_extension(extensions, "EGL_KHR_platform_wayland"); GLAD_EGL_KHR_platform_x11 = glad_egl_has_extension(extensions, "EGL_KHR_platform_x11"); @@ -248,6 +259,7 @@ int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userp if (!glad_egl_find_extensions_egl(display)) return 0; glad_egl_load_EGL_ANDROID_blob_cache(load, userptr); + glad_egl_load_EGL_EXT_platform_base(load, userptr); return version; diff --git a/thirdparty/glad/glad/egl.h b/thirdparty/glad/glad/egl.h index 1bf35c1404..8e03362f23 100644 --- a/thirdparty/glad/glad/egl.h +++ b/thirdparty/glad/glad/egl.h @@ -1,11 +1,11 @@ /** - * Loader generated by glad 2.0.3 on Fri Feb 3 07:06:48 2023 + * Loader generated by glad 2.0.6 on Sat Jun 1 18:07:46 2024 * * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: egl - * Extensions: 3 + * Extensions: 4 * * APIs: * - egl=1.5 @@ -19,10 +19,10 @@ * - ON_DEMAND = False * * Commandline: - * --api='egl=1.5' --extensions='EGL_ANDROID_blob_cache,EGL_KHR_platform_wayland,EGL_KHR_platform_x11' c --loader + * --api='egl=1.5' --extensions='EGL_ANDROID_blob_cache,EGL_EXT_platform_base,EGL_KHR_platform_wayland,EGL_KHR_platform_x11' c --loader * * Online: - * http://glad.sh/#api=egl%3D1.5&extensions=EGL_ANDROID_blob_cache%2CEGL_KHR_platform_wayland%2CEGL_KHR_platform_x11&generator=c&options=LOADER + * http://glad.sh/#api=egl%3D1.5&extensions=EGL_ANDROID_blob_cache%2CEGL_EXT_platform_base%2CEGL_KHR_platform_wayland%2CEGL_KHR_platform_x11&generator=c&options=LOADER * */ @@ -141,7 +141,7 @@ extern "C" { #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.3" +#define GLAD_GENERATOR_VERSION "2.0.6" typedef void (*GLADapiproc)(void); @@ -399,6 +399,8 @@ GLAD_API_CALL int GLAD_EGL_VERSION_1_4; GLAD_API_CALL int GLAD_EGL_VERSION_1_5; #define EGL_ANDROID_blob_cache 1 GLAD_API_CALL int GLAD_EGL_ANDROID_blob_cache; +#define EGL_EXT_platform_base 1 +GLAD_API_CALL int GLAD_EGL_EXT_platform_base; #define EGL_KHR_platform_wayland 1 GLAD_API_CALL int GLAD_EGL_KHR_platform_wayland; #define EGL_KHR_platform_x11 1 @@ -416,7 +418,9 @@ typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDi typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list); typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx); @@ -431,6 +435,7 @@ typedef EGLSurface (GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw); typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id); typedef EGLint (GLAD_API_PTR *PFNEGLGETERRORPROC)(void); typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void * native_display, const EGLAttrib * attrib_list); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void * native_display, const EGLint * attrib_list); typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char * procname); typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); typedef EGLBoolean (GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint * major, EGLint * minor); @@ -473,8 +478,12 @@ GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface; #define eglCreatePixmapSurface glad_eglCreatePixmapSurface GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface; #define eglCreatePlatformPixmapSurface glad_eglCreatePlatformPixmapSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT; +#define eglCreatePlatformPixmapSurfaceEXT glad_eglCreatePlatformPixmapSurfaceEXT GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; #define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT; +#define eglCreatePlatformWindowSurfaceEXT glad_eglCreatePlatformWindowSurfaceEXT GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; #define eglCreateSync glad_eglCreateSync GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface; @@ -503,6 +512,8 @@ GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError; #define eglGetError glad_eglGetError GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay; #define eglGetPlatformDisplay glad_eglGetPlatformDisplay +GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT; +#define eglGetPlatformDisplayEXT glad_eglGetPlatformDisplayEXT GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; #define eglGetProcAddress glad_eglGetProcAddress GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; |
