1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-31 05:23:21 +08:00

Merge pull request #31506 from peppy/fix-storyboard-break-overhead

Fix stutter on intensive storyboards when entering break time with 100% background dim
This commit is contained in:
Bartłomiej Dach 2025-01-15 08:23:58 +01:00 committed by GitHub
commit 614243fef4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 68 additions and 12 deletions

View File

@ -3,6 +3,7 @@
#nullable disable #nullable disable
using System.Linq;
using System.Threading; using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -15,6 +16,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Input.States; using osu.Framework.Input.States;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
@ -31,6 +33,7 @@ using osu.Game.Screens.Play;
using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Screens.Play.PlayerSettings;
using osu.Game.Screens.Ranking; using osu.Game.Screens.Ranking;
using osu.Game.Screens.Select; using osu.Game.Screens.Select;
using osu.Game.Storyboards.Drawables;
using osu.Game.Tests.Resources; using osu.Game.Tests.Resources;
using osuTK; using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
@ -45,6 +48,7 @@ namespace osu.Game.Tests.Visual.Background
private LoadBlockingTestPlayer player; private LoadBlockingTestPlayer player;
private BeatmapManager manager; private BeatmapManager manager;
private RulesetStore rulesets; private RulesetStore rulesets;
private UpdateCounter storyboardUpdateCounter;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(GameHost host, AudioManager audio) private void load(GameHost host, AudioManager audio)
@ -194,6 +198,28 @@ namespace osu.Game.Tests.Visual.Background
AddUntilStep("Storyboard is visible", () => player.IsStoryboardVisible); AddUntilStep("Storyboard is visible", () => player.IsStoryboardVisible);
} }
[Test]
public void TestStoryboardUpdatesWhenDimmed()
{
performFullSetup();
createFakeStoryboard();
AddStep("Enable fully dimmed storyboard", () =>
{
player.StoryboardReplacesBackground.Value = true;
player.StoryboardEnabled.Value = true;
player.DimmableStoryboard.IgnoreUserSettings.Value = false;
songSelect.DimLevel.Value = 1f;
});
AddUntilStep("Storyboard is invisible", () => !player.IsStoryboardVisible);
AddWaitStep("wait some", 20);
AddUntilStep("Storyboard is always present", () => player.ChildrenOfType<DrawableStoryboard>().Single().AlwaysPresent, () => Is.True);
AddUntilStep("Dimmable storyboard content is being updated", () => storyboardUpdateCounter.StoryboardContentLastUpdated, () => Is.EqualTo(Time.Current).Within(100));
}
[Test] [Test]
public void TestStoryboardIgnoreUserSettings() public void TestStoryboardIgnoreUserSettings()
{ {
@ -269,15 +295,19 @@ namespace osu.Game.Tests.Visual.Background
{ {
player.StoryboardEnabled.Value = false; player.StoryboardEnabled.Value = false;
player.StoryboardReplacesBackground.Value = false; player.StoryboardReplacesBackground.Value = false;
player.DimmableStoryboard.Add(new OsuSpriteText player.DimmableStoryboard.AddRange(new Drawable[]
{ {
Size = new Vector2(500, 50), storyboardUpdateCounter = new UpdateCounter(),
Alpha = 1, new OsuSpriteText
Colour = Color4.White, {
Anchor = Anchor.Centre, Size = new Vector2(500, 50),
Origin = Anchor.Centre, Alpha = 1,
Text = "THIS IS A STORYBOARD", Colour = Color4.White,
Font = new FontUsage(size: 50) Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = "THIS IS A STORYBOARD",
Font = new FontUsage(size: 50)
}
}); });
}); });
@ -353,7 +383,7 @@ namespace osu.Game.Tests.Visual.Background
/// <summary> /// <summary>
/// Make sure every time a screen gets pushed, the background doesn't get replaced /// Make sure every time a screen gets pushed, the background doesn't get replaced
/// </summary> /// </summary>
/// <returns>Whether or not the original background (The one created in DummySongSelect) is still the current background</returns> /// <returns>Whether the original background (The one created in DummySongSelect) is still the current background</returns>
public bool IsBackgroundCurrent() => background?.IsCurrentScreen() == true; public bool IsBackgroundCurrent() => background?.IsCurrentScreen() == true;
} }
@ -384,7 +414,7 @@ namespace osu.Game.Tests.Visual.Background
public new DimmableStoryboard DimmableStoryboard => base.DimmableStoryboard; public new DimmableStoryboard DimmableStoryboard => base.DimmableStoryboard;
// Whether or not the player should be allowed to load. // Whether the player should be allowed to load.
public bool BlockLoad; public bool BlockLoad;
public Bindable<bool> StoryboardEnabled; public Bindable<bool> StoryboardEnabled;
@ -451,6 +481,17 @@ namespace osu.Game.Tests.Visual.Background
} }
} }
private partial class UpdateCounter : Drawable
{
public double StoryboardContentLastUpdated;
protected override void Update()
{
base.Update();
StoryboardContentLastUpdated = Time.Current;
}
}
private partial class TestDimmableBackground : BackgroundScreenBeatmap.DimmableBackground private partial class TestDimmableBackground : BackgroundScreenBeatmap.DimmableBackground
{ {
public Color4 CurrentColour => Content.Colour; public Color4 CurrentColour => Content.Colour;

View File

@ -69,7 +69,22 @@ namespace osu.Game.Screens.Play
protected override void LoadComplete() protected override void LoadComplete()
{ {
ShowStoryboard.BindValueChanged(_ => initializeStoryboard(true), true); ShowStoryboard.BindValueChanged(show =>
{
initializeStoryboard(true);
if (drawableStoryboard != null)
{
// Regardless of user dim setting, for the time being we need to ensure storyboards are still updated in the background (even if not displayed).
// If we don't do this, an intensive storyboard will have a lot of catch-up work to do at the start of a break, causing a huge stutter.
//
// This can be reconsidered when https://github.com/ppy/osu-framework/issues/6491 is resolved.
bool alwaysPresent = show.NewValue;
Content.AlwaysPresent = alwaysPresent;
drawableStoryboard.AlwaysPresent = alwaysPresent;
}
}, true);
base.LoadComplete(); base.LoadComplete();
} }

View File

@ -35,7 +35,7 @@ namespace osu.Game.Storyboards.Drawables
protected override Container<DrawableStoryboardLayer> Content { get; } protected override Container<DrawableStoryboardLayer> Content { get; }
protected override Vector2 DrawScale => new Vector2(Parent!.DrawHeight / 480); protected override Vector2 DrawScale => new Vector2((Parent?.DrawHeight ?? 0) / 480);
public override bool RemoveCompletedTransforms => false; public override bool RemoveCompletedTransforms => false;