Fix non-multithreaded web target

This commit is contained in:
Maximilian Ammann 2022-10-31 09:32:47 +01:00
parent 8af27b29cf
commit d835ef461f
4 changed files with 98 additions and 25 deletions

View File

@ -41,30 +41,22 @@ export const startMapLibre = async (wasmPath: string | undefined, workerPath: st
const memory = new WebAssembly.Memory({initial: 1024, shared: false})
await maplibre.default(wasmPath, memory);
let callbacks: {worker_callback?: (message: MessageEvent) => void} = {}
let init_result = await maplibre.init_maplibre(() => {
let init_result = await maplibre.init_maplibre((ptr) => {
let worker: Worker = workerPath ? new Worker(workerPath, {
type: 'module'
}) : PoolWorker();
worker.onmessage = (message: MessageEvent) => {
callbacks.worker_callback(message)
let tag = message.data[0];
let data = new Uint8Array(message.data[1]);
// @ts-ignore TODO singlethreaded_main_entry may not be defined
maplibre.singlethreaded_main_entry(ptr, tag, data)
}
return worker;
})
// MAJOR FIXME: cloning is not possible let clonedMap = maplibre.clone_map(init_result)
/*callbacks.worker_callback = (message) => {
let tag = message.data[0];
let data = new Uint8Array(message.data[1]);
// @ts-ignore TODO unsync_main_entry may not be defined
maplibre.singlethreaded_main_entry(clonedMap, tag, data)
}*/
maplibre.run(init_result)
}
}

View File

@ -6,6 +6,7 @@ use wasm_bindgen::{prelude::*, JsCast};
use web_sys::Worker;
use super::pool::WorkerPool;
use crate::CurrentEnvironment;
pub struct WebWorkerPoolScheduler {
pool: WorkerPool,

View File

@ -16,6 +16,7 @@ use std::{
};
use js_sys::Uint8Array;
use log::info;
use maplibre::{
environment::Environment,
error::Error,
@ -25,21 +26,23 @@ use maplibre::{
source_client::{HttpClient, HttpSourceClient, SourceClient},
transferables::Transferables,
},
kernel::Kernel,
};
use wasm_bindgen::{prelude::*, JsCast, JsValue};
use web_sys::{DedicatedWorkerGlobalScope, Worker};
use web_sys::{console::info, DedicatedWorkerGlobalScope, Worker};
use crate::{
platform::singlethreaded::transferables::{
InnerData, LinearTessellatedLayer, LinearTransferables,
},
MapType, WHATWGFetchHttpClient,
CurrentEnvironment, MapType, WHATWGFetchHttpClient,
};
type UsedTransferables = LinearTransferables;
type UsedHttpClient = WHATWGFetchHttpClient;
type UsedContext = PassingContext;
#[derive(Debug)]
enum SerializedMessageTag {
TileTessellated = 1,
UnavailableLayer = 2,
@ -144,18 +147,26 @@ impl Context<UsedTransferables, UsedHttpClient> for PassingContext {
}
}
type ReceivedType = RefCell<Vec<Message<UsedTransferables>>>;
pub struct PassingAsyncProcedureCall {
new_worker: Box<dyn Fn() -> Worker>,
workers: Vec<Worker>,
received: RefCell<Vec<Message<UsedTransferables>>>, // FIXME (wasm-executor): Is RefCell fine?
received: Rc<ReceivedType>, // FIXME (wasm-executor): Is RefCell fine?
}
impl PassingAsyncProcedureCall {
pub fn new(new_worker: js_sys::Function, initial_workers: u8) -> Self {
let received = Rc::new(RefCell::new(vec![]));
let received_ref = received.clone();
let create_new_worker = Box::new(move || {
new_worker
.call0(&JsValue::undefined())
.call1(
&JsValue::undefined(),
&JsValue::from(Rc::into_raw(received_ref.clone()) as u32),
)
.unwrap() // FIXME (wasm-executor): Remove unwrap
.dyn_into::<Worker>()
.unwrap() // FIXME (wasm-executor): Remove unwrap
@ -175,7 +186,7 @@ impl PassingAsyncProcedureCall {
Self {
new_worker: create_new_worker,
workers,
received: RefCell::new(vec![]),
received,
}
}
}
@ -219,25 +230,24 @@ pub async fn singlethreaded_worker_entry(procedure_ptr: u32, input: String) -> R
/// Entry point invoked by the main thread.
#[wasm_bindgen]
pub unsafe fn singlethreaded_main_entry(
map_ptr: *const RefCell<MapType>,
received_ptr: *const ReceivedType,
type_id: u32,
data: Uint8Array,
) -> Result<(), JsValue> {
// FIXME (wasm-executor): Can we make this call safe? check if it was cloned before?
let mut map = Rc::from_raw(map_ptr);
let mut received: Rc<ReceivedType> = Rc::from_raw(received_ptr);
let message = Message::<UsedTransferables>::deserialize(
SerializedMessageTag::from_u32(type_id).unwrap(),
data,
);
let map = map.deref().borrow();
let kernel = map.kernel();
info!("singlethreaded_main_entry {:?}", message.tag());
// MAJOR FIXME: Fix mutability
// kernel.apc().received.push(message);
received.borrow_mut().push(message);
mem::forget(map); // FIXME (wasm-executor): Enforce this somehow
mem::forget(received); // FIXME (wasm-executor): Enforce this somehow
Ok(())
}

View File

@ -1,5 +1,6 @@
use bytemuck::{TransparentWrapper, Zeroable};
use bytemuck_derive::{Pod, Zeroable};
use log::warn;
use maplibre::{
benchmarking::tessellation::{IndexDataType, OverAlignedVertexBuffer},
coords::WorldTileCoords,
@ -122,6 +123,75 @@ impl TessellatedLayer for LinearTessellatedLayer {
feature_indices_len: feature_indices.len(),
});
if buffer.buffer.vertices.len() > 15000 {
warn!("vertices too large");
return Self {
data: Box::new(InnerData {
coords: WrapperWorldTileCoords::wrap(coords),
layer_name: [0; 32],
layer_name_len: 0,
vertices: LongVertexShader::wrap([ShaderVertex::zeroed(); 15000]),
vertices_len: 0,
indices: LongIndices::wrap([IndexDataType::zeroed(); 40000]),
indices_len: 0,
usable_indices: 0,
feature_indices: [0u32; 2048],
feature_indices_len: 0,
}),
};
}
if buffer.buffer.indices.len() > 40000 {
warn!("indices too large");
return Self {
data: Box::new(InnerData {
coords: WrapperWorldTileCoords::wrap(coords),
layer_name: [0; 32],
layer_name_len: 0,
vertices: LongVertexShader::wrap([ShaderVertex::zeroed(); 15000]),
vertices_len: 0,
indices: LongIndices::wrap([IndexDataType::zeroed(); 40000]),
indices_len: 0,
usable_indices: 0,
feature_indices: [0u32; 2048],
feature_indices_len: 0,
}),
};
}
if feature_indices.len() > 2048 {
warn!("feature_indices too large");
return Self {
data: Box::new(InnerData {
coords: WrapperWorldTileCoords::wrap(coords),
layer_name: [0; 32],
layer_name_len: 0,
vertices: LongVertexShader::wrap([ShaderVertex::zeroed(); 15000]),
vertices_len: 0,
indices: LongIndices::wrap([IndexDataType::zeroed(); 40000]),
indices_len: 0,
usable_indices: 0,
feature_indices: [0u32; 2048],
feature_indices_len: 0,
}),
};
}
data.vertices.0[0..buffer.buffer.vertices.len()].clone_from_slice(&buffer.buffer.vertices);
data.indices.0[0..buffer.buffer.indices.len()].clone_from_slice(&buffer.buffer.indices);
data.feature_indices[0..feature_indices.len()].clone_from_slice(&feature_indices);