Check buffer pool instead of tile cache

This commit is contained in:
Maximilian Ammann 2022-04-05 17:25:45 +02:00
parent 567fb1c1d7
commit ad620397ae
6 changed files with 87 additions and 57 deletions

View File

@ -118,7 +118,7 @@ impl ThreadLocalState {
};
self.tessellate_layers_with_request(&tile_result, &tile_request, request_id)?;
self.index_geometry(&tile_result);
/*self.index_geometry(&tile_result);*/
}
Ok(())
@ -298,12 +298,12 @@ impl Scheduler {
if let Ok(mut tile_request_state) = self.tile_request_state.try_lock() {
if let Ok(result) = self.tessellate_channel.1.try_recv() {
match result {
TessellateMessage::Tile(TileTessellateMessage { request_id }) => {
tile_request_state.finish_tile_request(request_id);
}
TessellateMessage::Layer(layer_result) => {
self.tile_cache.put_tessellated_layer(layer_result);
}
TessellateMessage::Tile(TileTessellateMessage { request_id }) => {
tile_request_state.finish_tile_request(request_id);
}
}
}
}

View File

@ -4,9 +4,21 @@ use crate::io::LayerTessellateMessage;
use std::collections::{btree_map, BTreeMap, HashSet};
pub struct CachedTile {
layers: Vec<LayerTessellateMessage>,
}
impl CachedTile {
pub fn new(first_layer: LayerTessellateMessage) -> Self {
Self {
layers: vec![first_layer],
}
}
}
#[derive(Default)]
pub struct TileCache {
cache: BTreeMap<Quadkey, Vec<LayerTessellateMessage>>,
cache: BTreeMap<Quadkey, CachedTile>,
}
impl TileCache {
@ -24,48 +36,15 @@ impl TileCache {
{
match entry {
btree_map::Entry::Vacant(entry) => {
entry.insert(vec![message]);
entry.insert(CachedTile::new(message));
}
btree_map::Entry::Occupied(mut entry) => {
entry.get_mut().push(message);
entry.get_mut().layers.push(message);
}
}
}
}
pub fn has_tile(&self, coords: &WorldTileCoords) -> bool {
coords
.build_quad_key()
.and_then(|key| {
self.cache.get(&key).and_then(|entries| {
if entries.is_empty() {
None
} else if entries.iter().all(|entry| match entry {
LayerTessellateMessage::UnavailableLayer { .. } => true,
LayerTessellateMessage::TessellatedLayer { .. } => false,
}) {
None
} else {
Some(entries)
}
})
})
.is_some()
}
pub fn get_tile_coords_fallback(&self, coords: &WorldTileCoords) -> Option<WorldTileCoords> {
let mut current = *coords;
loop {
if self.has_tile(&current) {
return Some(current);
} else if let Some(parent) = current.get_parent() {
current = parent
} else {
return None;
}
}
}
pub fn iter_tessellated_layers_at(
&self,
coords: &WorldTileCoords,
@ -73,7 +52,7 @@ impl TileCache {
coords
.build_quad_key()
.and_then(|key| self.cache.get(&key))
.map(|results| results.iter())
.map(|results| results.layers.iter())
}
pub fn retain_missing_layer_names(
@ -81,8 +60,9 @@ impl TileCache {
coords: &WorldTileCoords,
layers: &mut HashSet<String>,
) {
if let Some(results) = coords.build_quad_key().and_then(|key| self.cache.get(&key)) {
let tessellated_set: HashSet<String> = results
if let Some(cached_tile) = coords.build_quad_key().and_then(|key| self.cache.get(&key)) {
let tessellated_set: HashSet<String> = cached_tile
.layers
.iter()
.map(|tessellated_layer| tessellated_layer.layer_name().to_string())
.collect();
@ -92,8 +72,9 @@ impl TileCache {
}
pub fn is_layers_missing(&self, coords: &WorldTileCoords, layers: &HashSet<String>) -> bool {
if let Some(results) = coords.build_quad_key().and_then(|key| self.cache.get(&key)) {
let tessellated_set: HashSet<&str> = results
if let Some(cached_tile) = coords.build_quad_key().and_then(|key| self.cache.get(&key)) {
let tessellated_set: HashSet<&str> = cached_tile
.layers
.iter()
.map(|tessellated_layer| tessellated_layer.layer_name())
.collect();

View File

@ -464,6 +464,26 @@ impl RingIndex {
}
}
pub fn has_tile(&self, coords: &WorldTileCoords) -> bool {
coords
.build_quad_key()
.and_then(|key| self.tree_index.get(&key))
.is_some()
}
pub fn get_tile_coords_fallback(&self, coords: &WorldTileCoords) -> Option<WorldTileCoords> {
let mut current = *coords;
loop {
if self.has_tile(&current) {
return Some(current);
} else if let Some(parent) = current.get_parent() {
current = parent
} else {
return None;
}
}
}
pub fn iter(&self) -> impl Iterator<Item = impl Iterator<Item = &IndexEntry>> + '_ {
self.linear_index
.iter()

View File

@ -6,7 +6,7 @@ pub const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32; // Must m
pub const VERTEX_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32;
pub const FEATURE_METADATA_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32;
pub const INDICES_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 16;
pub const TILE_VIEW_BUFFER_SIZE: BufferAddress = 4096;
pub const INDICES_BUFFER_SIZE: BufferAddress = 1024 * 1024 * 32;
pub const LAYER_METADATA_BUFFER_SIZE: BufferAddress = 1024 * 24;
pub const TILE_META_COUNT: BufferAddress = 1024 * 24;
pub const TILE_VIEW_BUFFER_SIZE: BufferAddress = 4096;

View File

@ -19,7 +19,7 @@ use crate::render::camera;
use crate::render::camera::ViewProjection;
use crate::render::options::{
DEBUG_WIREFRAME, FEATURE_METADATA_BUFFER_SIZE, INDEX_FORMAT, INDICES_BUFFER_SIZE,
TILE_META_COUNT, TILE_VIEW_BUFFER_SIZE, VERTEX_BUFFER_SIZE,
LAYER_METADATA_BUFFER_SIZE, TILE_VIEW_BUFFER_SIZE, VERTEX_BUFFER_SIZE,
};
use crate::render::tile_view_pattern::{TileInView, TileViewPattern};
use crate::tessellation::IndexDataType;
@ -167,7 +167,7 @@ impl RenderState {
cmp::max(MIN_BUFFER_SIZE, std::mem::size_of::<ShaderGlobals>() as u64);
let layer_metadata_buffer_size =
std::mem::size_of::<ShaderLayerMetadata>() as u64 * TILE_META_COUNT;
std::mem::size_of::<ShaderLayerMetadata>() as u64 * LAYER_METADATA_BUFFER_SIZE;
let layer_metadata_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Layer Metadata ubo"),
size: layer_metadata_buffer_size,
@ -388,8 +388,12 @@ impl RenderState {
view_region: &ViewRegion,
view_proj: &ViewProjection,
) {
self.tile_view_pattern
.update_pattern(view_region, scheduler.get_tile_cache(), self.zoom);
self.tile_view_pattern.update_pattern(
view_region,
scheduler.get_tile_cache(),
&self.buffer_pool,
self.zoom,
);
self.tile_view_pattern
.upload_pattern(&self.queue, view_proj);
@ -520,6 +524,7 @@ impl RenderState {
})
.collect::<Vec<_>>();
tracing::trace!("Allocating geometry at {}", &coords);
self.buffer_pool.allocate_layer_geometry(
&self.queue,
*coords,
@ -708,6 +713,8 @@ impl RenderState {
pass.draw_indexed(entry.indices_range(), 0, 0..1);
}
}
} else {
tracing::trace!("No layers found at {}", &shape_to_render.coords);
}
}
}

View File

@ -1,13 +1,16 @@
use crate::coords::{ViewRegion, WorldTileCoords};
use crate::io::tile_cache::TileCache;
use crate::render::buffer_pool::{BackingBufferDescriptor, Queue};
use crate::render::buffer_pool::{BackingBufferDescriptor, BufferPool, Queue};
use crate::render::camera::ViewProjection;
use crate::render::shaders::ShaderTileMetadata;
use crate::render::shaders::{ShaderFeatureStyle, ShaderLayerMetadata, ShaderTileMetadata};
use cgmath::Matrix4;
use crate::render::ShaderVertex;
use crate::tessellation::IndexDataType;
use std::marker::PhantomData;
use std::mem::size_of;
use std::ops::Range;
use wgpu::Buffer;
/// The tile mask pattern assigns each tile a value which can be used for stencil testing.
pub struct TileViewPattern<Q, B> {
@ -55,7 +58,20 @@ impl<Q: Queue<B>, B> TileViewPattern<Q, B> {
}
#[tracing::instrument(skip_all)]
pub fn update_pattern(&mut self, view_region: &ViewRegion, tile_cache: &TileCache, zoom: f64) {
pub fn update_pattern(
&mut self,
view_region: &ViewRegion,
tile_cache: &TileCache,
buffer_pool: &BufferPool<
wgpu::Queue,
Buffer,
ShaderVertex,
IndexDataType,
ShaderLayerMetadata,
ShaderFeatureStyle,
>,
zoom: f64,
) {
self.in_view.clear();
let stride = size_of::<ShaderTileMetadata>() as u64;
@ -77,8 +93,14 @@ impl<Q: Queue<B>, B> TileViewPattern<Q, B> {
index += 1;
let fallback = {
if !tile_cache.has_tile(&coords) {
if let Some(fallback_coords) = tile_cache.get_tile_coords_fallback(&coords) {
if !buffer_pool.index().has_tile(&coords) {
if let Some(fallback_coords) =
buffer_pool.index().get_tile_coords_fallback(&coords)
{
tracing::trace!(
"Could not find data at {coords}. Falling back to {fallback_coords}"
);
let shape = TileShape {
coords: fallback_coords,
zoom_factor: 2.0_f64.powf(fallback_coords.z as f64 - zoom),