// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Collections.Generic; using System.Linq; using osuTK; namespace osu.Framework.Graphics.Shaders { internal static class GlobalPropertyManager { private static readonly HashSet all_shaders = new HashSet(); private static readonly IUniformMapping[] global_properties; static GlobalPropertyManager() { var values = Enum.GetValues(typeof(GlobalProperty)).OfType().ToArray(); global_properties = new IUniformMapping[values.Length]; global_properties[(int)GlobalProperty.ProjMatrix] = new UniformMapping("g_ProjMatrix"); global_properties[(int)GlobalProperty.MaskingRect] = new UniformMapping("g_MaskingRect"); global_properties[(int)GlobalProperty.ToMaskingSpace] = new UniformMapping("g_ToMaskingSpace"); global_properties[(int)GlobalProperty.CornerRadius] = new UniformMapping("g_CornerRadius"); global_properties[(int)GlobalProperty.CornerExponent] = new UniformMapping("g_CornerExponent"); global_properties[(int)GlobalProperty.BorderThickness] = new UniformMapping("g_BorderThickness"); global_properties[(int)GlobalProperty.BorderColour] = new UniformMapping("g_BorderColour"); global_properties[(int)GlobalProperty.MaskingBlendRange] = new UniformMapping("g_MaskingBlendRange"); global_properties[(int)GlobalProperty.AlphaExponent] = new UniformMapping("g_AlphaExponent"); global_properties[(int)GlobalProperty.EdgeOffset] = new UniformMapping("g_EdgeOffset"); global_properties[(int)GlobalProperty.DiscardInner] = new UniformMapping("g_DiscardInner"); global_properties[(int)GlobalProperty.InnerCornerRadius] = new UniformMapping("g_InnerCornerRadius"); global_properties[(int)GlobalProperty.GammaCorrection] = new UniformMapping("g_GammaCorrection"); global_properties[(int)GlobalProperty.WrapModeS] = new UniformMapping("g_WrapModeS"); global_properties[(int)GlobalProperty.WrapModeT] = new UniformMapping("g_WrapModeT"); // Backbuffer internals global_properties[(int)GlobalProperty.BackbufferDraw] = new UniformMapping("g_BackbufferDraw"); } /// /// Sets a uniform for all shaders that contain this property. /// Any future-initialized shaders will also have this uniform set. /// /// The uniform. /// The uniform value. public static void Set(GlobalProperty property, T value) where T : struct, IEquatable { ((UniformMapping)global_properties[(int)property]).UpdateValue(ref value); } public static void Register(Shader shader) { if (!all_shaders.Add(shader)) return; // transfer all existing global properties across. foreach (var global in global_properties) { if (!shader.Uniforms.TryGetValue(global.Name, out IUniform uniform)) continue; global.LinkShaderUniform(uniform); } } public static void Unregister(Shader shader) { if (!all_shaders.Remove(shader)) return; foreach (var global in global_properties) { if (!shader.Uniforms.TryGetValue(global.Name, out IUniform uniform)) continue; global.UnlinkShaderUniform(uniform); } } /// /// Check whether a global uniform exists with the specified name. /// /// The name to check /// Whether a global exists. public static bool CheckGlobalExists(string name) => global_properties.Any(m => m.Name == name); } }