perf(themes): add pre-computed ABGR cache on theme records
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
using HellionChat.Util;
|
||||||
|
|
||||||
namespace HellionChat.Themes;
|
namespace HellionChat.Themes;
|
||||||
|
|
||||||
public sealed record Theme(
|
public sealed record Theme(
|
||||||
@@ -10,4 +12,47 @@ public sealed record Theme(
|
|||||||
ThemeTypography Typography,
|
ThemeTypography Typography,
|
||||||
bool IsBuiltIn,
|
bool IsBuiltIn,
|
||||||
ThemeChatColors? ChatColors = null
|
ThemeChatColors? ChatColors = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Pre-computed ABGR mirror of ThemeColors so PushGlobal can skip the
|
||||||
|
// RgbaToAbgr conversion per slot per frame.
|
||||||
|
public ThemeAbgrCache AbgrCache { get; private set; }
|
||||||
|
|
||||||
|
public void RecomputeAbgrCache()
|
||||||
|
{
|
||||||
|
AbgrCache = new ThemeAbgrCache(
|
||||||
|
PrimaryDark: ColourUtil.RgbaToAbgr(Colors.PrimaryDark),
|
||||||
|
Primary: ColourUtil.RgbaToAbgr(Colors.Primary),
|
||||||
|
PrimaryLight: ColourUtil.RgbaToAbgr(Colors.PrimaryLight),
|
||||||
|
PrimaryGlow: ColourUtil.RgbaToAbgr(Colors.PrimaryGlow),
|
||||||
|
AccentDark: ColourUtil.RgbaToAbgr(Colors.AccentDark),
|
||||||
|
Accent: ColourUtil.RgbaToAbgr(Colors.Accent),
|
||||||
|
AccentLight: ColourUtil.RgbaToAbgr(Colors.AccentLight),
|
||||||
|
Identity: ColourUtil.RgbaToAbgr(Colors.Identity),
|
||||||
|
WindowBg: ColourUtil.RgbaToAbgr(Colors.WindowBg),
|
||||||
|
ChildBg: ColourUtil.RgbaToAbgr(Colors.ChildBg),
|
||||||
|
FrameBg: ColourUtil.RgbaToAbgr(Colors.FrameBg),
|
||||||
|
Surface: ColourUtil.RgbaToAbgr(Colors.Surface),
|
||||||
|
SurfaceHover: ColourUtil.RgbaToAbgr(Colors.SurfaceHover),
|
||||||
|
Border: ColourUtil.RgbaToAbgr(Colors.Border),
|
||||||
|
TextPrimary: ColourUtil.RgbaToAbgr(Colors.TextPrimary),
|
||||||
|
TextMuted: ColourUtil.RgbaToAbgr(Colors.TextMuted),
|
||||||
|
TextDim: ColourUtil.RgbaToAbgr(Colors.TextDim),
|
||||||
|
StatusSuccess: ColourUtil.RgbaToAbgr(Colors.StatusSuccess),
|
||||||
|
StatusDanger: ColourUtil.RgbaToAbgr(Colors.StatusDanger),
|
||||||
|
StatusWarning: ColourUtil.RgbaToAbgr(Colors.StatusWarning),
|
||||||
|
StatusInfo: ColourUtil.RgbaToAbgr(Colors.StatusInfo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mirrors ThemeColors slot-for-slot. The FillsAll21Slots test pins the
|
||||||
|
// contract — a new slot without its mirror fails the build.
|
||||||
|
public readonly record struct ThemeAbgrCache(
|
||||||
|
uint PrimaryDark, uint Primary, uint PrimaryLight, uint PrimaryGlow,
|
||||||
|
uint AccentDark, uint Accent, uint AccentLight,
|
||||||
|
uint Identity,
|
||||||
|
uint WindowBg, uint ChildBg, uint FrameBg,
|
||||||
|
uint Surface, uint SurfaceHover, uint Border,
|
||||||
|
uint TextPrimary, uint TextMuted, uint TextDim,
|
||||||
|
uint StatusSuccess, uint StatusDanger, uint StatusWarning, uint StatusInfo
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ public sealed class ThemeRegistry
|
|||||||
{ ForgeMerchantman.Slug, ForgeMerchantman.Build() },
|
{ ForgeMerchantman.Slug, ForgeMerchantman.Build() },
|
||||||
{ MintGrove.Slug, MintGrove.Build() },
|
{ MintGrove.Slug, MintGrove.Build() },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Centralised so the nine .Build() factories stay free of cache plumbing.
|
||||||
|
foreach (var theme in _builtIns.Values)
|
||||||
|
theme.RecomputeAbgrCache();
|
||||||
|
|
||||||
_active = _builtIns[DefaultSlug];
|
_active = _builtIns[DefaultSlug];
|
||||||
_customThemesDir = customThemesDir;
|
_customThemesDir = customThemesDir;
|
||||||
}
|
}
|
||||||
@@ -81,6 +86,7 @@ public sealed class ThemeRegistry
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
theme = ThemeJsonLoader.LoadFromFile(path);
|
theme = ThemeJsonLoader.LoadFromFile(path);
|
||||||
|
theme.RecomputeAbgrCache();
|
||||||
_customCache[key] = (theme, stamp);
|
_customCache[key] = (theme, stamp);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
Reference in New Issue
Block a user