forked from 1b-agent/opencadstudio-upstream
feat(wasm): sequential rayon shim for the web build
wasm32 has no threads, so rayon's global pool would panic at runtime. Add `crate::par::prelude`: native re-exports `rayon::prelude`, wasm provides sequential `std`-iterator equivalents (par_iter / into_par_iter / flat_map_iter over slices, Vec, HashMap, HashSet). All call sites now `use crate::par::prelude::*;` instead of rayon directly. - wire_gpu's rayon `reduce` (2-arg, no std equivalent) is cfg-split to a sequential flat_map concat on wasm. - rayon moves to a non-wasm target dependency. Native still runs in parallel; all 75 tests pass. wasm bin compiles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
157d54a4d4
commit
9ca19a9db8
8 files changed
+96
-10
No files matched your search
Vendored
+2
-2
@@ -125,7 +125,7 @@ impl BlockCache {
|
||||
/// because their entities are emitted as top-level wires, not via the
|
||||
/// cache.
|
||||
pub fn build(doc: &CadDocument, anno_scale: f32, bg_color: [f32; 4]) -> Self {
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
let mut cache = Self::new();
|
||||
let referenced = collect_referenced_blocks(doc);
|
||||
// Each defn is built independently: nested INSERTs are stored as
|
||||
@@ -151,7 +151,7 @@ impl BlockCache {
|
||||
/// called in. Cycle guard: a self-referential block keeps an empty AABB
|
||||
/// (will fail every frustum test → not emitted, which is correct).
|
||||
fn compute_block_aabbs(&mut self, names: &[String]) {
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
// Phase 1 (parallel, read-only): each defn's union AABB is resolved
|
||||
// by `defn_aabb_recursive`, which only *reads* `self.defns` (the map
|
||||
// is fully built by now). There's no memoization, so a defn shared by
|
||||
|
||||
+4
-4
@@ -155,7 +155,7 @@ pub fn build_derived_caches(doc: &CadDocument) -> DerivedCaches {
|
||||
// filters that `cache::block_cache::build_defn` already uses for block defns)
|
||||
// and prefer the entity-scan when the header center drifts more than
|
||||
// 10× its own half-span away from the entity centroid.
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
|
||||
// Single pass over entities does triple duty: classify cache-kind handle
|
||||
// lists (hatch / image / mesh) AND accumulate per-entity centroids for the
|
||||
@@ -2245,7 +2245,7 @@ impl Scene {
|
||||
};
|
||||
|
||||
// Tessellate in parallel across all available CPU cores.
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
let doc = &self.document;
|
||||
// Selection / hover highlight is NOT baked into tessellation. It is
|
||||
// applied per frame in the GPU xray overlay pass from the live
|
||||
@@ -4297,7 +4297,7 @@ impl Scene {
|
||||
})
|
||||
.collect();
|
||||
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
self.hatches = entries
|
||||
.into_par_iter()
|
||||
.filter_map(|(handle, kind)| {
|
||||
@@ -4350,7 +4350,7 @@ impl Scene {
|
||||
})
|
||||
.collect();
|
||||
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
let facet_res = self.document.header.facet_resolution;
|
||||
let woff = self.world_offset;
|
||||
self.meshes = entries
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
use crate::scene::model::wire_model::WireModel;
|
||||
use iced::wgpu;
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
|
||||
/// Allocate a VERTEX buffer with `mapped_at_creation` and write `data` directly
|
||||
/// into the mapped slice. Skips the intermediate staging copy that
|
||||
@@ -295,7 +295,7 @@ impl WireGpu {
|
||||
scissor: Option<[f32; 4]>,
|
||||
mesh_edge: bool,
|
||||
) -> Vec<Self> {
|
||||
use rayon::prelude::*;
|
||||
use crate::par::prelude::*;
|
||||
const MAX_INSTANCES: usize = 268_435_456 / std::mem::size_of::<WireInstance>();
|
||||
let per: Vec<Vec<WireInstance>> = wires
|
||||
.par_iter()
|
||||
@@ -340,6 +340,7 @@ impl WireGpu {
|
||||
// within a batch does not affect correctness. `reduce` concatenates the
|
||||
// per-wire Vec<WireInstance> chunks while letting rayon spread work
|
||||
// across cores.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let instances: Vec<WireInstance> = wires
|
||||
.par_iter()
|
||||
.map(|wire| emit_wire_instances(wire, wire.color, wire_draw_depth(wire, depth_map)))
|
||||
@@ -353,6 +354,12 @@ impl WireGpu {
|
||||
acc
|
||||
}
|
||||
});
|
||||
// Web: no thread pool — concatenate the per-wire streams sequentially.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let instances: Vec<WireInstance> = wires
|
||||
.iter()
|
||||
.flat_map(|wire| emit_wire_instances(wire, wire.color, wire_draw_depth(wire, depth_map)))
|
||||
.collect();
|
||||
|
||||
if instances.is_empty() {
|
||||
return vec![];
|
||||
|
||||
Reference in new issue
Block a user