1+ use std:: hash:: Hash ;
12use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
23use std:: sync:: Arc ;
34use std:: time:: Duration ;
45
6+ use ahash:: HashSet ;
7+ use ordered_hash_map:: OrderedHashMap ;
58use parking_lot:: Mutex ;
69
710use crate :: render:: PackedBundle ;
@@ -31,18 +34,18 @@ pub(crate) trait TileProvider<StyleId> {
3134
3235pub ( crate ) struct TilesContainer < StyleId , Provider >
3336where
34- StyleId : Copy ,
37+ StyleId : Copy + Hash + Eq ,
3538 Provider : TileProvider < StyleId > ,
3639{
37- pub ( crate ) tiles : Mutex < Vec < DisplayedTile < StyleId > > > ,
40+ pub ( crate ) tiles : Mutex < OrderedHashMap < ( WrappingTileIndex , StyleId ) , DisplayedTile < StyleId > > > ,
3841 tile_schema : TileSchema ,
3942 pub ( crate ) tile_provider : Provider ,
4043 pub fade_in_duration : AtomicU64 ,
4144}
4245
4346impl < StyleId , Provider > TilesContainer < StyleId , Provider >
4447where
45- StyleId : Copy + PartialEq ,
48+ StyleId : Copy + Hash + Eq ,
4649 Provider : TileProvider < StyleId > ,
4750{
4851 pub ( crate ) fn new ( tile_schema : TileSchema , tile_provider : Provider ) -> Self {
@@ -62,19 +65,20 @@ where
6265 let mut displayed_tiles = self . tiles . lock ( ) ;
6366
6467 let mut needed_tiles = vec ! [ ] ;
68+ let mut tile_indices = HashSet :: default ( ) ;
6569 let mut to_substitute = vec ! [ ] ;
6670
6771 let now = web_time:: Instant :: now ( ) ;
6872 let fade_in_time = self . fade_in_duration ( ) ;
6973 let mut requires_redraw = false ;
7074
7175 for index in needed_indices {
72- if let Some ( displayed) = displayed_tiles
73- . iter_mut ( )
74- . find ( |displayed| displayed. index == index && displayed. style_id == style_id)
75- {
76+ if let Some ( mut displayed) = displayed_tiles. remove ( & ( index, style_id) ) {
7677 if !displayed. is_opaque ( ) {
77- to_substitute. push ( index) ;
78+ if let Some ( bbox) = self . tile_schema . tile_bbox ( index) {
79+ to_substitute. push ( bbox) ;
80+ }
81+
7882 let fade_in_secs = fade_in_time. as_secs_f64 ( ) ;
7983 displayed. opacity = if fade_in_secs > 0.001 {
8084 ( ( now. duration_since ( displayed. displayed_at ) ) . as_secs_f64 ( ) / fade_in_secs)
8690 }
8791
8892 needed_tiles. push ( displayed. clone ( ) ) ;
93+ tile_indices. insert ( ( index, style_id) ) ;
8994 } else {
9095 match self . tile_provider . get_tile ( index. into ( ) , style_id) {
91- None => to_substitute. push ( index) ,
96+ None => {
97+ if let Some ( bbox) = self . tile_schema . tile_bbox ( index) {
98+ to_substitute. push ( bbox) ;
99+ }
100+ }
92101 Some ( bundle) => {
93102 let opacity = if self . requires_animation ( ) { 0.0 } else { 1.0 } ;
94103 needed_tiles. push ( DisplayedTile {
@@ -98,39 +107,46 @@ where
98107 opacity,
99108 displayed_at : now,
100109 } ) ;
101- to_substitute. push ( index) ;
110+ tile_indices. insert ( ( index, style_id) ) ;
111+
112+ if let Some ( bbox) = self . tile_schema . tile_bbox ( index) {
113+ to_substitute. push ( bbox) ;
114+ }
115+
102116 requires_redraw = true ;
103117 }
104118 }
105119 }
106120 }
107121
108- let mut new_displayed = vec ! [ ] ;
109- for displayed in displayed_tiles. iter ( ) {
110- if needed_tiles
111- . iter ( )
112- . any ( |new| new. index == displayed. index && new. style_id == displayed. style_id )
113- {
114- continue ;
115- }
116-
117- let Some ( displayed_bbox) = self . tile_schema . tile_bbox ( displayed. index ) else {
118- continue ;
119- } ;
122+ let mut new_displayed = OrderedHashMap :: new ( ) ;
123+ let mut selected = Vec :: with_capacity ( displayed_tiles. len ( ) ) ;
120124
121- for subst in & to_substitute {
122- let Some ( subst_bbox) = self . tile_schema . tile_bbox ( * subst) else {
125+ for subst_bbox in & to_substitute {
126+ for key in displayed_tiles. keys ( ) {
127+ let Some ( displayed_bbox) = self . tile_schema . tile_bbox ( key. 0 ) else {
123128 continue ;
124129 } ;
125130
126- if displayed_bbox. intersects ( subst_bbox) {
127- new_displayed. push ( displayed. clone ( ) ) ;
128- break ;
131+ if displayed_bbox. intersects ( * subst_bbox) {
132+ selected. push ( * key) ;
129133 }
130134 }
135+
136+ for key in & selected {
137+ let Some ( tile) = displayed_tiles. remove ( key) else {
138+ continue ;
139+ } ;
140+
141+ new_displayed. insert ( * key, tile) ;
142+ }
143+
144+ selected. clear ( ) ;
131145 }
132146
133- new_displayed. append ( & mut needed_tiles) ;
147+ for tile in needed_tiles {
148+ new_displayed. insert ( ( tile. index , tile. style_id ) , tile) ;
149+ }
134150 * displayed_tiles = new_displayed;
135151
136152 requires_redraw
0 commit comments