fix: stabilize web loading and paper rendering
This commit is contained in:
parent
fe49cc8eb5
commit
bca65600cd
25 changed files with 109 additions and 62 deletions
|
|
@ -3219,22 +3219,40 @@ impl MultiPipeline {
|
|||
self.slot_clock = self.slot_clock.wrapping_add(1).max(1);
|
||||
let now = self.slot_clock;
|
||||
let reserved: rustc_hash::FxHashSet<u64> = instance_ids.iter().copied().collect();
|
||||
// `inner.slot_id` is updated later in `prepare`, after this whole
|
||||
// method returns. Without a per-call claim set, two new viewports in
|
||||
// the same primitive both see the freshly-grown slot as `MAX` and get
|
||||
// assigned to it. Paper then blits the final occupant's resolve texture
|
||||
// once as the full sheet and again as the floating viewport.
|
||||
let mut claimed: rustc_hash::FxHashSet<usize> =
|
||||
rustc_hash::FxHashSet::default();
|
||||
let mut slots = Vec::with_capacity(instance_ids.len());
|
||||
|
||||
for &instance_id in instance_ids {
|
||||
let slot = if let Some(&slot) = self.slot_by_instance.get(&instance_id) {
|
||||
let existing = self
|
||||
.slot_by_instance
|
||||
.get(&instance_id)
|
||||
.copied()
|
||||
.filter(|slot| !claimed.contains(slot));
|
||||
let slot = if let Some(slot) = existing {
|
||||
slot
|
||||
} else {
|
||||
self.slot_by_instance.remove(&instance_id);
|
||||
let vacant = self
|
||||
.inners
|
||||
.iter()
|
||||
.position(|inner| inner.slot_id == u64::MAX);
|
||||
.enumerate()
|
||||
.find(|(slot, inner)| {
|
||||
!claimed.contains(slot) && inner.slot_id == u64::MAX
|
||||
})
|
||||
.map(|(slot, _)| slot);
|
||||
let recyclable = vacant.or_else(|| {
|
||||
(self.inners.len() >= SOFT_LIMIT)
|
||||
.then(|| {
|
||||
self.inners
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(slot, _)| !claimed.contains(slot))
|
||||
.filter(|(_, inner)| !reserved.contains(&inner.slot_id))
|
||||
.filter(|(slot, _)| {
|
||||
now.saturating_sub(self.slot_last_used[*slot]) > HOT_WINDOW
|
||||
|
|
@ -3256,6 +3274,7 @@ impl MultiPipeline {
|
|||
self.slot_by_instance.insert(instance_id, slot);
|
||||
slot
|
||||
};
|
||||
claimed.insert(slot);
|
||||
self.slot_last_used[slot] = now;
|
||||
slots.push(slot);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ impl WireArena {
|
|||
) -> Option<Self> {
|
||||
let ranges = handle_ranges(wires)?;
|
||||
let perf = crate::perf::enabled();
|
||||
let total_started = std::time::Instant::now();
|
||||
let total_started = iced::time::Instant::now();
|
||||
|
||||
// Reject an oversized batch before parallel emission allocates hundreds
|
||||
// of megabytes. `points.len() - 1` is an upper bound because NaN-break
|
||||
|
|
@ -363,7 +363,7 @@ impl WireArena {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let pack_started = std::time::Instant::now();
|
||||
let pack_started = iced::time::Instant::now();
|
||||
use crate::par::prelude::*;
|
||||
let packed: Vec<PackedSlab> = plans
|
||||
.par_iter()
|
||||
|
|
@ -441,7 +441,7 @@ impl WireArena {
|
|||
let const_cap = ((const_tail as u64 * HEADROOM_NUM / HEADROOM_DEN)
|
||||
.max(MIN_CONST_CAP)
|
||||
.min(MAX_CONSTS)) as u32;
|
||||
let upload_started = std::time::Instant::now();
|
||||
let upload_started = iced::time::Instant::now();
|
||||
let inst_buf = alloc_inst_initialized(device, inst_cap as u64, &instances);
|
||||
let const_buf = alloc_const_initialized(device, const_cap as u64, &consts_cpu);
|
||||
let upload_ms = upload_started.elapsed().as_secs_f64() * 1000.0;
|
||||
|
|
|
|||
|
|
@ -224,9 +224,6 @@ impl PackedWireInstance {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub type WireInstance = PackedWireInstance;
|
||||
|
||||
/// Wire and hatch pipelines switch together: the fast path uses storage
|
||||
/// buffers; the compatibility path carries wire constants in packed vertex
|
||||
/// attributes and hatch data in a texture.
|
||||
|
|
|
|||
Loading…
Reference in a new issue