diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index e978f9c8203..d966710cdde 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -74,7 +74,7 @@ jobs: artifact: false cache-limit: 5 - - name: Template w/ Mono (target=template_release, tests=yes) + - name: Template w/ Mono, release (target=template_release, tests=yes) cache-name: linux-template-mono target: template_release sconsflags: module_mono_enabled=yes @@ -84,6 +84,16 @@ jobs: artifact: true cache-limit: 1 + - name: Template w/ Mono, debug (target=template_debug, tests=yes) + cache-name: linux-template-mono-debug + target: template_debug + sconsflags: module_mono_enabled=yes + bin: ./bin/godot.linuxbsd.template_debug.x86_64.mono + build-mono: false + tests: true + artifact: true + cache-limit: 1 + - name: Minimal template (target=template_release, tests=yes, everything disabled) cache-name: linux-template-minimal target: template_release diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 7651b61c5be..cf32dd313ff 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -535,7 +535,7 @@ Returns [code]true[/code] if the node is present in the [SceneTree], its [member visible] property is [code]true[/code] and all its ancestors are also visible. If any ancestor is hidden, this node will not be visible in the scene tree, and is therefore not drawn (see [method _draw]). Visibility is checked only in parent nodes that inherit from [CanvasItem], [CanvasLayer], and [Window]. If the parent is of any other type (such as [Node], [AnimationPlayer], or [Node3D]), it is assumed to be visible. - [b]Note:[/b] This method does not take [member visibility_layer] into account, so even if this method returns [code]true[/code] the node might end up not being rendered. + [b]Note:[/b] This method does not take [member visibility_layer] into account, so even if this method returns [code]true[/code], the node might end up not being rendered. diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml index ba0272b02fe..d092fd50a99 100644 --- a/doc/classes/Node3D.xml +++ b/doc/classes/Node3D.xml @@ -117,6 +117,8 @@ Returns [code]true[/code] if the node is present in the [SceneTree], its [member visible] property is [code]true[/code] and all its ancestors are also visible. If any ancestor is hidden, this node will not be visible in the scene tree. + Visibility is checked only in parent nodes that inherit from [Node3D]. If the parent is of any other type (such as [Node], [AnimationPlayer], or [Node2D]), it is assumed to be visible. + [b]Note:[/b] This method does not take [member VisualInstance3D.layers] into account, so even if this method returns [code]true[/code], the node might end up not being rendered. diff --git a/drivers/metal/metal_device_properties.h b/drivers/metal/metal_device_properties.h index 815af367648..853ddcaebc5 100644 --- a/drivers/metal/metal_device_properties.h +++ b/drivers/metal/metal_device_properties.h @@ -93,6 +93,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) MetalFeatures { bool needs_arg_encoders = true; bool metal_fx_spatial = false; /**< If true, Metal FX spatial functions are supported. */ bool metal_fx_temporal = false; /**< If true, Metal FX temporal functions are supported. */ + bool supports_gpu_address = false; /**< If true, referencing a GPU address in a shader is supported. */ }; struct MetalLimits { diff --git a/drivers/metal/metal_device_properties.mm b/drivers/metal/metal_device_properties.mm index d4d6d6bcd32..21553f7173d 100644 --- a/drivers/metal/metal_device_properties.mm +++ b/drivers/metal/metal_device_properties.mm @@ -99,6 +99,10 @@ void MetalDeviceProperties::init_features(id p_device) { features.supports32BitMSAA = p_device.supports32BitMSAA; } + if (@available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) { + features.supports_gpu_address = true; + } + features.hostMemoryPageSize = sysconf(_SC_PAGESIZE); for (SampleCount sc = SampleCount1; sc <= SampleCount64; sc <<= 1) { diff --git a/drivers/metal/metal_objects.h b/drivers/metal/metal_objects.h index 4dc9b6d3f3d..67bb15a30fb 100644 --- a/drivers/metal/metal_objects.h +++ b/drivers/metal/metal_objects.h @@ -65,7 +65,6 @@ #import #import #import -#import // These types can be used in Vector and other containers that use // pointer operations not supported by ARC. @@ -563,7 +562,7 @@ struct API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) BindingInfo { MTLBindingAccess access = MTLBindingAccessReadOnly; MTLResourceUsage usage = 0; MTLTextureType textureType = MTLTextureType2D; - spv::ImageFormat imageFormat = spv::ImageFormatUnknown; + int imageFormat = 0; uint32_t arrayLength = 0; bool isMultisampled = false; diff --git a/drivers/metal/rendering_device_driver_metal.mm b/drivers/metal/rendering_device_driver_metal.mm index 2e32e99c2eb..d66064249ac 100644 --- a/drivers/metal/rendering_device_driver_metal.mm +++ b/drivers/metal/rendering_device_driver_metal.mm @@ -164,6 +164,9 @@ uint64_t RenderingDeviceDriverMetal::buffer_get_device_address(BufferID p_buffer id obj = rid::get(p_buffer); return obj.gpuAddress; } else { +#if DEV_ENABLED + WARN_PRINT_ONCE("buffer_get_device_address is not supported on this OS version."); +#endif return 0; } } @@ -355,7 +358,7 @@ RDD::TextureID RenderingDeviceDriverMetal::texture_create(const TextureFormat &p // Check if it is a linear format for atomic operations and therefore needs a buffer, // as generally Metal does not support atomic operations on textures. - bool needs_buffer = is_linear || (p_format.array_layers == 1 && p_format.mipmaps == 1 && p_format.texture_type == TEXTURE_TYPE_2D && flags::any(p_format.usage_bits, TEXTURE_USAGE_STORAGE_BIT) && (p_format.format == DATA_FORMAT_R32_UINT || p_format.format == DATA_FORMAT_R32_SINT)); + bool needs_buffer = is_linear || (p_format.array_layers == 1 && p_format.mipmaps == 1 && p_format.texture_type == TEXTURE_TYPE_2D && flags::any(p_format.usage_bits, TEXTURE_USAGE_STORAGE_BIT) && (p_format.format == DATA_FORMAT_R32_UINT || p_format.format == DATA_FORMAT_R32_SINT || p_format.format == DATA_FORMAT_R32G32_UINT || p_format.format == DATA_FORMAT_R32G32_SINT)); id obj = nil; if (needs_buffer) { @@ -2033,10 +2036,6 @@ Vector RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec CompilerMSL::Options msl_options{}; msl_options.set_msl_version(version_major, version_minor); - if (version_major == 3 && version_minor >= 1) { - // TODO(sgc): Restrict to Metal 3.0 for now, until bugs in SPIRV-cross image atomics are resolved. - msl_options.set_msl_version(3, 0); - } bin_data.msl_version = msl_options.msl_version; #if TARGET_OS_OSX msl_options.platform = CompilerMSL::Options::macOS; @@ -2063,9 +2062,9 @@ Vector RenderingDeviceDriverMetal::shader_compile_binary_from_spirv(Vec msl_options.argument_buffers = false; bin_data.set_uses_argument_buffers(false); } - - msl_options.force_active_argument_buffer_resources = true; // Same as MoltenVK when using argument buffers. - // msl_options.pad_argument_buffer_resources = true; // Same as MoltenVK when using argument buffers. + msl_options.force_active_argument_buffer_resources = true; + // We can't use this, as we have to add the descriptor sets via compiler.add_msl_resource_binding. + // msl_options.pad_argument_buffer_resources = true; msl_options.texture_buffer_native = true; // Enable texture buffer support. msl_options.use_framebuffer_fetch_subpasses = false; msl_options.pad_fragment_output_components = true; @@ -4036,7 +4035,7 @@ bool RenderingDeviceDriverMetal::has_feature(Features p_feature) { case SUPPORTS_FRAGMENT_SHADER_WITH_ONLY_SIDE_EFFECTS: return true; case SUPPORTS_BUFFER_DEVICE_ADDRESS: - return false; + return device_properties->features.supports_gpu_address; case SUPPORTS_METALFX_SPATIAL: return device_properties->features.metal_fx_spatial; case SUPPORTS_METALFX_TEMPORAL: diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index a4224db1c3d..da31447b561 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -605,7 +605,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int file_popup->add_separator(); file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_LIBRARY); Rect2 pos = tree->get_item_rect(p_item, 1, 0); - Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll(); + Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)); file_popup->popup(Rect2(popup_pos, Size2())); file_dialog_animation = StringName(); @@ -645,7 +645,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int file_popup->add_separator(); file_popup->add_item(TTR("Open in Inspector"), FILE_MENU_EDIT_ANIMATION); Rect2 pos = tree->get_item_rect(p_item, 1, 0); - Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)) - tree->get_scroll(); + Vector2 popup_pos = tree->get_screen_transform().xform(pos.position + Vector2(0, pos.size.height)); file_popup->popup(Rect2(popup_pos, Size2())); file_dialog_animation = anim_name; diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 4256e74619a..a58659f29b4 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -623,7 +623,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no return; } xform = vp->get_popup_base_transform(); - if (!vp->get_visible_rect().has_point(xform.xform_inv(p_pos))) { + if (!vp->get_visible_rect().has_point(xform.affine_inverse().xform(p_pos))) { return; } } @@ -726,7 +726,7 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n return; } xform = vp->get_popup_base_transform(); - if (!vp->get_visible_rect().intersects(xform.xform_inv(p_rect))) { + if (!vp->get_visible_rect().intersects(xform.affine_inverse().xform(p_rect))) { return; } } diff --git a/editor/window_wrapper.cpp b/editor/window_wrapper.cpp index a680dd79c67..4d82df70db9 100644 --- a/editor/window_wrapper.cpp +++ b/editor/window_wrapper.cpp @@ -261,6 +261,11 @@ void WindowWrapper::restore_window_from_saved_position(const Rect2 p_window_rect window_rect = Rect2i(window_rect.position * screen_ratio, window_rect.size * screen_ratio); window_rect.position += real_screen_rect.position; + // Make sure to restore the window if the user minimized it the last time it was displayed. + if (window->get_mode() == Window::MODE_MINIMIZED) { + window->set_mode(Window::MODE_WINDOWED); + } + // All good, restore the window. window->set_current_screen(p_screen); if (window->is_visible()) { diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 2383401630c..8ff0c63bd45 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1075,26 +1075,6 @@ void GDScript::_bind_methods() { ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new")); } -void GDScript::set_path_cache(const String &p_path) { - if (ResourceCache::has(p_path)) { - set_path(p_path, true); - return; - } - - if (is_root_script()) { - Script::set_path_cache(p_path); - } - - String old_path = path; - path = p_path; - path_valid = true; - GDScriptCache::move_script(old_path, p_path); - - for (KeyValue> &kv : subclasses) { - kv.value->set_path_cache(p_path); - } -} - void GDScript::set_path(const String &p_path, bool p_take_over) { if (is_root_script()) { Script::set_path(p_path, p_take_over); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 9e96b883349..fa141d65ac5 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -309,7 +309,6 @@ public: virtual Error reload(bool p_keep_state = false) override; - virtual void set_path_cache(const String &p_path) override; virtual void set_path(const String &p_path, bool p_take_over = false) override; String get_script_path() const; Error load_source_code(const String &p_path); diff --git a/modules/gdscript/gdscript_cache.cpp b/modules/gdscript/gdscript_cache.cpp index c9a5f26c82b..90af67ccd60 100644 --- a/modules/gdscript/gdscript_cache.cpp +++ b/modules/gdscript/gdscript_cache.cpp @@ -312,7 +312,7 @@ Ref GDScriptCache::get_shallow_script(const String &p_path, Error &r_e Ref script; script.instantiate(); - script->set_path_cache(p_path); + script->set_path(p_path, true); if (remapped_path.get_extension().to_lower() == "gdc") { Vector buffer = get_binary_tokens(remapped_path); if (buffer.is_empty()) { @@ -360,7 +360,6 @@ Ref GDScriptCache::get_full_script(const String &p_path, Error &r_erro return script; } } - script->set_path(p_path, true); const String remapped_path = ResourceLoader::path_remap(p_path); diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl index ea7044c5710..9c05b42e8e7 100644 --- a/modules/lightmapper_rd/lm_compute.glsl +++ b/modules/lightmapper_rd/lm_compute.glsl @@ -648,7 +648,7 @@ void trace_direct_light(vec3 p_position, vec3 p_normal, uint p_light_index, bool } r_shadow = penumbra; - r_light = light_data.color * light_data.energy * attenuation * penumbra * penumbra_color; + r_light = light_data.energy * attenuation * penumbra * penumbra_color; } #endif diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 2cd2afe1a9e..51db84fde02 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1377,8 +1377,6 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { } if (desktop_valid) { - use_simple_method = false; - // Handle bad window errors silently because there's no other way to check // that one of the windows has been destroyed in the meantime. int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&bad_window_error_handler); @@ -1406,6 +1404,8 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const { } } if (!g_bad_window && strut_found && (format == 32) && (strut_len >= 4) && strut_data) { + use_simple_method = false; + long *struts = (long *)strut_data; long left = struts[0]; @@ -4767,6 +4767,13 @@ void DisplayServerX11::process_events() { // Have we failed to set fullscreen while the window was unmapped? _validate_mode_on_map(window_id); + + // On KDE Plasma, when the parent window of an embedded process is restored after being minimized, + // only the embedded window receives the Map notification, causing it to + // appear without its parent. + if (wd.embed_parent) { + XMapWindow(x11_display, wd.embed_parent); + } } break; case Expose: { diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index aa449beb1b9..76cb24867a9 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -597,7 +597,7 @@ void CPUParticles2D::_validate_property(PropertyInfo &p_property) const { } if (p_property.name == "seed" && !use_fixed_seed) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; + p_property.usage = PROPERTY_USAGE_NONE; } } @@ -1392,6 +1392,8 @@ void CPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX); BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); + ADD_PROPERTY_DEFAULT("seed", 0); + //////////////////////////////// ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles2D::set_direction); @@ -1561,6 +1563,7 @@ CPUParticles2D::CPUParticles2D() { set_emitting(true); set_amount(8); set_use_local_coordinates(false); + set_seed(Math::rand()); rng.instantiate(); diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp index 23e90582809..81c9aa82dd4 100644 --- a/scene/2d/gpu_particles_2d.cpp +++ b/scene/2d/gpu_particles_2d.cpp @@ -408,7 +408,7 @@ Ref GPUParticles2D::get_texture() const { void GPUParticles2D::_validate_property(PropertyInfo &p_property) const { if (p_property.name == "seed" && !use_fixed_seed) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; + p_property.usage = PROPERTY_USAGE_NONE; } if (p_property.name == "emitting") { p_property.hint = one_shot ? PROPERTY_HINT_ONESHOT : PROPERTY_HINT_NONE; @@ -899,6 +899,8 @@ void GPUParticles2D::_bind_methods() { BIND_ENUM_CONSTANT(EMIT_FLAG_VELOCITY); BIND_ENUM_CONSTANT(EMIT_FLAG_COLOR); BIND_ENUM_CONSTANT(EMIT_FLAG_CUSTOM); + + ADD_PROPERTY_DEFAULT("seed", 0); } GPUParticles2D::GPUParticles2D() { @@ -912,8 +914,8 @@ GPUParticles2D::GPUParticles2D() { one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); set_one_shot(false); + set_seed(Math::rand()); set_use_fixed_seed(false); - set_seed(0); set_amount(8); set_amount_ratio(1.0); set_lifetime(1); diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp index f150e07bcaa..0f4c887652e 100644 --- a/scene/3d/cpu_particles_3d.cpp +++ b/scene/3d/cpu_particles_3d.cpp @@ -612,7 +612,7 @@ void CPUParticles3D::_validate_property(PropertyInfo &p_property) const { } if (p_property.name == "seed" && !use_fixed_seed) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; + p_property.usage = PROPERTY_USAGE_NONE; } } @@ -1564,6 +1564,8 @@ void CPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME); BIND_ENUM_CONSTANT(DRAW_ORDER_VIEW_DEPTH); + ADD_PROPERTY_DEFAULT("seed", 0); + //////////////////////////////// ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles3D::set_direction); @@ -1764,6 +1766,7 @@ CPUParticles3D::CPUParticles3D() { set_emitting(true); set_amount(8); + set_seed(Math::rand()); rng.instantiate(); diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp index db2d2f41902..2d9435ce4a9 100644 --- a/scene/3d/gpu_particles_3d.cpp +++ b/scene/3d/gpu_particles_3d.cpp @@ -464,7 +464,7 @@ void GPUParticles3D::_validate_property(PropertyInfo &p_property) const { } } if (p_property.name == "seed" && !use_fixed_seed) { - p_property.usage = PROPERTY_USAGE_NO_EDITOR; + p_property.usage = PROPERTY_USAGE_NONE; } } @@ -868,6 +868,8 @@ void GPUParticles3D::_bind_methods() { BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD); BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Y_TO_VELOCITY); BIND_ENUM_CONSTANT(TRANSFORM_ALIGN_Z_BILLBOARD_Y_TO_VELOCITY); + + ADD_PROPERTY_DEFAULT("seed", 0); } GPUParticles3D::GPUParticles3D() { @@ -877,6 +879,7 @@ GPUParticles3D::GPUParticles3D() { one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); set_one_shot(false); + set_seed(Math::rand()); set_amount_ratio(1.0); set_amount(8); set_lifetime(1); @@ -895,7 +898,6 @@ GPUParticles3D::GPUParticles3D() { set_collision_base_size(collision_base_size); set_transform_align(TRANSFORM_ALIGN_DISABLED); set_use_fixed_seed(false); - set_seed(0); } GPUParticles3D::~GPUParticles3D() { diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h index 1b3d7f236e3..36a391ebdbd 100644 --- a/scene/animation/animation_blend_tree.h +++ b/scene/animation/animation_blend_tree.h @@ -410,7 +410,7 @@ class AnimationNodeBlendTree : public AnimationRootNode { Vector connections; }; - AHashMap nodes; + RBMap nodes; Vector2 graph_offset; diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h index d5b1d4ea460..5ac24b49857 100644 --- a/scene/animation/animation_tree.h +++ b/scene/animation/animation_tree.h @@ -306,8 +306,8 @@ private: uint64_t last_pass = 0; real_t activity = 0.0; }; - mutable AHashMap> input_activity_map; - mutable AHashMap *> input_activity_map_get; + mutable HashMap> input_activity_map; + mutable HashMap *> input_activity_map_get; NodePath animation_player; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 7e9df9412fb..329c6f3da31 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -5208,10 +5208,12 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const { } int ofs = get_item_offset(p_item); - int height = compute_item_height(p_item); + int height = compute_item_height(p_item) + theme_cache.v_separation; Rect2 r; - r.position.y = ofs; + r.position.y = ofs - theme_cache.offset.y + theme_cache.panel_style->get_offset().y; r.size.height = height; + bool rtl = is_layout_rtl(); + const Rect2 content_rect = _get_content_rect(); if (p_column == -1) { r.position.x = 0; @@ -5221,18 +5223,45 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column, int p_button) const { for (int i = 0; i < p_column; i++) { accum += get_column_width(i); } - r.position.x = accum; + r.position.x = (rtl) ? get_size().x - (accum - theme_cache.offset.x) - get_column_width(p_column) - theme_cache.panel_style->get_margin(SIDE_LEFT) : accum - theme_cache.offset.x + theme_cache.panel_style->get_margin(SIDE_LEFT); r.size.x = get_column_width(p_column); if (p_button != -1) { + // RTL direction support for button rect is different due to buttons not + // having same behavior as they do in LTR when tree is scrolled. const TreeItem::Cell &c = p_item->cells[p_column]; - Vector2 ofst = Vector2(r.position.x + r.size.x, r.position.y); + Vector2 ofst = Vector2(r.position.x + r.size.x + theme_cache.button_margin, r.position.y); + + // Compute total width of buttons block including spacings. + int buttons_width = 0; for (int j = c.buttons.size() - 1; j >= 0; j--) { Ref b = c.buttons[j].texture; Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); - ofst.x -= size.x; + buttons_width += size.width + theme_cache.button_margin; + } + for (int j = c.buttons.size() - 1; j >= 0; j--) { + Ref b = c.buttons[j].texture; + Size2 size = b->get_size() + theme_cache.button_pressed->get_minimum_size(); + ofst.x -= size.x + theme_cache.button_margin; + + if (rtl) { + if (j == p_button) { + return Rect2(r.position, Size2(size.x, r.size.y)); + } + r.position.x += size.x + theme_cache.button_margin; + continue; + } if (j == p_button) { - return Rect2(ofst, size); + float content_rect_end_x = content_rect.position.x + content_rect.size.width; + if (r.position.x + r.size.x < content_rect_end_x) { + return Rect2(ofst, Size2(size.x, r.size.y)); + } + // Button block can be outside of content_rect + if (content_rect_end_x - (r.position.x + theme_cache.h_separation) < buttons_width) { + return Rect2(r.position + Point2(theme_cache.h_separation + (buttons_width - ((r.position.x + r.size.x) - ofst.x)), 0), Size2(size.x, r.size.y)); + } + + return Rect2(ofst - Vector2((r.position.x + r.size.x) - content_rect_end_x, 0), Size2(size.x, r.size.y)); } } } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index a0fc977bd8f..6008a4d38f2 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -344,7 +344,7 @@ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, int p_ } } -_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector &value, uint8_t *data) { +_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector &value, uint8_t *data, bool p_use_linear_color) { switch (type) { case ShaderLanguage::TYPE_BOOL: { uint32_t *gui = (uint32_t *)data; @@ -441,18 +441,28 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, } break; case ShaderLanguage::TYPE_VEC3: { + Color c = Color(value[0].real, value[1].real, value[2].real); + if (p_use_linear_color) { + c = c.srgb_to_linear(); + } + float *gui = reinterpret_cast(data); for (int i = 0; i < 3; i++) { - gui[i] = value[i].real; + gui[i] = c.components[i]; } } break; case ShaderLanguage::TYPE_VEC4: { + Color c = Color(value[0].real, value[1].real, value[2].real, value[3].real); + if (p_use_linear_color) { + c = c.srgb_to_linear(); + } + float *gui = reinterpret_cast(data); for (int i = 0; i < 4; i++) { - gui[i] = value[i].real; + gui[i] = c.components[i]; } } break; case ShaderLanguage::TYPE_MAT2: { @@ -789,7 +799,7 @@ void MaterialStorage::MaterialData::update_uniform_buffer(const HashMap 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL) { + const bool flush_frames = (get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL; + if (flush_frames) { if (_buffer_make_mutable(buffer, p_buffer)) { // The buffer must be mutable to be used as a copy source. draw_graph.add_synchronization(); } - for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) { + for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) { uint32_t local_index = get_data_request.frame_local_index + i; draw_graph.add_buffer_get_data(buffer->driver_id, buffer->draw_tracker, frames[frame].download_buffer_staging_buffers[local_index], frames[frame].download_buffer_copy_regions[local_index]); } - - flushed_copies = get_data_request.frame_local_count; } _staging_buffer_execute_required_action(download_staging_buffers, required_action); + if (flush_frames) { + get_data_request.frame_local_count = 0; + get_data_request.frame_local_index = frames[frame].download_buffer_copy_regions.size(); + } + RDD::BufferCopyRegion region; region.src_offset = submit_from + p_offset; region.dst_offset = block_write_offset; @@ -775,7 +778,7 @@ Error RenderingDevice::buffer_get_data_async(RID p_buffer, const Callable &p_cal draw_graph.add_synchronization(); } - for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) { + for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) { uint32_t local_index = get_data_request.frame_local_index + i; draw_graph.add_buffer_get_data(buffer->driver_id, buffer->draw_tracker, frames[frame].download_buffer_staging_buffers[local_index], frames[frame].download_buffer_copy_regions[local_index]); } @@ -2098,7 +2101,6 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c uint32_t block_write_offset; uint32_t block_write_amount; StagingRequiredAction required_action; - uint32_t flushed_copies = 0; for (uint32_t i = 0; i < tex->mipmaps; i++) { uint32_t image_total = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, i + 1, &w, &h, &d); uint32_t tight_mip_size = image_total - mipmap_offset; @@ -2119,17 +2121,21 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c Error err = _staging_buffer_allocate(download_staging_buffers, to_allocate, required_align, block_write_offset, block_write_amount, required_action, false); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); - if ((get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL) { - for (uint32_t j = flushed_copies; j < get_data_request.frame_local_count; j++) { + const bool flush_frames = (get_data_request.frame_local_count > 0) && required_action == STAGING_REQUIRED_ACTION_FLUSH_AND_STALL_ALL; + if (flush_frames) { + for (uint32_t j = 0; j < get_data_request.frame_local_count; j++) { uint32_t local_index = get_data_request.frame_local_index + j; draw_graph.add_texture_get_data(tex->driver_id, tex->draw_tracker, frames[frame].download_texture_staging_buffers[local_index], frames[frame].download_buffer_texture_copy_regions[local_index]); } - - flushed_copies = get_data_request.frame_local_count; } _staging_buffer_execute_required_action(download_staging_buffers, required_action); + if (flush_frames) { + get_data_request.frame_local_count = 0; + get_data_request.frame_local_index = frames[frame].download_buffer_texture_copy_regions.size(); + } + RDD::BufferTextureCopyRegion copy_region; copy_region.buffer_offset = block_write_offset; copy_region.texture_subresources.aspect = tex->read_aspect_flags; @@ -2154,12 +2160,11 @@ Error RenderingDevice::texture_get_data_async(RID p_texture, uint32_t p_layer, c } if (get_data_request.frame_local_count > 0) { - for (uint32_t i = flushed_copies; i < get_data_request.frame_local_count; i++) { + for (uint32_t i = 0; i < get_data_request.frame_local_count; i++) { uint32_t local_index = get_data_request.frame_local_index + i; draw_graph.add_texture_get_data(tex->driver_id, tex->draw_tracker, frames[frame].download_texture_staging_buffers[local_index], frames[frame].download_buffer_texture_copy_regions[local_index]); } - flushed_copies = get_data_request.frame_local_count; frames[frame].download_texture_get_data_requests.push_back(get_data_request); }