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);
}