1- use std:: sync:: atomic:: { AtomicU64 , Ordering :: Relaxed } ;
2-
31use emath:: Vec2 ;
42
53use super :: {
@@ -17,18 +15,23 @@ struct PrimaryKey {
1715type Bucket = HashMap < Option < SizeHint > , Entry > ;
1816
1917struct Entry {
20- last_used : AtomicU64 ,
18+ last_used : u64 ,
2119
2220 /// Size of the original SVG, if any, or the texel size of the image if not an SVG.
2321 source_size : Vec2 ,
2422
2523 handle : TextureHandle ,
2624}
2725
26+ #[ derive( Default ) ]
27+ struct State {
28+ pass_index : u64 ,
29+ cache : HashMap < PrimaryKey , Bucket > ,
30+ }
31+
2832#[ derive( Default ) ]
2933pub struct DefaultTextureLoader {
30- pass_index : AtomicU64 ,
31- cache : Mutex < HashMap < PrimaryKey , Bucket > > ,
34+ state : Mutex < State > ,
3235}
3336
3437impl TextureLoader for DefaultTextureLoader {
@@ -55,18 +58,18 @@ impl TextureLoader for DefaultTextureLoader {
5558 None
5659 } ;
5760
58- let mut cache = self . cache . lock ( ) ;
61+ let mut state = self . state . lock ( ) ;
62+ let State { pass_index, cache } = & mut * state;
63+
5964 let bucket = cache
6065 . entry ( PrimaryKey {
6166 uri : uri. to_owned ( ) ,
6267 texture_options,
6368 } )
6469 . or_default ( ) ;
6570
66- if let Some ( texture) = bucket. get ( & svg_size_hint) {
67- texture
68- . last_used
69- . store ( self . pass_index . load ( Relaxed ) , Relaxed ) ;
71+ if let Some ( texture) = bucket. get_mut ( & svg_size_hint) {
72+ texture. last_used = * pass_index;
7073 let texture = SizedTexture :: new ( texture. handle . id ( ) , texture. source_size ) ;
7174 Ok ( TexturePoll :: Ready { texture } )
7275 } else {
@@ -79,7 +82,7 @@ impl TextureLoader for DefaultTextureLoader {
7982 bucket. insert (
8083 svg_size_hint,
8184 Entry {
82- last_used : AtomicU64 :: new ( self . pass_index . load ( Relaxed ) ) ,
85+ last_used : * pass_index,
8386 source_size,
8487 handle,
8588 } ,
@@ -104,33 +107,37 @@ impl TextureLoader for DefaultTextureLoader {
104107 fn forget ( & self , uri : & str ) {
105108 log:: trace!( "forget {uri:?}" ) ;
106109
107- self . cache . lock ( ) . retain ( |key, _value| key. uri != uri) ;
110+ self . state . lock ( ) . cache . retain ( |key, _value| key. uri != uri) ;
108111 }
109112
110113 fn forget_all ( & self ) {
111114 log:: trace!( "forget all" ) ;
112115
113- self . cache . lock ( ) . clear ( ) ;
116+ self . state . lock ( ) . cache . clear ( ) ;
114117 }
115118
116119 fn end_pass ( & self , pass_index : u64 ) {
117- self . pass_index . store ( pass_index, Relaxed ) ;
118- let mut cache = self . cache . lock ( ) ;
120+ let mut state = self . state . lock ( ) ;
121+ state. pass_index = pass_index;
122+
123+ let State { pass_index, cache } = & mut * state;
124+
119125 cache. retain ( |_key, bucket| {
120126 if 2 <= bucket. len ( ) {
121127 // There are multiple textures of the same URI (e.g. SVGs of different scales).
122128 // This could be because someone has an SVG in a resizable container,
123129 // and so we get a lot of different sizes of it.
124130 // This could wast VRAM, so we remove the ones that are not used in this frame.
125- bucket. retain ( |_, texture| pass_index <= texture. last_used . load ( Relaxed ) + 1 ) ;
131+ bucket. retain ( |_, texture| * pass_index <= texture. last_used + 1 ) ;
126132 }
127133 !bucket. is_empty ( )
128134 } ) ;
129135 }
130136
131137 fn byte_size ( & self ) -> usize {
132- self . cache
138+ self . state
133139 . lock ( )
140+ . cache
134141 . values ( )
135142 . map ( |bucket| {
136143 bucket
0 commit comments