Skip to content

Commit

Permalink
Merge pull request #23034 from peppy/fix-ruleset-shader-caching
Browse files Browse the repository at this point in the history
Fix stutters during gameplay due to shaders not correctly using cache
  • Loading branch information
peppy authored Apr 2, 2023
2 parents 327e284 + 1e0b64c commit ea42e7f
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 33 deletions.
2 changes: 1 addition & 1 deletion osu.Android.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.327.0" />
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.402.1" />
</ItemGroup>
<ItemGroup>
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
Expand Down
18 changes: 9 additions & 9 deletions osu.Game.Tests/Testing/TestSceneRulesetDependencies.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using System.Collections.Generic;
using NUnit.Framework;
Expand Down Expand Up @@ -51,9 +49,11 @@ public void TestRetrieveSample()
[Test]
public void TestRetrieveShader()
{
AddAssert("ruleset shaders retrieved", () =>
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs") != null &&
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs") != null);
AddStep("ruleset shaders retrieved without error", () =>
{
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs");
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs");
});
}

[Test]
Expand All @@ -76,12 +76,12 @@ public TestRuleset()
}

public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new TestRulesetConfigManager();
public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new TestRulesetConfigManager();

public override IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>();
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => null;
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null;
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null;
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod>? mods = null) => null!;
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null!;
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null!;
}

private class TestRulesetConfigManager : IRulesetConfigManager
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private partial class CountSection : Container
set => valueText.Text = value.ToLocalisableString("N0");
}

public CountSection(LocalisableString header)
protected CountSection(LocalisableString header)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, Gam
if (window != null)
{
currentDisplay.BindTo(window.CurrentDisplayBindable);
windowModes.BindTo(window.SupportedWindowModes);
window.DisplaysChanged += onDisplaysChanged;
}

Expand All @@ -87,7 +86,7 @@ private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, Gam
windowModeDropdown = new SettingsDropdown<WindowMode>
{
LabelText = GraphicsSettingsStrings.ScreenMode,
ItemSource = windowModes,
Items = window?.SupportedWindowModes,
Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
},
displayDropdown = new DisplaySettingsDropdown
Expand Down
43 changes: 26 additions & 17 deletions osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,28 @@ public class DrawableRulesetDependencies : DependencyContainer, IDisposable
/// <summary>
/// The texture store to be used for the ruleset.
/// </summary>
/// <remarks>
/// Reads textures from the "Textures" folder in ruleset resources.
/// If not available locally, lookups will fallback to the global texture store.
/// </remarks>
public TextureStore TextureStore { get; }

/// <summary>
/// The sample store to be used for the ruleset.
/// </summary>
/// <remarks>
/// This is the local sample store pointing to the ruleset sample resources,
/// the cached sample store (<see cref="FallbackSampleStore"/>) retrieves from
/// this store and falls back to the parent store if this store doesn't have the requested sample.
/// Reads samples from the "Samples" folder in ruleset resources.
/// If not available locally, lookups will fallback to the global sample store.
/// </remarks>
public ISampleStore SampleStore { get; }

/// <summary>
/// The shader manager to be used for the ruleset.
/// </summary>
/// <remarks>
/// Reads shaders from the "Shaders" folder in ruleset resources.
/// If not available locally, lookups will fallback to the global shader manager.
/// </remarks>
public ShaderManager ShaderManager { get; }

/// <summary>
Expand All @@ -61,8 +68,7 @@ public DrawableRulesetDependencies(Ruleset ruleset, IReadOnlyDependencyContainer
SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>()));

ShaderManager = new ShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"));
CacheAs(ShaderManager = new FallbackShaderManager(host.Renderer, ShaderManager, parent.Get<ShaderManager>()));
CacheAs(ShaderManager = new RulesetShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"), parent.Get<ShaderManager>()));

RulesetConfigManager = parent.Get<IRulesetConfigCache>().GetConfigFor(ruleset);
if (RulesetConfigManager != null)
Expand Down Expand Up @@ -190,24 +196,27 @@ protected override void Dispose(bool disposing)
}
}

private class FallbackShaderManager : ShaderManager
private class RulesetShaderManager : ShaderManager
{
private readonly ShaderManager primary;
private readonly ShaderManager fallback;
private readonly ShaderManager parent;

public FallbackShaderManager(IRenderer renderer, ShaderManager primary, ShaderManager fallback)
: base(renderer, new ResourceStore<byte[]>())
public RulesetShaderManager(IRenderer renderer, NamespacedResourceStore<byte[]> rulesetResources, ShaderManager parent)
: base(renderer, rulesetResources)
{
this.primary = primary;
this.fallback = fallback;
this.parent = parent;
}

public override byte[]? LoadRaw(string name) => primary.LoadRaw(name) ?? fallback.LoadRaw(name);

protected override void Dispose(bool disposing)
public override IShader Load(string vertex, string fragment)
{
base.Dispose(disposing);
if (primary.IsNotNull()) primary.Dispose();
try
{
return base.Load(vertex, fragment);
}
catch
{
// Shader lookup is very non-standard. Rather than returning null on missing shaders, exceptions are thrown.
return parent.Load(vertex, fragment);
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions osu.Game/Screens/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ private void load(ShaderManager manager)

loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE));

loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"));

loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
}

Expand Down
4 changes: 2 additions & 2 deletions osu.Game/osu.Game.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Realm" Version="10.20.0" />
<PackageReference Include="ppy.osu.Framework" Version="2023.327.0" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.320.0" />
<PackageReference Include="ppy.osu.Framework" Version="2023.402.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.402.0" />
<PackageReference Include="Sentry" Version="3.28.1" />
<PackageReference Include="SharpCompress" Version="0.32.2" />
<PackageReference Include="NUnit" Version="3.13.3" />
Expand Down
2 changes: 1 addition & 1 deletion osu.iOS.props
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.327.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.402.1" />
</ItemGroup>
</Project>

0 comments on commit ea42e7f

Please sign in to comment.