From 5cac7757ffefca29159b0b1d33d3e7b2f436ef71 Mon Sep 17 00:00:00 2001 From: menvae <116231436+menvae@users.noreply.github.com> Date: Thu, 19 Feb 2026 05:49:48 +0200 Subject: [PATCH 1/2] Fix typo in BlendingParameters.translateBlendingFactorSrc & add missing OneMinusSrcColor case (#6707) --- osu.Framework/Graphics/BlendingParameters.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Framework/Graphics/BlendingParameters.cs b/osu.Framework/Graphics/BlendingParameters.cs index 1721dab3a..4cc7bd4ed 100644 --- a/osu.Framework/Graphics/BlendingParameters.cs +++ b/osu.Framework/Graphics/BlendingParameters.cs @@ -238,6 +238,9 @@ namespace osu.Framework.Graphics return BlendingFactorSrc.OneMinusDstColor; case BlendingType.OneMinusSrcAlpha: + return BlendingFactorSrc.OneMinusSrcAlpha; + + case BlendingType.OneMinusSrcColor: return BlendingFactorSrc.OneMinusSrcColor; case BlendingType.SrcAlpha: From ca40f0a4d314b2acbad09f63e63824ae2670aa29 Mon Sep 17 00:00:00 2001 From: cdwcgt Date: Fri, 20 Feb 2026 21:13:29 +0800 Subject: [PATCH 2/2] Fix instability from near-zero scale by preserving sign when clamping in DrawInfo (#6708) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix instability from near-zero scale by preserving sign when clamping in DrawInfo * Add test coverage for properly accounting for numerical instability at low draw scale --------- Co-authored-by: Bartłomiej Dach --- .../Visual/Drawables/TestSceneAutoSize.cs | 93 +++++++++++++++++++ osu.Framework/Graphics/DrawInfo.cs | 4 +- 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs diff --git a/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs b/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs new file mode 100644 index 000000000..f4639a4b8 --- /dev/null +++ b/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs @@ -0,0 +1,93 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Framework.Utils; +using osuTK; + +namespace osu.Framework.Tests.Visual.Drawables +{ + [HeadlessTest] + public partial class TestSceneAutoSize : TestScene + { + private static readonly object[][] scales = Enumerable.Range(0, 10).Select(i => new object[] { MathF.Pow(10, -i) }).ToArray(); + + [TestCaseSource(nameof(scales))] + public void TestAlmostZeroXScale(float scale) + { + Container autoSizeContainer = null!; + Container outerContainer; + + AddStep("add box", () => + { + Add(outerContainer = new Container + { + Name = "outer container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Child = autoSizeContainer = new Container + { + Name = "autosize container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Child = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(128f), + } + } + }); + + outerContainer.Scale = new Vector2(scale, 2); + }); + + AddAssert("autosize container preserves width", () => autoSizeContainer.Width, () => Is.EqualTo(128).Within(Precision.FLOAT_EPSILON)); + } + + [TestCaseSource(nameof(scales))] + public void TestAlmostZeroYScale(float scale) + { + Container autoSizeContainer = null!; + Container outerContainer; + + AddStep("add box", () => + { + Add(outerContainer = new Container + { + Name = "outer container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Child = autoSizeContainer = new Container + { + Name = "autosize container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Child = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(128f), + } + } + }); + + outerContainer.Scale = new Vector2(2, scale); + }); + + AddAssert("autosize container preserves height", () => autoSizeContainer.Height, () => Is.EqualTo(128).Within(Precision.FLOAT_EPSILON)); + } + } +} diff --git a/osu.Framework/Graphics/DrawInfo.cs b/osu.Framework/Graphics/DrawInfo.cs index 44bd44602..050d6c5fa 100644 --- a/osu.Framework/Graphics/DrawInfo.cs +++ b/osu.Framework/Graphics/DrawInfo.cs @@ -52,8 +52,8 @@ namespace osu.Framework.Graphics if (scale != Vector2.One) { // Zero scale leads to unexpected input and autosize calculations, so it's clamped to a sane value. - if (scale.X == 0) scale.X = Precision.FLOAT_EPSILON; - if (scale.Y == 0) scale.Y = Precision.FLOAT_EPSILON; + if (Math.Abs(scale.X) < Precision.FLOAT_EPSILON) scale.X = Math.Sign(scale.X == 0 ? 1 : scale.X) * Precision.FLOAT_EPSILON; + if (Math.Abs(scale.Y) < Precision.FLOAT_EPSILON) scale.Y = Math.Sign(scale.Y == 0 ? 1 : scale.Y) * Precision.FLOAT_EPSILON; MatrixExtensions.ScaleFromLeft(ref Matrix, scale); MatrixExtensions.ScaleFromRight(ref MatrixInverse, Vector2.Divide(Vector2.One, scale));