From 67109d882797e2408cb456adf04465a2cb3d7401 Mon Sep 17 00:00:00 2001 From: Maximilian Ammann Date: Fri, 25 Mar 2022 16:14:27 +0100 Subject: [PATCH] First version of keeping-tiles until next ones finished --- src/coords.rs | 72 ++++++++++++++++++++------------------ src/render/buffer_pool.rs | 29 +++++++++++++++ src/render/render_state.rs | 59 +++++++++++++++++-------------- 3 files changed, 100 insertions(+), 60 deletions(-) diff --git a/src/coords.rs b/src/coords.rs index 52928d45..35e1ba9d 100644 --- a/src/coords.rs +++ b/src/coords.rs @@ -55,40 +55,6 @@ impl TileCoords { }, }) } - - /// Get the tile which is one zoom level lower and contains this one - pub fn get_parent(&self) -> [TileCoords; 4] { - [ - TileCoords { - x: self.x * 2, - y: self.y * 2, - z: self.z + 1, - }, - TileCoords { - x: self.x * 2 + 1, - y: self.y * 2, - z: self.z + 1, - }, - TileCoords { - x: self.x * 2 + 1, - y: self.y * 2 + 1, - z: self.z + 1, - }, - TileCoords { - x: self.x * 2, - y: self.y * 2 + 1, - z: self.z + 1, - }, - ] - } - - pub fn get_children(&self) -> TileCoords { - TileCoords { - x: self.x >> 1, - y: self.y >> 1, - z: self.z - 1, - } - } } impl From<(u32, u32, u8)> for TileCoords { @@ -192,6 +158,44 @@ impl WorldTileCoords { } key } + + pub fn get_children(&self) -> [WorldTileCoords; 4] { + [ + WorldTileCoords { + x: self.x * 2, + y: self.y * 2, + z: self.z + 1, + }, + WorldTileCoords { + x: self.x * 2 + 1, + y: self.y * 2, + z: self.z + 1, + }, + WorldTileCoords { + x: self.x * 2 + 1, + y: self.y * 2 + 1, + z: self.z + 1, + }, + WorldTileCoords { + x: self.x * 2, + y: self.y * 2 + 1, + z: self.z + 1, + }, + ] + } + + /// Get the tile which is one zoom level lower and contains this one + pub fn get_parent(&self) -> Option { + if self.z == 0 { + return None; + } + + Some(WorldTileCoords { + x: self.x >> 1, + y: self.y >> 1, + z: self.z - 1, + }) + } } impl From<(i32, i32, u8)> for WorldTileCoords { diff --git a/src/render/buffer_pool.rs b/src/render/buffer_pool.rs index 00e5bfbb..2c947389 100644 --- a/src/render/buffer_pool.rs +++ b/src/render/buffer_pool.rs @@ -415,6 +415,29 @@ impl RingIndex { self.tree_index.get(coords.to_quad_key().as_slice()) } + pub fn get_layers_fallback(&self, coords: &WorldTileCoords) -> Option<&VecDeque> { + let mut current = *coords; + + /*index.get_layers(&world_coords) + .or_else(|| { + world_coords + .get_parent() + .and_then(|parent| index.get_layers(&parent)) + })*/ + + loop { + if let Some(entries) = self.get_layers(¤t) { + return Some(entries); + } else { + if let Some(parent) = current.get_parent() { + current = parent + } else { + return None; + } + } + } + } + pub fn pop_front(&mut self) -> Option { if let Some(entries) = self .linear_index @@ -440,6 +463,12 @@ impl RingIndex { self.linear_index.push_back(key) } + + pub fn iter(&self) -> impl Iterator> + '_ { + self.linear_index + .iter() + .flat_map(|key| self.tree_index.get(key)) + } } #[cfg(test)] diff --git a/src/render/render_state.rs b/src/render/render_state.rs index 01e0a436..c4226e65 100644 --- a/src/render/render_state.rs +++ b/src/render/render_state.rs @@ -381,42 +381,47 @@ impl RenderState { } let view_proj = self.camera.calc_view_proj(&self.perspective); - // Factor which determines how much we need to adjust the width of lines for example. - // If zoom == z -> zoom_factor == 1 - let zoom_factor = 2.0_f64.powf(visible_z as f64 - self.zoom) as f32; // Update tile metadata for all required tiles on the GPU according to current zoom, camera and perspective // We perform the update before uploading new tessellated tiles, such that each // tile metadata in the the `buffer_pool` gets updated exactly once and not twice. - if let Some(view_region) = &view_region { - for world_coords in view_region.iter() { - if let Some(entries) = self.buffer_pool.index().get_layers(&world_coords) { - for entry in entries { - let transform: Matrix4 = (view_proj - * entry.coords.transform_for_zoom(self.zoom)) - .cast() - .unwrap(); - self.buffer_pool.update_tile_metadata( - &self.queue, - entry, - ShaderTileMetadata::new( - transform.into(), - zoom_factor, - entry.style_layer.index as f32, - ), - ); - } - } + for entries in self.buffer_pool.index().iter() { + for entry in entries { + let world_coords = entry.coords; + + // Factor which determines how much we need to adjust the width of lines for example. + // If zoom == z -> zoom_factor == 1 + let zoom_factor = 2.0_f64.powf(world_coords.z as f64 - self.zoom) as f32; + + let transform: Matrix4 = (view_proj + * world_coords.transform_for_zoom(self.zoom)) + .cast() + .unwrap(); + + self.buffer_pool.update_tile_metadata( + &self.queue, + entry, + ShaderTileMetadata::new( + transform.into(), + zoom_factor, + entry.style_layer.index as f32, + ), + ); } } + // Factor which determines how much we need to adjust the width of lines for example. + // If zoom == z -> zoom_factor == 1 + let zoom_factor = 2.0_f64.powf(visible_z as f64 - self.zoom) as f32; + // Upload all tessellated layers which are in view if let Some(view_region) = &view_region { - for coords in view_region.iter() { - let loaded_layers = self.buffer_pool.get_loaded_layers_at(&coords); + for world_coords in view_region.iter() { + let loaded_layers = self.buffer_pool.get_loaded_layers_at(&world_coords); - let available_layers = scheduler.get_tessellated_layers_at(&coords, &loaded_layers); + let available_layers = + scheduler.get_tessellated_layers_at(&world_coords, &loaded_layers); for style_layer in &self.style.layers { let source_layer = style_layer.source_layer.as_ref().unwrap(); @@ -557,9 +562,11 @@ impl RenderState { .view_region_bounding_box(&self.perspective) .map(|bounding_box| ViewRegion::new(bounding_box, 2, self.zoom, visible_z)); + let index = self.buffer_pool.index(); + if let Some(view_region) = &view_region { for world_coords in view_region.iter() { - if let Some(entries) = self.buffer_pool.index().get_layers(&world_coords) { + if let Some(entries) = index.get_layers_fallback(&world_coords) { let mut to_render: Vec<&IndexEntry> = Vec::from_iter(entries); to_render.sort_by_key(|entry| entry.style_layer.index);