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>(
&'b self,
pub fn iter_tessellated_layers_at(
&self,
coords: &WorldTileCoords,
skip_layers: &'a HashSet<&str>,
) -> Option<impl Iterator<Item = &LayerTessellateResult> + 'a> {
) -> Option<impl Iterator<Item = &LayerTessellateResult> + '_> {
coords
.build_quad_key()
.and_then(|key| self.cache_index.get(&key))
.map(|results| {
results
.iter()
.filter(|result| !skip_layers.contains(&result.layer_name()))
})
.map(|results| results.iter())
}
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);
}
#[tracing::instrument(skip_all)]
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_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 {
&self.index
}

View File

@ -2,6 +2,8 @@ use cgmath::{Matrix4, Vector4};
use std::collections::HashSet;
use std::default::Default;
use std::fmt::Formatter;
use std::io::sink;
use std::time::{Instant, SystemTime};
use std::{cmp, fmt, iter};
use crate::coords::{ViewRegion, TILE_SIZE};
@ -376,21 +378,39 @@ impl RenderState {
/// 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.
#[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 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
// FIXME: Does not take into account rendering tiles with different z
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 transform: Matrix4<f32> = (view_proj
.to_model_view_projection(world_coords.transform_for_zoom(self.zoom)))
.downcast();
// TODO: Update features
self.buffer_pool.update_layer_metadata(
&self.queue,
entry,
@ -400,6 +420,54 @@ impl RenderState {
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();
if let Some(available_layers) = scheduler
.get_tile_cache()
.iter_tessellated_layers_at(&world_coords, &loaded_layers)
.map(|layers| layers.collect::<Vec<_>>())
.iter_tessellated_layers_at(&world_coords)
.map(|layers| {
layers
.filter(|result| !loaded_layers.contains(&result.layer_name()))
.collect::<Vec<_>>()
})
{
for style_layer in &self.style.layers {
let source_layer = style_layer.source_layer.as_ref().unwrap();
@ -500,13 +572,12 @@ impl RenderState {
let view_region = self
.camera
.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);
self.update_metadata(&view_proj);
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.request_tiles_in_view(view_region, scheduler);
}
@ -584,7 +655,7 @@ impl RenderState {
let view_region = self
.camera
.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();