1- using System . Collections . Generic ;
1+ using System . Collections . Concurrent ;
22using System . Runtime . CompilerServices ;
33using SkiaSharp ;
44
@@ -7,47 +7,51 @@ namespace VexTile.Renderer.Mvt.AliFlux;
77// ReSharper disable once InconsistentNaming
88public static class SKColorFactory
99{
10- private static readonly Dictionary < string , SKColor > Colours = new ( ) ;
10+ // Use packed ARGB (0xAARRGGBB) as the key to avoid string allocations
11+ private static readonly ConcurrentDictionary < uint , SKColor > Colours = new ( ) ;
1112
1213 // try to centralise this as tracking down where colours ar made is hard
1314 public static SKColor MakeColor ( byte red , byte green , byte blue , byte alpha = 255 , [ CallerMemberName ] string callerName = "<unknown>" )
1415 {
15- string key = MakeKey ( red , green , blue , alpha ) ;
16+ uint key = MakeKey ( red , green , blue , alpha ) ;
1617
17- if ( ! Colours . TryGetValue ( key , out SKColor color ) )
18- {
19- color = new SKColor ( red , green , blue , alpha ) ;
20- Colours [ key ] = color ;
18+ var color = Colours . GetOrAdd ( key , _ => new SKColor ( red , green , blue , alpha ) ) ;
2119
2220#if DEBUG_COLORS
23- log . Debug ( $ "{ callerName } -> Created { key } :: SKColorFactory.MakeColor({ red } , { green } , { blue } , { alpha } )") ;
21+ var hex = MakeKeyHex ( red , green , blue , alpha ) ; // RRGGBBAA for readability
22+ log . Debug ( $ "{ callerName } -> GetOrAdd { hex } :: SKColorFactory.MakeColor({ red } , { green } , { blue } , { alpha } )") ;
2423#endif
25- }
26- else
27- {
28- #if DEBUG_COLORS
29- log . Debug ( $ "{ callerName } -> Got { key } :: SKColorFactory.MakeColor") ;
30- #endif
31- }
3224
3325 return color ;
3426 }
3527
36- private static string MakeKey ( byte red , byte green , byte blue , byte alpha )
28+ private static uint MakeKey ( byte red , byte green , byte blue , byte alpha )
3729 {
38- string key = $ " { red : x2 } { green : x2 } { blue : x2 } { alpha : x2 } " ;
39- return key ;
30+ // ARGB packed to match SKColor's internal layout
31+ return ( ( uint ) alpha << 24 ) | ( ( uint ) red << 16 ) | ( ( uint ) green << 8 ) | blue ;
4032 }
4133
42- // make logging colors simpler
34+ #if DEBUG_COLORS
35+ // Keep previous readable logging format (RRGGBBAA)
36+ private static string MakeKeyHex ( byte red , byte green , byte blue , byte alpha )
37+ {
38+ return $ "{ red : x2} { green : x2} { blue : x2} { alpha : x2} ";
39+ }
40+ #endif
41+
42+ // Make logging colors simpler
4343 public static SKColor LogColor ( SKColor color , [ CallerMemberName ] string callerName = "<unknown>" )
4444 {
45- string key = MakeKey ( color . Red , color . Green , color . Blue , color . Alpha ) ;
45+ // Use the packed ARGB from the color directly
46+ uint key = ( uint ) color ;
47+
48+ _ = Colours . TryAdd ( key , color ) ;
49+
50+ #if DEBUG_COLORS
51+ var hex = MakeKeyHex ( color . Red , color . Green , color . Blue , color . Alpha ) ;
52+ log . Debug ( $ "{ callerName } -> Log { hex } :: SKColorFactory.LogColor") ;
53+ #endif
4654
47- if ( ! Colours . TryGetValue ( key , out _ ) )
48- {
49- Colours . Add ( key , color ) ;
50- }
5155 return color ;
5256 }
5357}
0 commit comments