mirror of
https://github.com/ppy/osu.git
synced 2025-02-14 04:52:55 +08:00
Merge pull request #23034 from peppy/fix-ruleset-shader-caching
Fix stutters during gameplay due to shaders not correctly using cache
This commit is contained in:
commit
ea42e7f3fa
@ -11,7 +11,7 @@
|
|||||||
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
|
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.327.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.402.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
|
<AndroidManifestOverlay Include="$(MSBuildThisFileDirectory)osu.Android\Properties\AndroidManifestOverlay.xml" />
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -51,9 +49,11 @@ namespace osu.Game.Tests.Testing
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRetrieveShader()
|
public void TestRetrieveShader()
|
||||||
{
|
{
|
||||||
AddAssert("ruleset shaders retrieved", () =>
|
AddStep("ruleset shaders retrieved without error", () =>
|
||||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs") != null &&
|
{
|
||||||
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs") != null);
|
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestVertex.vs");
|
||||||
|
Dependencies.Get<ShaderManager>().LoadRaw(@"sh_TestFragment.fs");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -76,12 +76,12 @@ namespace osu.Game.Tests.Testing
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override IResourceStore<byte[]> CreateResourceStore() => new NamespacedResourceStore<byte[]>(TestResources.GetStore(), @"Resources");
|
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 IEnumerable<Mod> GetModsFor(ModType type) => Array.Empty<Mod>();
|
||||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => null;
|
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod>? mods = null) => null!;
|
||||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null;
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => null!;
|
||||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null;
|
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestRulesetConfigManager : IRulesetConfigManager
|
private class TestRulesetConfigManager : IRulesetConfigManager
|
||||||
|
@ -55,7 +55,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
|||||||
set => valueText.Text = value.ToLocalisableString("N0");
|
set => valueText.Text = value.ToLocalisableString("N0");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CountSection(LocalisableString header)
|
protected CountSection(LocalisableString header)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
|
@ -75,7 +75,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
if (window != null)
|
if (window != null)
|
||||||
{
|
{
|
||||||
currentDisplay.BindTo(window.CurrentDisplayBindable);
|
currentDisplay.BindTo(window.CurrentDisplayBindable);
|
||||||
windowModes.BindTo(window.SupportedWindowModes);
|
|
||||||
window.DisplaysChanged += onDisplaysChanged;
|
window.DisplaysChanged += onDisplaysChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
windowModeDropdown = new SettingsDropdown<WindowMode>
|
windowModeDropdown = new SettingsDropdown<WindowMode>
|
||||||
{
|
{
|
||||||
LabelText = GraphicsSettingsStrings.ScreenMode,
|
LabelText = GraphicsSettingsStrings.ScreenMode,
|
||||||
ItemSource = windowModes,
|
Items = window?.SupportedWindowModes,
|
||||||
Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
|
Current = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode),
|
||||||
},
|
},
|
||||||
displayDropdown = new DisplaySettingsDropdown
|
displayDropdown = new DisplaySettingsDropdown
|
||||||
|
@ -25,21 +25,28 @@ namespace osu.Game.Rulesets.UI
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The texture store to be used for the ruleset.
|
/// The texture store to be used for the ruleset.
|
||||||
/// </summary>
|
/// </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; }
|
public TextureStore TextureStore { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The sample store to be used for the ruleset.
|
/// The sample store to be used for the ruleset.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This is the local sample store pointing to the ruleset sample resources,
|
/// Reads samples from the "Samples" folder in ruleset resources.
|
||||||
/// the cached sample store (<see cref="FallbackSampleStore"/>) retrieves from
|
/// If not available locally, lookups will fallback to the global sample store.
|
||||||
/// this store and falls back to the parent store if this store doesn't have the requested sample.
|
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public ISampleStore SampleStore { get; }
|
public ISampleStore SampleStore { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The shader manager to be used for the ruleset.
|
/// The shader manager to be used for the ruleset.
|
||||||
/// </summary>
|
/// </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; }
|
public ShaderManager ShaderManager { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -61,8 +68,7 @@ namespace osu.Game.Rulesets.UI
|
|||||||
SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
|
SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
|
||||||
CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>()));
|
CacheAs(SampleStore = new FallbackSampleStore(SampleStore, parent.Get<ISampleStore>()));
|
||||||
|
|
||||||
ShaderManager = new ShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"));
|
CacheAs(ShaderManager = new RulesetShaderManager(host.Renderer, new NamespacedResourceStore<byte[]>(resources, @"Shaders"), parent.Get<ShaderManager>()));
|
||||||
CacheAs(ShaderManager = new FallbackShaderManager(host.Renderer, ShaderManager, parent.Get<ShaderManager>()));
|
|
||||||
|
|
||||||
RulesetConfigManager = parent.Get<IRulesetConfigCache>().GetConfigFor(ruleset);
|
RulesetConfigManager = parent.Get<IRulesetConfigCache>().GetConfigFor(ruleset);
|
||||||
if (RulesetConfigManager != null)
|
if (RulesetConfigManager != null)
|
||||||
@ -190,24 +196,27 @@ namespace osu.Game.Rulesets.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FallbackShaderManager : ShaderManager
|
private class RulesetShaderManager : ShaderManager
|
||||||
{
|
{
|
||||||
private readonly ShaderManager primary;
|
private readonly ShaderManager parent;
|
||||||
private readonly ShaderManager fallback;
|
|
||||||
|
|
||||||
public FallbackShaderManager(IRenderer renderer, ShaderManager primary, ShaderManager fallback)
|
public RulesetShaderManager(IRenderer renderer, NamespacedResourceStore<byte[]> rulesetResources, ShaderManager parent)
|
||||||
: base(renderer, new ResourceStore<byte[]>())
|
: base(renderer, rulesetResources)
|
||||||
{
|
{
|
||||||
this.primary = primary;
|
this.parent = parent;
|
||||||
this.fallback = fallback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[]? LoadRaw(string name) => primary.LoadRaw(name) ?? fallback.LoadRaw(name);
|
public override IShader Load(string vertex, string fragment)
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
{
|
||||||
base.Dispose(disposing);
|
try
|
||||||
if (primary.IsNotNull()) primary.Dispose();
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,8 @@ namespace osu.Game.Screens
|
|||||||
|
|
||||||
loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE));
|
loadTargets.Add(manager.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE));
|
||||||
|
|
||||||
|
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_2, "TriangleBorder"));
|
||||||
|
|
||||||
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Realm" Version="10.20.0" />
|
<PackageReference Include="Realm" Version="10.20.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2023.327.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2023.402.1" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.320.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2023.402.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.28.1" />
|
<PackageReference Include="Sentry" Version="3.28.1" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
<PackageReference Include="SharpCompress" Version="0.32.2" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
|
@ -16,6 +16,6 @@
|
|||||||
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
|
<RuntimeIdentifier>iossimulator-x64</RuntimeIdentifier>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.327.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2023.402.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
Reference in New Issue
Block a user