From db46050b16814cd983a003a66adc87c729d48afb Mon Sep 17 00:00:00 2001 From: Saas Date: Sun, 1 Mar 2026 11:01:55 +0100 Subject: [PATCH 1/5] tweak caret blink speed --- Source/Engine/UI/GUI/Common/RichTextBoxBase.cs | 4 ++-- Source/Engine/UI/GUI/Common/TextBox.cs | 4 ++-- Source/Engine/UI/GUI/Common/TextBoxBase.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs b/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs index 2fc2ef4b3..7722fc94b 100644 --- a/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/RichTextBoxBase.cs @@ -437,8 +437,8 @@ namespace FlaxEngine.GUI // Caret if (IsFocused && CaretPosition > -1) { - float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f); - alpha = alpha * alpha * alpha * alpha * alpha * alpha; + float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.8f); + alpha = alpha * alpha; Render2D.FillRectangle(CaretBounds, CaretColor * alpha); } diff --git a/Source/Engine/UI/GUI/Common/TextBox.cs b/Source/Engine/UI/GUI/Common/TextBox.cs index 1dfd9facc..3d7099db6 100644 --- a/Source/Engine/UI/GUI/Common/TextBox.cs +++ b/Source/Engine/UI/GUI/Common/TextBox.cs @@ -310,8 +310,8 @@ namespace FlaxEngine.GUI // Caret if (IsFocused && CaretPosition > -1) { - float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f); - alpha = alpha * alpha * alpha * alpha * alpha * alpha; + float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.8f); + alpha = alpha * alpha; Render2D.FillRectangle(CaretBounds, CaretColor * alpha); } diff --git a/Source/Engine/UI/GUI/Common/TextBoxBase.cs b/Source/Engine/UI/GUI/Common/TextBoxBase.cs index 243e4786e..7deb9a367 100644 --- a/Source/Engine/UI/GUI/Common/TextBoxBase.cs +++ b/Source/Engine/UI/GUI/Common/TextBoxBase.cs @@ -275,7 +275,7 @@ namespace FlaxEngine.GUI /// Gets or sets the speed of the caret flashing animation. /// [EditorDisplay("Caret Style"), EditorOrder(2021), Tooltip("The speed of the caret flashing animation.")] - public float CaretFlashSpeed { get; set; } = 6.0f; + public float CaretFlashSpeed { get; set; } = 6.5f; /// /// Gets or sets the speed of the selection background flashing animation. From 5f9e8dedec6d32c298197a32a643b956d2f75b71 Mon Sep 17 00:00:00 2001 From: Ari Vuollet Date: Mon, 2 Mar 2026 23:40:41 +0200 Subject: [PATCH 2/5] Pass String reference values via temporary values --- Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 3bdb16815..f1c4c6be8 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1300,10 +1300,10 @@ namespace Flax.Build.Bindings else if (parameterInfo.Type.IsRef && !parameterInfo.Type.IsConst) { // Non-const lvalue reference parameters needs to be passed via temporary value - if (parameterInfo.IsOut || parameterInfo.IsRef) - contents.Append(indent).AppendFormat("{2}& {0}Temp = {1};", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine(); - else + if (parameterInfo.Type.Type is "String" or "StringView" or "StringAnsi" or "StringAnsiView" && parameterInfo.Type.GenericArgs == null) contents.Append(indent).AppendFormat("{2} {0}Temp = {1};", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine(); + else + contents.Append(indent).AppendFormat("{2}& {0}Temp = {1};", parameterInfo.Name, param, parameterInfo.Type.ToString(false)).AppendLine(); callParams += parameterInfo.Name; callParams += "Temp"; } From f7e2f3a4d5a39bcc1511f5174011f767224064c6 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Mon, 2 Mar 2026 19:20:15 -0600 Subject: [PATCH 3/5] Only set kinematic target if rigid body has kinematic flag. --- Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index 8c3d3610e..b5efa9d73 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -2450,7 +2450,7 @@ void PhysicsBackend::SetRigidActorPose(void* actor, const Vector3& position, con if (kinematic) { auto actorPhysX = (PxRigidDynamic*)actor; - if (actorPhysX->getActorFlags() & PxActorFlag::eDISABLE_SIMULATION) + if (actorPhysX->getActorFlags() & PxActorFlag::eDISABLE_SIMULATION || !(actorPhysX->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC)) { // Ensures the disabled kinematic actor ends up in the correct pose after enabling simulation actorPhysX->setGlobalPose(trans, wakeUp); From 10bcf9c9a330b14609a352f71b6f428db998c96c Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 3 Mar 2026 23:29:10 +0100 Subject: [PATCH 4/5] Fix Vulkan timeout to be larger (5s) #3967 --- .../GraphicsDevice/Vulkan/CmdBufferVulkan.cpp | 23 +++++++++---------- .../GraphicsDevice/Vulkan/CmdBufferVulkan.h | 2 +- Source/Engine/GraphicsDevice/Vulkan/Config.h | 5 ++++ .../GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp | 9 ++++---- .../GraphicsDevice/Vulkan/GPUDeviceVulkan.h | 4 ++-- .../GraphicsDevice/Vulkan/QueueVulkan.cpp | 6 +---- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp index 36eacccf9..737c147d9 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.cpp @@ -136,6 +136,15 @@ void CmdBufferVulkan::EndEvent() #endif +void CmdBufferVulkan::Wait(float timeoutSeconds) +{ + PROFILE_CPU(); + ASSERT(IsSubmitted()); + const bool failed = _device->FenceManager.WaitForFence(GetFence(), timeoutSeconds); + ASSERT(!failed); + RefreshFenceStatus(); +} + void CmdBufferVulkan::RefreshFenceStatus() { if (_state == State::Submitted) @@ -186,9 +195,8 @@ CmdBufferVulkan::~CmdBufferVulkan() auto& fenceManager = _device->FenceManager; if (_state == State::Submitted) { - // Wait 60ms - const uint64 waitForCmdBufferInNanoSeconds = 60 * 1000 * 1000LL; - fenceManager.WaitAndReleaseFence(_fence, waitForCmdBufferInNanoSeconds); + // Wait + fenceManager.WaitAndReleaseFence(_fence); } else { @@ -281,15 +289,6 @@ void CmdBufferManagerVulkan::SubmitActiveCmdBuffer(SemaphoreVulkan* signalSemaph _activeCmdBuffer = nullptr; } -void CmdBufferManagerVulkan::WaitForCmdBuffer(CmdBufferVulkan* cmdBuffer, float timeInSecondsToWait) -{ - PROFILE_CPU(); - ASSERT(cmdBuffer->IsSubmitted()); - const bool failed = _device->FenceManager.WaitForFence(cmdBuffer->GetFence(), (uint64)(timeInSecondsToWait * 1e9)); - ASSERT(!failed); - cmdBuffer->RefreshFenceStatus(); -} - void CmdBufferManagerVulkan::PrepareForNewActiveCommandBuffer() { PROFILE_CPU(); diff --git a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h index 7cb3ee104..c8e096cdd 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/CmdBufferVulkan.h @@ -136,6 +136,7 @@ public: void EndEvent(); #endif + void Wait(float timeoutSeconds = VULKAN_WAIT_TIMEOUT); void RefreshFenceStatus(); }; @@ -206,7 +207,6 @@ public: public: void SubmitActiveCmdBuffer(SemaphoreVulkan* signalSemaphore = nullptr); - void WaitForCmdBuffer(CmdBufferVulkan* cmdBuffer, float timeInSecondsToWait = 1.0f); void RefreshFenceStatus(CmdBufferVulkan* skipCmdBuffer = nullptr) { _pool.RefreshFenceStatus(skipCmdBuffer); diff --git a/Source/Engine/GraphicsDevice/Vulkan/Config.h b/Source/Engine/GraphicsDevice/Vulkan/Config.h index 1f30c301a..7b4e54137 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/Config.h +++ b/Source/Engine/GraphicsDevice/Vulkan/Config.h @@ -49,4 +49,9 @@ #define VULKAN_USE_QUERIES 1 #endif +// Fence wait operation timeout in seconds +#ifndef VULKAN_WAIT_TIMEOUT +#define VULKAN_WAIT_TIMEOUT 5.0f +#endif + #endif diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index e96f7b3b3..71ef42005 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -2184,11 +2184,12 @@ FenceVulkan* FenceManagerVulkan::AllocateFence(bool createSignaled) return fence; } -bool FenceManagerVulkan::WaitForFence(FenceVulkan* fence, uint64 timeInNanoseconds) const +bool FenceManagerVulkan::WaitForFence(FenceVulkan* fence, float timeoutSeconds) const { ASSERT(_usedFences.Contains(fence)); ASSERT(!fence->IsSignaled); - const VkResult result = vkWaitForFences(_device->Device, 1, &fence->Handle, true, timeInNanoseconds); + uint64 timeNanoseconds = (uint64)((double)timeoutSeconds * 1000000000.0); + const VkResult result = vkWaitForFences(_device->Device, 1, &fence->Handle, true, timeNanoseconds); LOG_VULKAN_RESULT(result); if (result == VK_SUCCESS) { @@ -2216,11 +2217,11 @@ void FenceManagerVulkan::ReleaseFence(FenceVulkan*& fence) fence = nullptr; } -void FenceManagerVulkan::WaitAndReleaseFence(FenceVulkan*& fence, uint64 timeInNanoseconds) +void FenceManagerVulkan::WaitAndReleaseFence(FenceVulkan*& fence, float timeoutSeconds) { ScopeLock lock(_device->_fenceLock); if (!fence->IsSignaled) - WaitForFence(fence, timeInNanoseconds); + WaitForFence(fence, timeoutSeconds); ResetFence(fence); _usedFences.Remove(fence); _freeFences.Add(fence); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h index 09fa93f3e..a22cd9cc6 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h @@ -88,7 +88,7 @@ public: } // Returns true if waiting timed out or failed, false otherwise. - bool WaitForFence(FenceVulkan* fence, uint64 timeInNanoseconds) const; + bool WaitForFence(FenceVulkan* fence, float timeoutSeconds = VULKAN_WAIT_TIMEOUT) const; void ResetFence(FenceVulkan* fence) const; @@ -96,7 +96,7 @@ public: void ReleaseFence(FenceVulkan*& fence); // Sets the fence handle to null - void WaitAndReleaseFence(FenceVulkan*& fence, uint64 timeInNanoseconds); + void WaitAndReleaseFence(FenceVulkan*& fence, float timeoutSeconds = VULKAN_WAIT_TIMEOUT); private: // Returns true if fence was signaled, otherwise false. diff --git a/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp index f2d2521d0..39b0d2691 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/QueueVulkan.cpp @@ -62,11 +62,7 @@ void QueueVulkan::Submit(CmdBufferVulkan* cmdBuffer, uint32 signalSemaphoresCoun const bool WaitForIdleOnSubmit = false; if (WaitForIdleOnSubmit) { - // Use 200ms timeout - bool success = _device->FenceManager.WaitForFence(fence, 200 * 1000 * 1000); - ASSERT(success); - ASSERT(_device->FenceManager.IsFenceSignaled(fence)); - cmdBuffer->GetOwner()->RefreshFenceStatus(); + cmdBuffer->Wait(); } #endif From cee1b72f2fcfd9e21387760e63c45ba800ffea26 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Wed, 4 Mar 2026 00:02:06 +0100 Subject: [PATCH 5/5] Fix regression from 7b7a92758ff1a6f040c535b8e5a8858dd36d7380 #3932 --- Source/Engine/Core/Types/Variant.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp index dcabe8e48..96db06656 100644 --- a/Source/Engine/Core/Types/Variant.cpp +++ b/Source/Engine/Core/Types/Variant.cpp @@ -247,7 +247,7 @@ VariantType::VariantType(VariantType&& other) noexcept VariantType& VariantType::operator=(const Types& type) { Type = type; - if (StaticName) + if (!StaticName) Allocator::Free(TypeName); TypeName = nullptr; StaticName = 0; @@ -266,7 +266,7 @@ VariantType& VariantType::operator=(const VariantType& other) { ASSERT(this != &other); Type = other.Type; - if (StaticName) + if (!StaticName) Allocator::Free(TypeName); StaticName = other.StaticName; if (StaticName) @@ -316,7 +316,7 @@ void VariantType::SetTypeName(const StringView& typeName) { if (StringUtils::Length(TypeName) != typeName.Length()) { - if (StaticName) + if (!StaticName) Allocator::Free(TypeName); StaticName = 0; TypeName = static_cast(Allocator::Allocate(typeName.Length() + 1)); @@ -329,7 +329,7 @@ void VariantType::SetTypeName(const StringAnsiView& typeName, bool staticName) { if (StringUtils::Length(TypeName) != typeName.Length() || StaticName != staticName) { - if (StaticName) + if (!StaticName) Allocator::Free(TypeName); StaticName = staticName; if (staticName)