1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-15 09:42:57 +08:00

Cache argon character glyph lookups to reduce string allocations

This commit is contained in:
Dean Herbert 2024-01-05 01:24:00 +09:00
parent 35b9940c4e
commit 91bb3f6c57
No known key found for this signature in database

View File

@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -137,33 +139,48 @@ namespace osu.Game.Screens.Play.HUD
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(TextureStore textures) private void load(TextureStore textures)
{ {
const string font_name = @"argon-counter";
Spacing = new Vector2(-2f, 0f); Spacing = new Vector2(-2f, 0f);
Font = new FontUsage(@"argon-counter", 1); Font = new FontUsage(font_name, 1);
glyphStore = new GlyphStore(textures, getLookup); glyphStore = new GlyphStore(font_name, textures, getLookup);
} }
protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore); protected override TextBuilder CreateTextBuilder(ITexturedGlyphLookupStore store) => base.CreateTextBuilder(glyphStore);
private class GlyphStore : ITexturedGlyphLookupStore private class GlyphStore : ITexturedGlyphLookupStore
{ {
private readonly string fontName;
private readonly TextureStore textures; private readonly TextureStore textures;
private readonly Func<char, string> getLookup; private readonly Func<char, string> getLookup;
public GlyphStore(TextureStore textures, Func<char, string> getLookup) private readonly Dictionary<char, ITexturedCharacterGlyph?> cache = new Dictionary<char, ITexturedCharacterGlyph?>();
public GlyphStore(string fontName, TextureStore textures, Func<char, string> getLookup)
{ {
this.fontName = fontName;
this.textures = textures; this.textures = textures;
this.getLookup = getLookup; this.getLookup = getLookup;
} }
public ITexturedCharacterGlyph? Get(string? fontName, char character) public ITexturedCharacterGlyph? Get(string? fontName, char character)
{ {
// We only service one font.
Debug.Assert(fontName == this.fontName);
if (cache.TryGetValue(character, out var cached))
return cached;
string lookup = getLookup(character); string lookup = getLookup(character);
var texture = textures.Get($"Gameplay/Fonts/{fontName}-{lookup}"); var texture = textures.Get($"Gameplay/Fonts/{fontName}-{lookup}");
if (texture == null) TexturedCharacterGlyph? glyph = null;
return null;
return new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, texture.Height, null), texture, 0.125f); if (texture != null)
glyph = new TexturedCharacterGlyph(new CharacterGlyph(character, 0, 0, texture.Width, texture.Height, null), texture, 0.125f);
cache[character] = glyph;
return glyph;
} }
public Task<ITexturedCharacterGlyph?> GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character)); public Task<ITexturedCharacterGlyph?> GetAsync(string fontName, char character) => Task.Run(() => Get(fontName, character));