diff --git a/osu-framework b/osu-framework index d2c6d11f3b..9cd6968a8c 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit d2c6d11f3bcc54a5aeb5a16d6563036c7e1f4759 +Subproject commit 9cd6968a8c4d27415808f5e770d24fec5a44485f diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index ca541ea552..ec2e8e0cb1 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -1,8 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Shaders; using osu.Game.Screens.Menu; using OpenTK; using osu.Framework.Screens; @@ -33,14 +37,28 @@ namespace osu.Game.Screens logo.FadeInFromZero(5000, Easing.OutQuint); } + private OsuScreen loadScreen; + private ShaderPrecompiler precompiler; + protected override void OnEntering(Screen last) { base.OnEntering(last); - if (showDisclaimer) - LoadComponentAsync(new Disclaimer(), d => Push(d)); - else - LoadComponentAsync(new Intro(), d => Push(d)); + LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add); + LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady()); + } + + private void loadIfReady() + { + if (ChildScreen == loadScreen) return; + + if (loadScreen.LoadState != LoadState.Ready) + return; + + if (!precompiler.FinishedCompiling) + return; + + Push(loadScreen); } protected override void LogoSuspending(OsuLogo logo) @@ -54,5 +72,49 @@ namespace osu.Game.Screens { showDisclaimer = game.IsDeployedBuild; } + + /// + /// Compiles a set of shaders before continuing. Attempts to draw some frames between compilation by limiting to one compile per draw frame. + /// + public class ShaderPrecompiler : Drawable + { + private readonly Action onLoaded; + private readonly List loadTargets = new List(); + + public bool FinishedCompiling { get; private set; } + + public ShaderPrecompiler(Action onLoaded) + { + this.onLoaded = onLoaded; + } + + [BackgroundDependencyLoader] + private void load(ShaderManager manager) + { + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.BLUR)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE)); + + loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE)); + + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE_ROUNDED)); + loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); + } + + private Shader currentLoadTarget; + + protected override void Update() + { + base.Update(); + + // if our target is null we are done. + if (loadTargets.All(s => s.Loaded)) + { + FinishedCompiling = true; + Expire(); + onLoaded?.Invoke(); + } + } + } } }