mirror of
https://github.com/penpot/penpot.git
synced 2026-08-07 13:29:07 +00:00
⚡ Fix progressive render budget when timestamp is stale (#11094)
Pass performance.now from finalize/debounce and re-anchor the WASM budget if the stamp is 0 or already past max_blocking_time, so HQ tiles are not yielded after a few nodes with almost no real work.
This commit is contained in:
parent
649f4bebef
commit
8b64b0f84f
@ -1406,7 +1406,7 @@
|
||||
;; this implicitly (`zoom_changed`); this extends it to pan/resize-triggered
|
||||
;; ends (e.g. selecting a shape opens the options panel and resizes the
|
||||
;; viewport), which previously blanked.
|
||||
(internal-render 0 RENDER-FLAG-SYNC-TILES)
|
||||
(internal-render (js/performance.now) RENDER-FLAG-SYNC-TILES)
|
||||
;; The direct render above bypasses the rAF `render` loop, so repaint the
|
||||
;; editor overlay explicitly. Only when this was a full frame: a progressive
|
||||
;; render keeps painting through the rAF loop and its partial frames must not
|
||||
@ -1421,7 +1421,7 @@
|
||||
(if (view-gesture-active?)
|
||||
;; Pan/zoom pause: render without ending the interaction.
|
||||
(do
|
||||
(internal-render 0 RENDER-FLAG-SYNC-TILES)
|
||||
(internal-render (js/performance.now) RENDER-FLAG-SYNC-TILES)
|
||||
(render-text-editor-overlay-after-frame!))
|
||||
(finalize-view-interaction!))))]
|
||||
(fns/debounce do-render DEBOUNCE_DELAY_MS)))
|
||||
|
||||
@ -2357,6 +2357,7 @@ impl RenderState {
|
||||
allow_stop: bool,
|
||||
) -> Result<FrameType> {
|
||||
performance::begin_measure!("continue_render_loop");
|
||||
let timestamp = self.render_budget_start(timestamp);
|
||||
let frame_type =
|
||||
self.render_shape_tree_partial(base_object, tree, timestamp, allow_stop)?;
|
||||
|
||||
@ -2404,6 +2405,7 @@ impl RenderState {
|
||||
tree: ShapesPoolRef,
|
||||
timestamp: i32,
|
||||
) -> Result<FrameType> {
|
||||
let timestamp = self.render_budget_start(timestamp);
|
||||
self.render_shape_tree_partial(base_object, tree, timestamp, false)?;
|
||||
|
||||
// Same composition as `continue_render_loop` for full frames: snapshot only the
|
||||
@ -2538,6 +2540,24 @@ impl RenderState {
|
||||
Ok((data.as_bytes().to_vec(), width, height))
|
||||
}
|
||||
|
||||
/// Anchor the progressive render budget to wall-clock now when the
|
||||
/// caller-provided timestamp is unusable:
|
||||
/// - Frontend sometimes passes `0` (finalize-view / debounced zoom-end).
|
||||
/// - rAF may hand a timestamp that is already older than the budget when
|
||||
/// the handler runs late. Using that stamp made `should_stop_rendering`
|
||||
/// yield after a few nodes with ~0ms of real work.
|
||||
#[inline]
|
||||
fn render_budget_start(&self, timestamp: i32) -> i32 {
|
||||
let now = performance::get_time();
|
||||
if timestamp <= 0 {
|
||||
return now;
|
||||
}
|
||||
if now - timestamp > self.options.max_blocking_time_ms {
|
||||
return now;
|
||||
}
|
||||
timestamp
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn should_stop_rendering(&self, iteration: i32, timestamp: i32) -> bool {
|
||||
if iteration % self.options.node_batch_threshold != 0 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user