Cleanup dependencies and simplify bounds

This commit is contained in:
Maximilian Ammann 2022-06-01 13:59:12 +02:00
parent cfba8189c3
commit 200e16f345
12 changed files with 82 additions and 84 deletions

View File

@ -14,13 +14,8 @@ trace = ["maplibre/trace", "tracing-subscriber", "tracing-tracy", "tracy-client"
[dependencies]
env_logger = "0.9"
maplibre = { path = "../maplibre", version = "0.0.2" }
maplibre = { path = "../maplibre", version = "0.0.2", features = ["headless"] }
maplibre-winit = { path = "../maplibre-winit", version = "0.0.1" }
geozero = { version = "0.9.4", default-features = false, features = ["with-mvt", "with-geo"]}
tokio = "1.18"
wgpu = "0.12"
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.3", optional = true }

View File

@ -1,4 +1,3 @@
use geozero::mvt::tile;
use maplibre::benchmarking::tessellation::{IndexDataType, OverAlignedVertexBuffer};
use maplibre::coords::WorldTileCoords;
use maplibre::error::Error;
@ -8,19 +7,18 @@ use maplibre::io::pipeline_steps::build_vector_tile_pipeline;
use maplibre::io::scheduler::ScheduleMethod;
use maplibre::io::source_client::{HttpClient, HttpSourceClient};
use maplibre::io::tile_repository::StoredLayer;
use maplibre::io::{TileRequest, TileRequestID};
use maplibre::io::{RawLayer, TileRequest, TileRequestID};
use maplibre::map_schedule::{EventuallyMapContext, InteractiveMapSchedule};
use maplibre::platform::http_client::ReqwestHttpClient;
use maplibre::platform::run_multithreaded;
use maplibre::platform::schedule_method::TokioScheduleMethod;
use maplibre::render::settings::RendererSettings;
use maplibre::render::settings::{RendererSettings, TextureFormat};
use maplibre::render::ShaderVertex;
use maplibre::window::{EventLoop, MapWindow, MapWindowConfig, WindowSize};
use maplibre::MapBuilder;
use maplibre_winit::winit::{WinitEventLoop, WinitMapWindow, WinitMapWindowConfig, WinitWindow};
use std::any::Any;
use std::collections::HashSet;
use wgpu::TextureFormat;
#[cfg(feature = "trace")]
fn enable_tracing() {
@ -77,7 +75,7 @@ impl PipelineProcessor for HeadlessPipelineProcessor {
coords: &WorldTileCoords,
buffer: OverAlignedVertexBuffer<ShaderVertex, IndexDataType>,
feature_indices: Vec<u32>,
layer_data: tile::Layer,
layer_data: RawLayer,
) {
self.layers.push(StoredLayer::TessellatedLayer {
coords: *coords,

View File

@ -14,6 +14,7 @@ web-webgl = ["wgpu/webgl"]
trace = [ "tracing-subscriber", "tracing-tracy", "tracy-client"]
no-thread-safe-futures = []
embed-static-tiles = ["maplibre-build-tools/sqlite"]
headless = ["png"]
[target.'cfg(any(target_os = "macos", target_os = "ios", target_os = "linux", target_os = "android", target_os = "windows"))'.dependencies]
@ -33,24 +34,25 @@ reqwest = { version = "0.11", default-features = false, features = ["rustls-tls"
async-trait = "0.1"
instant = { version = "0.1", features = ["wasm-bindgen"] } # FIXME: Untrusted dependency
raw-window-handle = "0.4"
# Tracing
tracing = { version = "0.1" }
tracing-subscriber = { version = "0.3", optional = true }
# Maths
cgmath = "0.18"
# Geo
geo = { version = "0.19" }
geo-types = { version = "0.7", features = ["use-rstar_0_9"] }
rstar = { version = "0.9" }
prost = "0.10.1"
geozero = { version = "0.9.4", default-features = false, features = ["with-mvt", "with-geo"]}
tile-grid = "0.3"
# Rendering
wgpu = { version = "0.12" }
lyon = { version = "0.17", features = [] }
raw-window-handle = "0.4"
# cached = "0.32"
@ -61,18 +63,24 @@ log = "0.4"
bytemuck = "1.2.0"
bytemuck_derive = "1.0"
# Static tiles inclusion
include_dir = "0.7.2"
# JSON
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
# Colors
csscolorparser = { version = "0.5", features = ["serde", "cint"]}
cint = "0.2"
# Required by bevy renderer
thiserror = "1"
downcast-rs = "1.2"
smallvec = "1.8"
png = "0.17"
# Headless
png = { version = "0.17", optional = true }
[build-dependencies]
maplibre-build-tools = { path = "../maplibre-build-tools", version = "0.1.0", features = ["sqlite"] }

View File

@ -55,6 +55,7 @@ impl ViewState {
}
}
/// Stores the context of the map.
pub struct MapContext {
pub view_state: ViewState,
pub style: Style,

View File

@ -1,14 +1,10 @@
//! Handles IO related processing as well as multithreading.
use crate::coords::WorldTileCoords;
use crate::tessellation::{IndexDataType, OverAlignedVertexBuffer};
use crate::render::ShaderVertex;
use geozero::mvt::tile;
use crate::tessellation::{IndexDataType, OverAlignedVertexBuffer};
use std::collections::HashSet;
use std::fmt;
pub mod scheduler;
pub mod source_client;
pub mod static_tile_fetcher;
@ -19,6 +15,8 @@ pub mod pipeline_steps;
pub mod tile_repository;
pub mod tile_request_state;
pub use geozero::mvt::tile::Layer as RawLayer;
/// A request for a tile at the given coordinates and in the given layers.
#[derive(Clone)]
pub struct TileRequest {

View File

@ -160,7 +160,7 @@ where
#[cfg(target_os = "android")]
let renderer = None;
#[cfg(not(target_os = "android"))]
let renderer = Renderer::initialize::<MWC>(
let renderer = Renderer::initialize(
&window,
self.wgpu_settings.clone(),
self.renderer_settings.clone(),
@ -186,7 +186,7 @@ where
let window = self.map_window_config.create();
let window_size = window.size();
let renderer = Renderer::initialize_headless::<MWC>(
let renderer = Renderer::initialize_headless(
&window,
self.wgpu_settings.clone(),
self.renderer_settings.clone(),

View File

@ -1,5 +1,3 @@
//! Stores the state of the map such as `[crate::coords::Zoom]`, `[crate::camera::Camera]`, `[crate::style::Style]`, `[crate::io::tile_repository::TileCache]` and more.
use crate::context::{MapContext, ViewState};
use crate::error::Error;
use crate::io::geometry_index::GeometryIndex;
@ -162,8 +160,7 @@ where
let mut renderer = &mut map_context.renderer;
renderer
.state
.surface
.recreate::<MWC>(window, &renderer.instance);
.recreate_surface::<MWC::MapWindow>(window, &renderer.instance);
self.suspended = false;
}
}
@ -187,13 +184,10 @@ where
..
}) => {
let window = self.map_window_config.create();
let renderer = Renderer::initialize::<MWC>(
&window,
wgpu_settings.clone(),
renderer_settings.clone(),
)
.await
.unwrap();
let renderer =
Renderer::initialize(&window, wgpu_settings.clone(), renderer_settings.clone())
.await
.unwrap();
self.map_context.make_full(renderer);
true
}

View File

@ -32,7 +32,7 @@ use log::info;
use std::sync::Arc;
// Rendering internals
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "headless")]
mod copy_surface_to_buffer_node;
pub mod graph;
mod graph_runner;
@ -78,7 +78,7 @@ pub struct RenderState {
depth_texture: Eventually<Texture>,
multisampling_texture: Eventually<Option<Texture>>,
pub surface: Surface,
surface: Surface,
mask_phase: RenderPhase<TileInView>,
tile_phase: RenderPhase<(IndexEntry, TileShape)>,
@ -100,11 +100,18 @@ impl RenderState {
tile_phase: Default::default(),
}
}
pub fn recreate_surface<MW>(&mut self, window: &MW, instance: &wgpu::Instance)
where
MW: MapWindow + HeadedMapWindow,
{
self.surface.recreate::<MW>(window, instance);
}
}
pub struct Renderer {
pub instance: wgpu::Instance,
pub device: Arc<wgpu::Device>,
pub device: Arc<wgpu::Device>, // TODO: Arc is needed for headless rendering. Is there a simpler solution?
pub queue: wgpu::Queue,
pub adapter_info: wgpu::AdapterInfo,
@ -117,18 +124,17 @@ pub struct Renderer {
impl Renderer {
/// Initializes the renderer by retrieving and preparing the GPU instance, device and queue
/// for the specified backend.
pub async fn initialize<MWC>(
window: &MWC::MapWindow,
pub async fn initialize<MW>(
window: &MW,
wgpu_settings: WgpuSettings,
settings: RendererSettings,
) -> Result<Self, wgpu::RequestDeviceError>
where
MWC: MapWindowConfig,
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
MW: MapWindow + HeadedMapWindow,
{
let instance = wgpu::Instance::new(wgpu_settings.backends.unwrap_or(wgpu::Backends::all()));
let surface = Surface::from_window::<MWC>(&instance, window, &settings);
let surface = Surface::from_window(&instance, window, &settings);
let compatible_surface = match &surface.head() {
Head::Headed(window_head) => Some(window_head.surface()),
@ -162,13 +168,13 @@ impl Renderer {
})
}
pub async fn initialize_headless<MWC>(
window: &MWC::MapWindow,
pub async fn initialize_headless<MW>(
window: &MW,
wgpu_settings: WgpuSettings,
settings: RendererSettings,
) -> Result<Self, wgpu::RequestDeviceError>
where
MWC: MapWindowConfig,
MW: MapWindow,
{
let instance = wgpu::Instance::new(wgpu_settings.backends.unwrap_or(wgpu::Backends::all()));
@ -183,7 +189,7 @@ impl Renderer {
)
.await?;
let surface = Surface::from_image::<MWC>(&device, window, &settings);
let surface = Surface::from_image(&device, window, &settings);
Ok(Self {
instance,
@ -440,9 +446,9 @@ mod tests {
}
}
// Plugins that contribute to the RenderGraph should use the following label conventions:
// Contributors to the RenderGraph should use the following label conventions:
// 1. Graph modules should have a NAME, input module, and node module (where relevant)
// 2. The "top level" graph is the plugin module root. Just add things like `pub mod node` directly under the plugin module
// 2. The "main_graph" graph is the root.
// 3. "sub graph" modules should be nested beneath their parent graph module
pub mod main_graph {
// Labels for input nodes
@ -462,7 +468,7 @@ pub mod draw_graph {
// Labels for non-input nodes
pub mod node {
pub const MAIN_PASS: &str = "main_pass";
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "headless")]
pub const COPY: &str = "copy";
}
}

View File

@ -44,10 +44,9 @@ impl WindowHead {
self.surface.configure(device, &self.surface_config);
}
pub fn recreate_surface<MWC>(&mut self, window: &MWC::MapWindow, instance: &wgpu::Instance)
pub fn recreate_surface<MW>(&mut self, window: &MW, instance: &wgpu::Instance)
where
MWC: MapWindowConfig,
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
MW: MapWindow + HeadedMapWindow,
{
self.surface = unsafe { instance.create_surface(window.inner()) };
}
@ -121,14 +120,13 @@ pub struct Surface {
}
impl Surface {
pub fn from_window<MWC>(
pub fn from_window<MW>(
instance: &wgpu::Instance,
window: &MWC::MapWindow,
window: &MW,
settings: &RendererSettings,
) -> Self
where
MWC: MapWindowConfig,
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
MW: MapWindow + HeadedMapWindow,
{
let size = window.size();
let surface_config = wgpu::SurfaceConfiguration {
@ -151,13 +149,10 @@ impl Surface {
}
}
pub fn from_image<MWC>(
device: &wgpu::Device,
window: &MWC::MapWindow,
settings: &RendererSettings,
) -> Self
// TODO: Give better name
pub fn from_image<MW>(device: &wgpu::Device, window: &MW, settings: &RendererSettings) -> Self
where
MWC: MapWindowConfig,
MW: MapWindow,
{
let size = window.size();
@ -250,15 +245,14 @@ impl Surface {
}
}
pub fn recreate<MWC>(&mut self, window: &MWC::MapWindow, instance: &wgpu::Instance)
pub fn recreate<MW>(&mut self, window: &MW, instance: &wgpu::Instance)
where
MWC: MapWindowConfig,
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
MW: MapWindow + HeadedMapWindow,
{
match &mut self.head {
Head::Headed(window_head) => {
if window_head.has_changed(&(self.size.width(), self.size.height())) {
window_head.recreate_surface::<MWC>(window, instance);
window_head.recreate_surface(window, instance);
}
}
Head::Headless(_) => {}

View File

@ -4,6 +4,10 @@ use crate::platform::COLOR_TEXTURE_FORMAT;
use std::borrow::Cow;
pub use wgpu::Backends;
pub use wgpu::Features;
pub use wgpu::Limits;
pub use wgpu::PowerPreference;
pub use wgpu::TextureFormat;
/// Provides configuration for renderer initialization. Use [`Device::features`](crate::renderer::Device::features),
/// [`Device::limits`](crate::renderer::Device::limits), and the [`WgpuAdapterInfo`](crate::render_resource::WgpuAdapterInfo)
@ -11,17 +15,17 @@ pub use wgpu::Backends;
#[derive(Clone)]
pub struct WgpuSettings {
pub device_label: Option<Cow<'static, str>>,
pub backends: Option<wgpu::Backends>,
pub power_preference: wgpu::PowerPreference,
pub backends: Option<Backends>,
pub power_preference: PowerPreference,
/// The features to ensure are enabled regardless of what the adapter/backend supports.
/// Setting these explicitly may cause renderer initialization to fail.
pub features: wgpu::Features,
pub features: Features,
/// The features to ensure are disabled regardless of what the adapter/backend supports
pub disabled_features: Option<wgpu::Features>,
pub disabled_features: Option<Features>,
/// The imposed limits.
pub limits: wgpu::Limits,
pub limits: Limits,
/// The constraints on limits allowed regardless of what the adapter/backend supports
pub constrained_limits: Option<wgpu::Limits>,
pub constrained_limits: Option<Limits>,
/// Whether a trace is recorded an stored in the current working directory
pub record_trace: bool,
@ -32,12 +36,12 @@ impl Default for WgpuSettings {
let backends = Some(wgpu::util::backend_bits_from_env().unwrap_or(wgpu::Backends::all()));
let limits = if cfg!(feature = "web-webgl") {
wgpu::Limits {
Limits {
max_texture_dimension_2d: 4096,
..wgpu::Limits::downlevel_webgl2_defaults()
..Limits::downlevel_webgl2_defaults()
}
} else if cfg!(target_os = "android") {
wgpu::Limits {
Limits {
max_storage_textures_per_shader_stage: 4,
max_compute_workgroups_per_dimension: 0,
max_compute_workgroup_size_z: 0,
@ -45,19 +49,19 @@ impl Default for WgpuSettings {
max_compute_workgroup_size_x: 0,
max_compute_workgroup_storage_size: 0,
max_compute_invocations_per_workgroup: 0,
..wgpu::Limits::downlevel_defaults()
..Limits::downlevel_defaults()
}
} else {
wgpu::Limits {
..wgpu::Limits::default()
Limits {
..Limits::default()
}
};
Self {
device_label: Default::default(),
backends,
power_preference: wgpu::PowerPreference::HighPerformance,
features: wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
power_preference: PowerPreference::HighPerformance,
features: Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
disabled_features: None,
limits,
constrained_limits: None,
@ -101,7 +105,7 @@ impl Default for Msaa {
#[derive(Clone)]
pub struct RendererSettings {
pub msaa: Msaa,
pub texture_format: wgpu::TextureFormat,
pub texture_format: TextureFormat,
}
impl Default for RendererSettings {

View File

@ -19,7 +19,7 @@ mod phase_sort_stage;
mod queue_stage;
mod resource_stage;
mod upload_stage;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "headless")]
mod write_surface_buffer_stage;
/// The labels of the default App rendering stages.
@ -69,7 +69,7 @@ pub fn register_render_stages(
let input_node_id = draw_graph.set_input(vec![]);
draw_graph.add_node_edge(input_node_id, draw_graph::node::MAIN_PASS)?;
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "headless")]
if headless {
use crate::render::copy_surface_to_buffer_node::CopySurfaceBufferNode;
draw_graph.add_node(draw_graph::node::COPY, CopySurfaceBufferNode::default());
@ -89,7 +89,7 @@ pub fn register_render_stages(
schedule.add_stage(RenderStageLabel::PhaseSort, PhaseSortStage::default());
schedule.add_stage(RenderStageLabel::Render, GraphRunnerStage::new(graph));
#[cfg(not(target_arch = "wasm32"))]
#[cfg(feature = "headless")]
if headless {
use crate::render::stages::write_surface_buffer_stage::WriteSurfaceBufferStage;
schedule.add_stage(

View File

@ -1,4 +1,4 @@
//! Receives data from async threads and populates the [`crate::io::tile_repository::TileCache`].
//! Receives data from async threads and populates the [`crate::io::tile_repository::TileRepository`].
use super::{MessageReceiver, SharedThreadState, TessellateMessage, TileTessellateMessage};
use crate::context::MapContext;