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

Merge pull request #4745 from peppy/fix-long-skip-performance

Fix long skip performance
This commit is contained in:
Dan Balasescu 2019-05-10 16:27:11 +09:00 committed by GitHub
commit 03c949c396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 6 deletions

View File

@ -73,6 +73,26 @@ namespace osu.Game.Tests.Visual.Gameplay
checkFrameCount(2); checkFrameCount(2);
} }
[Test]
public void TestInitialSeekWithGameplayStart()
{
seekManualTo(1000);
createStabilityContainer(30000);
confirmSeek(1000);
checkFrameCount(0);
seekManualTo(10000);
confirmSeek(10000);
checkFrameCount(1);
seekManualTo(130000);
confirmSeek(130000);
checkFrameCount(6002);
}
[Test] [Test]
public void TestInitialSeek() public void TestInitialSeek()
{ {
@ -83,7 +103,11 @@ namespace osu.Game.Tests.Visual.Gameplay
checkFrameCount(0); checkFrameCount(0);
} }
private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild())); private const int max_frames_catchup = 50;
private void createStabilityContainer(double gameplayStartTime = double.MinValue) => AddStep("create container", () =>
mainContainer.Child = new FrameStabilityContainer(gameplayStartTime) { MaxCatchUpFrames = max_frames_catchup }
.WithChild(consumer = new ClockConsumingChild()));
private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time); private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time);

View File

@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.UI
{ {
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
frameStabilityContainer = new FrameStabilityContainer frameStabilityContainer = new FrameStabilityContainer(GameplayStartTime)
{ {
Child = KeyBindingInputManager Child = KeyBindingInputManager
.WithChild(CreatePlayfieldAdjustmentContainer() .WithChild(CreatePlayfieldAdjustmentContainer()

View File

@ -17,10 +17,19 @@ namespace osu.Game.Rulesets.UI
/// </summary> /// </summary>
public class FrameStabilityContainer : Container, IHasReplayHandler public class FrameStabilityContainer : Container, IHasReplayHandler
{ {
public FrameStabilityContainer() private readonly double gameplayStartTime;
/// <summary>
/// The number of frames (per parent frame) which can be run in an attempt to catch-up to real-time.
/// </summary>
public int MaxCatchUpFrames { get; set; } = 5;
public FrameStabilityContainer(double gameplayStartTime = double.MinValue)
{ {
RelativeSizeAxes = Axes.Both; RelativeSizeAxes = Axes.Both;
gameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock())); gameplayClock = new GameplayClock(framedClock = new FramedClock(manualClock = new ManualClock()));
this.gameplayStartTime = gameplayStartTime;
} }
private readonly ManualClock manualClock; private readonly ManualClock manualClock;
@ -64,8 +73,6 @@ namespace osu.Game.Rulesets.UI
private bool isAttached => ReplayInputHandler != null; private bool isAttached => ReplayInputHandler != null;
private const int max_catch_up_updates_per_frame = 50;
private const double sixty_frame_time = 1000.0 / 60; private const double sixty_frame_time = 1000.0 / 60;
private bool firstConsumption = true; private bool firstConsumption = true;
@ -77,7 +84,7 @@ namespace osu.Game.Rulesets.UI
int loops = 0; int loops = 0;
while (validState && requireMoreUpdateLoops && loops++ < max_catch_up_updates_per_frame) while (validState && requireMoreUpdateLoops && loops++ < MaxCatchUpFrames)
{ {
updateClock(); updateClock();
@ -116,6 +123,8 @@ namespace osu.Game.Rulesets.UI
firstConsumption = false; firstConsumption = false;
} }
else if (manualClock.CurrentTime < gameplayStartTime)
manualClock.CurrentTime = newProposedTime = Math.Min(gameplayStartTime, newProposedTime);
else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f) else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
{ {
newProposedTime = newProposedTime > manualClock.CurrentTime newProposedTime = newProposedTime > manualClock.CurrentTime