|
|
@@ -95,21 +95,37 @@ impl<'a> TileCacheGl<'a> {
|
|
95
|
95
|
slot
|
|
96
|
96
|
}
|
|
97
|
97
|
|
|
98
|
|
- pub fn textured_visible_tiles(
|
|
|
98
|
+ /// Finds textures from the cache for a given slice of visible tiles. The texture atlas may not
|
|
|
99
|
+ /// be big enough to hold all textures at once; a possible remainder of untextured visible tiles is
|
|
|
100
|
+ /// returned as an `Option`.
|
|
|
101
|
+ /// The function guarantees that no more than `max_tiles_to_use` tiles are used for texturing;
|
|
|
102
|
+ /// the number of used tiles is returned as an `usize`.
|
|
|
103
|
+ pub fn textured_visible_tiles<'b>(
|
|
99
|
104
|
&mut self,
|
|
100
|
|
- visible_tiles: &[VisibleTile],
|
|
|
105
|
+ visible_tiles: &'b [VisibleTile],
|
|
|
106
|
+ max_tiles_to_use: usize,
|
|
101
|
107
|
source: &TileSource,
|
|
102
|
108
|
cache: &mut TileCache,
|
|
103
|
|
- ) -> Vec<TexturedVisibleTile>
|
|
|
109
|
+ ) -> (Vec<TexturedVisibleTile>, Option<&'b [VisibleTile]>, usize)
|
|
104
|
110
|
{
|
|
105
|
111
|
let mut tvt = Vec::with_capacity(visible_tiles.len());
|
|
106
|
112
|
|
|
107
|
113
|
let inset_x = 0.5 / f64::from(self.texture.width());
|
|
108
|
114
|
let inset_y = 0.5 / f64::from(self.texture.height());
|
|
109
|
115
|
|
|
110
|
|
- for vt in visible_tiles {
|
|
|
116
|
+ let num_usable_slots = self.slots_lru.len();
|
|
|
117
|
+ // The number of actually used slots may be lower, because slots can be used multiple times
|
|
|
118
|
+ // in the same view (especially the default slot).
|
|
|
119
|
+ let mut used_slots = 0_usize;
|
|
|
120
|
+
|
|
|
121
|
+ for (i, vt) in visible_tiles.iter().enumerate() {
|
|
|
122
|
+ if used_slots >= num_usable_slots || used_slots >= max_tiles_to_use {
|
|
|
123
|
+ return (tvt, Some(&visible_tiles[i..]), used_slots);
|
|
|
124
|
+ }
|
|
|
125
|
+
|
|
111
|
126
|
if let Some(slot) = self.store(vt.tile, source, cache, true) {
|
|
112
|
127
|
let tex_rect = self.slot_to_texture_rect(slot);
|
|
|
128
|
+ used_slots += 1;
|
|
113
|
129
|
tvt.push(
|
|
114
|
130
|
TexturedVisibleTile {
|
|
115
|
131
|
screen_rect: vt.rect,
|
|
|
@@ -120,6 +136,10 @@ impl<'a> TileCacheGl<'a> {
|
|
120
|
136
|
} else {
|
|
121
|
137
|
// exact tile not found
|
|
122
|
138
|
|
|
|
139
|
+ if used_slots + 5 > num_usable_slots || used_slots + 5 > max_tiles_to_use {
|
|
|
140
|
+ return (tvt, Some(&visible_tiles[i..]), used_slots);
|
|
|
141
|
+ }
|
|
|
142
|
+
|
|
123
|
143
|
// default tile
|
|
124
|
144
|
let mut tex_sub_rect = self.slot_to_texture_rect(Self::default_slot());
|
|
125
|
145
|
let mut tex_rect = tex_sub_rect;
|
|
|
@@ -128,6 +148,7 @@ impl<'a> TileCacheGl<'a> {
|
|
128
|
148
|
for dist in 1..31 {
|
|
129
|
149
|
if let Some((parent_tile, sub_coord)) = vt.tile.parent(dist) {
|
|
130
|
150
|
if let Some(slot) = self.store(parent_tile, source, cache, false) {
|
|
|
151
|
+ used_slots += 1;
|
|
131
|
152
|
tex_sub_rect = self.subslot_to_texture_rect(slot, sub_coord);
|
|
132
|
153
|
tex_rect = self.slot_to_texture_rect(slot);
|
|
133
|
154
|
break;
|
|
|
@@ -140,6 +161,7 @@ impl<'a> TileCacheGl<'a> {
|
|
140
|
161
|
// look for cached tiles in higher zoom layers
|
|
141
|
162
|
for &(child_tile, child_sub_coord) in &vt.tile.children() {
|
|
142
|
163
|
if let Some(slot) = self.store(child_tile, source, cache, false) {
|
|
|
164
|
+ used_slots += 1;
|
|
143
|
165
|
let tex_rect = self.slot_to_texture_rect(slot);
|
|
144
|
166
|
|
|
145
|
167
|
tvt.push(
|
|
|
@@ -162,7 +184,7 @@ impl<'a> TileCacheGl<'a> {
|
|
162
|
184
|
};
|
|
163
|
185
|
}
|
|
164
|
186
|
|
|
165
|
|
- tvt
|
|
|
187
|
+ (tvt, None, used_slots)
|
|
166
|
188
|
}
|
|
167
|
189
|
|
|
168
|
190
|
fn slot_to_texture_rect(&self, slot: CacheSlot) -> TextureRect {
|