Add examplary feature updates

This commit is contained in:
Maximilian Ammann 2022-04-02 13:25:56 +02:00
parent aa02b5376d
commit 703b8a9838
3 changed files with 117 additions and 20 deletions

View File

@ -67,19 +67,14 @@ impl TileCache {
} }
} }
pub fn iter_tessellated_layers_at<'b: 'a, 'a>( pub fn iter_tessellated_layers_at(
&'b self, &self,
coords: &WorldTileCoords, coords: &WorldTileCoords,
skip_layers: &'a HashSet<&str>, ) -> Option<impl Iterator<Item = &LayerTessellateResult> + '_> {
) -> Option<impl Iterator<Item = &LayerTessellateResult> + 'a> {
coords coords
.build_quad_key() .build_quad_key()
.and_then(|key| self.cache_index.get(&key)) .and_then(|key| self.cache_index.get(&key))
.map(|results| { .map(|results| results.iter())
results
.iter()
.filter(|result| !skip_layers.contains(&result.layer_name()))
})
} }
pub fn retain_missing_layer_names( pub fn retain_missing_layer_names(

View File

@ -230,6 +230,7 @@ impl<Q: Queue<B>, B, V: bytemuck::Pod, I: bytemuck::Pod, TM: bytemuck::Pod, FM:
self.index.push_back(maybe_entry); self.index.push_back(maybe_entry);
} }
#[tracing::instrument(skip_all)]
pub fn update_layer_metadata(&self, queue: &Q, entry: &IndexEntry, layer_metadata: TM) { pub fn update_layer_metadata(&self, queue: &Q, entry: &IndexEntry, layer_metadata: TM) {
let layer_metadata_stride = size_of::<TM>() as wgpu::BufferAddress; // TODO: deduplicate let layer_metadata_stride = size_of::<TM>() as wgpu::BufferAddress; // TODO: deduplicate
let (layer_metadata_bytes, aligned_layer_metadata_bytes) = let (layer_metadata_bytes, aligned_layer_metadata_bytes) =
@ -248,6 +249,36 @@ impl<Q: Queue<B>, B, V: bytemuck::Pod, I: bytemuck::Pod, TM: bytemuck::Pod, FM:
); );
} }
#[tracing::instrument(skip_all)]
pub fn update_feature_metadata(&self, queue: &Q, entry: &IndexEntry, feature_metadata: &[FM]) {
let feature_metadata_stride = size_of::<FM>() as wgpu::BufferAddress; // TODO: deduplicate
let (feature_metadata_bytes, aligned_feature_metadata_bytes) = Self::align(
feature_metadata_stride,
feature_metadata.len() as BufferAddress,
feature_metadata.len() as BufferAddress,
);
if entry.buffer_feature_metadata.end - entry.buffer_feature_metadata.start
!= feature_metadata_bytes
{
panic!("Updated feature metadata has wrong size!");
}
if feature_metadata_bytes != aligned_feature_metadata_bytes {
// FIXME: align if not aligned?
panic!(
"feature_metadata is not aligned. This should not happen as long as size_of::<FM>() is a multiple of the alignment."
)
}
queue.write_buffer(
&self.feature_metadata.inner,
entry.buffer_feature_metadata.start,
&bytemuck::cast_slice(feature_metadata)[0..aligned_feature_metadata_bytes as usize],
);
}
pub fn index(&self) -> &RingIndex { pub fn index(&self) -> &RingIndex {
&self.index &self.index
} }

View File

@ -2,6 +2,8 @@ use cgmath::{Matrix4, Vector4};
use std::collections::HashSet; use std::collections::HashSet;
use std::default::Default; use std::default::Default;
use std::fmt::Formatter; use std::fmt::Formatter;
use std::io::sink;
use std::time::{Instant, SystemTime};
use std::{cmp, fmt, iter}; use std::{cmp, fmt, iter};
use crate::coords::{ViewRegion, TILE_SIZE}; use crate::coords::{ViewRegion, TILE_SIZE};
@ -376,21 +378,39 @@ impl RenderState {
/// We perform the update before uploading new tessellated tiles, such that each /// 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. /// tile metadata in the the `buffer_pool` gets updated exactly once and not twice.
#[tracing::instrument] #[tracing::instrument]
fn update_metadata(&self, view_proj: &ViewProjection) { fn update_metadata(
&self,
_scheduler: &mut IOScheduler,
view_region: &ViewRegion,
view_proj: &ViewProjection,
) {
/*let animated_one = 0.5
* (1.0
+ ((SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs_f64()
* 10.0)
.sin()));*/
// Factor which determines how much we need to adjust the width of lines for example.
// If zoom == z -> zoom_factor == 1
for entries in self.buffer_pool.index().iter() { for entries in self.buffer_pool.index().iter() {
for entry in entries { for entry in entries {
let world_coords = entry.coords; let world_coords = entry.coords;
// Factor which determines how much we need to adjust the width of lines for example. // FIXME: Does not take into account rendering tiles with different z
// If zoom == z -> zoom_factor == 1 if !view_region.is_in_view(&entry.coords) {
continue;
}
let zoom_factor = 2.0_f64.powf(world_coords.z as f64 - self.zoom) as f32; let zoom_factor = 2.0_f64.powf(world_coords.z as f64 - self.zoom) as f32;
let transform: Matrix4<f32> = (view_proj let transform: Matrix4<f32> = (view_proj
.to_model_view_projection(world_coords.transform_for_zoom(self.zoom))) .to_model_view_projection(world_coords.transform_for_zoom(self.zoom)))
.downcast(); .downcast();
// TODO: Update features
self.buffer_pool.update_layer_metadata( self.buffer_pool.update_layer_metadata(
&self.queue, &self.queue,
entry, entry,
@ -400,6 +420,54 @@ impl RenderState {
entry.style_layer.index as f32, entry.style_layer.index as f32,
), ),
); );
// TODO: Update features
/*let source_layer = entry.style_layer.source_layer.as_ref().unwrap();
if let Some(result) = scheduler
.get_tile_cache()
.iter_tessellated_layers_at(&world_coords)
.unwrap()
.find(|layer| source_layer.as_str() == layer.layer_name())
{
let color: Option<Vec4f32> = entry
.style_layer
.paint
.as_ref()
.and_then(|paint| paint.get_color())
.map(|mut color| {
color.color.b = animated_one as f32;
color.into()
});
match result {
LayerTessellateResult::UnavailableLayer { .. } => {}
LayerTessellateResult::TessellatedLayer {
layer_data,
feature_indices,
..
} => {
let feature_metadata = layer_data
.features()
.iter()
.enumerate()
.flat_map(|(i, _feature)| {
iter::repeat(ShaderFeatureStyle {
color: color.unwrap(),
})
.take(feature_indices[i] as usize)
})
.collect::<Vec<_>>();
self.buffer_pool.update_feature_metadata(
&self.queue,
entry,
&feature_metadata,
);
}
}
}*/
} }
} }
} }
@ -425,8 +493,12 @@ impl RenderState {
.unwrap_or_default(); .unwrap_or_default();
if let Some(available_layers) = scheduler if let Some(available_layers) = scheduler
.get_tile_cache() .get_tile_cache()
.iter_tessellated_layers_at(&world_coords, &loaded_layers) .iter_tessellated_layers_at(&world_coords)
.map(|layers| layers.collect::<Vec<_>>()) .map(|layers| {
layers
.filter(|result| !loaded_layers.contains(&result.layer_name()))
.collect::<Vec<_>>()
})
{ {
for style_layer in &self.style.layers { for style_layer in &self.style.layers {
let source_layer = style_layer.source_layer.as_ref().unwrap(); let source_layer = style_layer.source_layer.as_ref().unwrap();
@ -500,13 +572,12 @@ impl RenderState {
let view_region = self let view_region = self
.camera .camera
.view_region_bounding_box(&self.camera.calc_view_proj(&self.perspective).invert()) .view_region_bounding_box(&self.camera.calc_view_proj(&self.perspective).invert())
.map(|bounding_box| ViewRegion::new(bounding_box, 2, self.zoom, visible_z)); .map(|bounding_box| ViewRegion::new(bounding_box, 1, self.zoom, visible_z));
let view_proj = self.camera.calc_view_proj(&self.perspective); let view_proj = self.camera.calc_view_proj(&self.perspective);
self.update_metadata(&view_proj);
if let Some(view_region) = &view_region { if let Some(view_region) = &view_region {
self.update_metadata(scheduler, &view_region, &view_proj);
self.upload_tile_geometry(&view_proj, &view_region, scheduler); self.upload_tile_geometry(&view_proj, &view_region, scheduler);
self.request_tiles_in_view(view_region, scheduler); self.request_tiles_in_view(view_region, scheduler);
} }
@ -584,7 +655,7 @@ impl RenderState {
let view_region = self let view_region = self
.camera .camera
.view_region_bounding_box(&inverted_view_proj) .view_region_bounding_box(&inverted_view_proj)
.map(|bounding_box| ViewRegion::new(bounding_box, 2, self.zoom, visible_z)); .map(|bounding_box| ViewRegion::new(bounding_box, 1, self.zoom, visible_z));
let index = self.buffer_pool.index(); let index = self.buffer_pool.index();