mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Simplify and fix headless rendering
This commit is contained in:
parent
355977e3b7
commit
03f38c2725
@ -1,7 +1,7 @@
|
||||
use maplibre::error::Error;
|
||||
use maplibre::io::scheduler::ScheduleMethod;
|
||||
use maplibre::io::source_client::HTTPClient;
|
||||
use maplibre::map_state::MapSchedule;
|
||||
use maplibre::map_schedule::MapSchedule;
|
||||
use maplibre::platform::http_client::ReqwestHttpClient;
|
||||
use maplibre::platform::run_multithreaded;
|
||||
use maplibre::platform::schedule_method::TokioScheduleMethod;
|
||||
@ -45,10 +45,6 @@ where
|
||||
HC: HTTPClient,
|
||||
{
|
||||
fn run(mut self, mut map_state: MapSchedule<MWC, SM, HC>, max_frames: Option<u64>) {
|
||||
let arc = map_state.map_context.renderer.device.clone();
|
||||
tokio::task::spawn_blocking(move || loop {
|
||||
arc.poll(wgpu::Maintain::Wait);
|
||||
});
|
||||
for i in 0..3 {
|
||||
match map_state.update_and_redraw() {
|
||||
Ok(_) => {}
|
||||
|
||||
@ -53,8 +53,8 @@ where
|
||||
SM: ScheduleMethod,
|
||||
HC: HTTPClient,
|
||||
{
|
||||
map_state: MapSchedule<W::MapWindowConfig, SM, HC>,
|
||||
window: W,
|
||||
map_state: MapSchedule<MWC, SM, HC>,
|
||||
window: MWC::MapWindow,
|
||||
}
|
||||
|
||||
impl<MWC, SM, HC> Map<MWC, SM, HC>
|
||||
@ -115,14 +115,18 @@ where
|
||||
{
|
||||
/// Initializes the whole rendering pipeline for the given configuration.
|
||||
/// Returns the initialized map, ready to be run.
|
||||
pub async fn initialize(self) -> Map<MWC::MapWindow, SM, HC> {
|
||||
let window = MWC::MapWindow::create(&self.map_window_config);
|
||||
pub async fn initialize(self) -> Map<MWC, SM, HC>
|
||||
where
|
||||
MWC: MapWindowConfig,
|
||||
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||
{
|
||||
let window = self.map_window_config.create();
|
||||
let window_size = window.size();
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
let renderer = None;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
let renderer = Renderer::initialize(
|
||||
let renderer = Renderer::initialize::<MWC>(
|
||||
&window,
|
||||
self.wgpu_settings.clone(),
|
||||
self.renderer_settings.clone(),
|
||||
@ -146,22 +150,25 @@ where
|
||||
|
||||
pub async fn initialize_headless(self) -> Map<MWC, SM, HC> {
|
||||
let window = self.map_window_config.create();
|
||||
let window_size = window.size();
|
||||
|
||||
let renderer = Renderer::initialize_headless::<MWC>(
|
||||
&window,
|
||||
self.wgpu_settings,
|
||||
self.renderer_settings,
|
||||
self.wgpu_settings.clone(),
|
||||
self.renderer_settings.clone(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
.ok();
|
||||
Map {
|
||||
map_state: MapSchedule::new(
|
||||
window.size(),
|
||||
self.map_window_config,
|
||||
Some(renderer),
|
||||
window_size,
|
||||
renderer,
|
||||
self.scheduler,
|
||||
self.http_client,
|
||||
self.style,
|
||||
self.wgpu_settings,
|
||||
self.renderer_settings,
|
||||
),
|
||||
window,
|
||||
}
|
||||
|
||||
@ -14,22 +14,22 @@ use crate::schedule::{Schedule, Stage};
|
||||
use crate::stages::register_stages;
|
||||
use crate::style::Style;
|
||||
use crate::{
|
||||
MapWindow, MapWindowConfig, Renderer, RendererSettings, ScheduleMethod, WgpuSettings,
|
||||
WindowSize,
|
||||
HeadedMapWindow, MapWindow, MapWindowConfig, Renderer, RendererSettings, ScheduleMethod,
|
||||
WgpuSettings, WindowSize,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
|
||||
pub struct PrematureMapContext {
|
||||
pub view_state: ViewState,
|
||||
pub style: Style,
|
||||
view_state: ViewState,
|
||||
style: Style,
|
||||
|
||||
pub tile_cache: TileCache,
|
||||
pub scheduler: Box<dyn ScheduleMethod>,
|
||||
tile_cache: TileCache,
|
||||
scheduler: Box<dyn ScheduleMethod>,
|
||||
|
||||
pub message_receiver: mpsc::Receiver<TessellateMessage>,
|
||||
pub shared_thread_state: SharedThreadState,
|
||||
message_receiver: mpsc::Receiver<TessellateMessage>,
|
||||
shared_thread_state: SharedThreadState,
|
||||
|
||||
wgpu_settings: WgpuSettings,
|
||||
renderer_settings: RendererSettings,
|
||||
@ -183,13 +183,16 @@ where
|
||||
self.suspended = true;
|
||||
}
|
||||
|
||||
pub fn resume<MW>(&mut self, window: &MW)
|
||||
pub fn resume(&mut self, window: &MWC::MapWindow)
|
||||
where
|
||||
MW: MapWindow,
|
||||
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||
{
|
||||
if let EventuallyMapContext::Full(map_context) = &mut self.map_context {
|
||||
let mut renderer = &mut map_context.renderer;
|
||||
renderer.surface.recreate(window, &renderer.instance);
|
||||
renderer
|
||||
.state
|
||||
.surface
|
||||
.recreate::<MWC>(window, &renderer.instance);
|
||||
self.suspended = false;
|
||||
}
|
||||
}
|
||||
@ -201,24 +204,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn late_init(&mut self) -> bool {
|
||||
pub async fn late_init(&mut self) -> bool
|
||||
where
|
||||
<MWC as MapWindowConfig>::MapWindow: HeadedMapWindow,
|
||||
{
|
||||
match &self.map_context {
|
||||
EventuallyMapContext::Full(_) => false,
|
||||
EventuallyMapContext::Premature(PrematureMapContext {
|
||||
view_state,
|
||||
style,
|
||||
tile_cache,
|
||||
scheduler,
|
||||
message_receiver,
|
||||
shared_thread_state,
|
||||
wgpu_settings,
|
||||
renderer_settings,
|
||||
..
|
||||
}) => {
|
||||
let window = MWC::MapWindow::create(&self.map_window_config);
|
||||
let renderer =
|
||||
Renderer::initialize(&window, wgpu_settings.clone(), renderer_settings.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
let window = self.map_window_config.create();
|
||||
let renderer = Renderer::initialize::<MWC>(
|
||||
&window,
|
||||
wgpu_settings.clone(),
|
||||
renderer_settings.clone(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
&self.map_context.make_full(renderer);
|
||||
true
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ pub struct RenderState {
|
||||
depth_texture: Eventually<Texture>,
|
||||
multisampling_texture: Eventually<Option<Texture>>,
|
||||
|
||||
surface: Surface,
|
||||
pub surface: Surface,
|
||||
|
||||
mask_phase: RenderPhase<TileInView>,
|
||||
tile_phase: RenderPhase<(IndexEntry, TileShape)>,
|
||||
|
||||
@ -65,6 +65,7 @@ pub struct BufferedTextureHead {
|
||||
impl BufferedTextureHead {
|
||||
pub async fn create_png<'a>(
|
||||
&self,
|
||||
device: &wgpu::Device,
|
||||
png_output_path: &str,
|
||||
// device: &wgpu::Device,
|
||||
) {
|
||||
@ -75,7 +76,7 @@ impl BufferedTextureHead {
|
||||
// Poll the device in a blocking manner so that our future resolves.
|
||||
// In an actual application, `device.poll(...)` should
|
||||
// be called in an event loop or on another thread.
|
||||
//device.poll(wgpu::Maintain::Wait);
|
||||
device.poll(wgpu::Maintain::Wait);
|
||||
if let Ok(()) = buffer_future.await {
|
||||
let padded_buffer = buffer_slice.get_mapped_range();
|
||||
|
||||
|
||||
@ -24,13 +24,15 @@ use tokio::task;
|
||||
use wgpu::{BufferAsyncError, BufferSlice};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct WriteSurfaceBufferStage;
|
||||
pub struct WriteSurfaceBufferStage {
|
||||
frame: u64,
|
||||
}
|
||||
|
||||
impl Stage for WriteSurfaceBufferStage {
|
||||
fn run(
|
||||
&mut self,
|
||||
MapContext {
|
||||
renderer: Renderer { state, .. },
|
||||
renderer: Renderer { state, device, .. },
|
||||
..
|
||||
}: &mut MapContext,
|
||||
) {
|
||||
@ -39,11 +41,18 @@ impl Stage for WriteSurfaceBufferStage {
|
||||
Head::Headless(buffered_texture) => {
|
||||
let buffered_texture = buffered_texture.clone();
|
||||
|
||||
let device = device.clone();
|
||||
let current_frame = self.frame;
|
||||
|
||||
task::block_in_place(|| {
|
||||
Handle::current().block_on(async {
|
||||
buffered_texture.create_png("test.png").await;
|
||||
buffered_texture
|
||||
.create_png(&device, format!("frame_{}.png", current_frame).as_str())
|
||||
.await;
|
||||
})
|
||||
});
|
||||
|
||||
self.frame += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user