mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Allow late initialization of render state
This commit is contained in:
parent
c289c184d3
commit
630a1e4bf7
@ -31,7 +31,7 @@ pub struct MapState<W> {
|
||||
camera: ChangeObserver<camera::Camera>,
|
||||
perspective: camera::Perspective,
|
||||
|
||||
render_state: RenderState,
|
||||
render_state: Option<RenderState>,
|
||||
scheduler: Scheduler,
|
||||
message_receiver: mpsc::Receiver<TessellateMessage>,
|
||||
shared_thread_state: SharedThreadState,
|
||||
@ -46,7 +46,7 @@ impl<W> MapState<W> {
|
||||
pub fn new(
|
||||
window: W,
|
||||
window_size: WindowSize,
|
||||
render_state: RenderState,
|
||||
render_state: Option<RenderState>,
|
||||
scheduler: Scheduler,
|
||||
style: Style,
|
||||
) -> Self {
|
||||
@ -100,7 +100,7 @@ impl<W> MapState<W> {
|
||||
self.prepare_render();
|
||||
|
||||
// Render buffers
|
||||
let result = self.render_state.render();
|
||||
let result = self.render_state_mut().render();
|
||||
|
||||
#[cfg(all(feature = "enable-tracing", not(target_arch = "wasm32")))]
|
||||
tracy_client::finish_continuous_frame!();
|
||||
@ -170,13 +170,12 @@ impl<W> MapState<W> {
|
||||
drop(_guard);
|
||||
|
||||
if let Some(view_region) = &view_region {
|
||||
self.render_state
|
||||
.upload_tile_geometry(view_region, &self.style, &self.tile_cache);
|
||||
self.render_state.as_mut().expect("render state not yet initialized. Call reinitialize().").upload_tile_geometry(view_region, &self.style, &self.tile_cache);
|
||||
|
||||
self.render_state
|
||||
.update_tile_view_pattern(view_region, &view_proj, self.zoom());
|
||||
let zoom = self.zoom();
|
||||
self.render_state_mut().update_tile_view_pattern(view_region, &view_proj, zoom);
|
||||
|
||||
self.render_state.update_metadata();
|
||||
self.render_state_mut().update_metadata();
|
||||
}
|
||||
|
||||
// TODO: Could we draw inspiration from StagingBelt (https://docs.rs/wgpu/latest/wgpu/util/struct.StagingBelt.html)?
|
||||
@ -188,7 +187,7 @@ impl<W> MapState<W> {
|
||||
self.try_failed = self.request_tiles_in_view(view_region);
|
||||
}
|
||||
|
||||
self.render_state.update_globals(&view_proj, &self.camera);
|
||||
self.render_state().update_globals(&view_proj, &self.camera);
|
||||
}
|
||||
|
||||
self.camera.update_reference();
|
||||
@ -253,7 +252,7 @@ impl<W> MapState<W> {
|
||||
self.perspective.resize(width, height);
|
||||
self.camera.resize(width, height);
|
||||
|
||||
self.render_state.resize(width, height)
|
||||
self.render_state_mut().resize(width, height)
|
||||
}
|
||||
|
||||
pub fn scheduler(&self) -> &Scheduler {
|
||||
@ -289,11 +288,19 @@ impl<W> MapState<W> {
|
||||
}
|
||||
|
||||
pub fn suspend(&mut self) {
|
||||
self.render_state.suspend();
|
||||
self.render_state_mut().suspend();
|
||||
}
|
||||
|
||||
pub fn resume(&mut self) {
|
||||
self.render_state.resume();
|
||||
self.render_state_mut().resume();
|
||||
}
|
||||
|
||||
pub fn render_state(&self) -> &RenderState {
|
||||
self.render_state.as_ref().expect("render state not yet initialized. Call reinitialize().")
|
||||
}
|
||||
|
||||
pub fn render_state_mut(&mut self) -> &'_ mut RenderState {
|
||||
self.render_state.as_mut().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,6 +309,18 @@ where
|
||||
W: raw_window_handle::HasRawWindowHandle,
|
||||
{
|
||||
pub fn recreate_surface(&mut self) {
|
||||
self.render_state.recreate_surface(&self.window);
|
||||
self.render_state.as_mut().expect("render state not yet initialized. Call reinitialize().").recreate_surface(&self.window);
|
||||
}
|
||||
|
||||
pub fn is_initialized(&self) -> bool {
|
||||
self.render_state.is_some()
|
||||
}
|
||||
|
||||
pub async fn reinitialize(&mut self) {
|
||||
if self.render_state.is_none() {
|
||||
let window_size = WindowSize::new(100, 100).unwrap(); // TODO get size
|
||||
let render_state = RenderState::initialize(&self.window, window_size);
|
||||
self.render_state = Some(render_state.await.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,11 +68,12 @@ impl RenderState {
|
||||
pub async fn initialize<W: raw_window_handle::HasRawWindowHandle>(
|
||||
window: &W,
|
||||
window_size: WindowSize,
|
||||
) -> Self {
|
||||
) -> Option<Self> {
|
||||
let sample_count = 4;
|
||||
|
||||
//let instance = wgpu::Instance::new(wgpu::Backends::GL);
|
||||
let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||
//let instance = wgpu::Instance::new(wgpu::Backends::all());
|
||||
let instance = wgpu::Instance::new(wgpu::Backends::VULKAN);
|
||||
|
||||
let surface = unsafe { instance.create_surface(&window) };
|
||||
let surface_config = wgpu::SurfaceConfiguration {
|
||||
@ -101,7 +102,13 @@ impl RenderState {
|
||||
} else if cfg!(target_os = "android") {
|
||||
Limits {
|
||||
max_storage_textures_per_shader_stage: 4,
|
||||
..wgpu::Limits::default()
|
||||
max_compute_workgroups_per_dimension: 0,
|
||||
max_compute_workgroup_size_z: 0,
|
||||
max_compute_workgroup_size_y: 0,
|
||||
max_compute_workgroup_size_x: 0,
|
||||
max_compute_workgroup_storage_size: 0,
|
||||
max_compute_invocations_per_workgroup: 0,
|
||||
..wgpu::Limits::downlevel_defaults()
|
||||
}
|
||||
} else {
|
||||
Limits {
|
||||
@ -125,8 +132,7 @@ impl RenderState {
|
||||
},
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
.await.ok()?;
|
||||
|
||||
surface.configure(&device, &surface_config);
|
||||
|
||||
@ -245,7 +251,7 @@ impl RenderState {
|
||||
None
|
||||
};
|
||||
|
||||
Self {
|
||||
Some(Self {
|
||||
instance,
|
||||
surface,
|
||||
device,
|
||||
@ -270,7 +276,7 @@ impl RenderState {
|
||||
tile_view_buffer,
|
||||
TILE_VIEW_BUFFER_SIZE,
|
||||
)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recreate_surface<W: raw_window_handle::HasRawWindowHandle>(&mut self, window: &W) {
|
||||
|
||||
@ -23,6 +23,20 @@ impl Runnable<winit::event_loop::EventLoop<()>> for MapState<winit::window::Wind
|
||||
let mut input_controller = InputController::new(0.2, 100.0, 0.1);
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
if !self.is_initialized() && event == Event::Resumed {
|
||||
use tokio::runtime::Handle;
|
||||
use tokio::task;
|
||||
|
||||
let state = task::block_in_place(|| {
|
||||
Handle::current().block_on(async {
|
||||
self.reinitialize().await;
|
||||
})
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
match event {
|
||||
Event::DeviceEvent {
|
||||
ref event,
|
||||
@ -70,12 +84,12 @@ impl Runnable<winit::event_loop::EventLoop<()>> for MapState<winit::window::Wind
|
||||
Ok(_) => {}
|
||||
Err(wgpu::SurfaceError::Lost) => {
|
||||
log::error!("Surface Lost");
|
||||
},
|
||||
}
|
||||
// The system is out of memory, we should probably quit
|
||||
Err(wgpu::SurfaceError::OutOfMemory) => {
|
||||
log::error!("Out of Memory");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
},
|
||||
}
|
||||
// All other errors (Outdated, Timeout) should be resolved by the next frame
|
||||
Err(e) => eprintln!("{:?}", e),
|
||||
};
|
||||
@ -121,7 +135,7 @@ impl FromWindow for MapBuilder<winit::window::Window, winit::event_loop::EventLo
|
||||
let size = window.inner_size();
|
||||
(
|
||||
window,
|
||||
WindowSize::new(size.width, size.height).unwrap(),
|
||||
WindowSize::new(100, 100).unwrap(),
|
||||
event_loop,
|
||||
)
|
||||
}))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user