mirror of
https://github.com/penpot/penpot.git
synced 2026-08-17 10:18:59 +00:00
⚡ Fix progressive render budget when timestamp is stale
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
151a5c9297
commit
c824fe8bfe
@ -1417,7 +1417,7 @@
|
|||||||
;; this implicitly (`zoom_changed`); this extends it to pan/resize-triggered
|
;; this implicitly (`zoom_changed`); this extends it to pan/resize-triggered
|
||||||
;; ends (e.g. selecting a shape opens the options panel and resizes the
|
;; ends (e.g. selecting a shape opens the options panel and resizes the
|
||||||
;; viewport), which previously blanked.
|
;; 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
|
;; The direct render above bypasses the rAF `render` loop, so repaint the
|
||||||
;; editor overlay explicitly. Only when this was a full frame: a progressive
|
;; 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
|
;; render keeps painting through the rAF loop and its partial frames must not
|
||||||
@ -1432,7 +1432,7 @@
|
|||||||
(if (view-gesture-active?)
|
(if (view-gesture-active?)
|
||||||
;; Pan/zoom pause: render without ending the interaction.
|
;; Pan/zoom pause: render without ending the interaction.
|
||||||
(do
|
(do
|
||||||
(internal-render 0 RENDER-FLAG-SYNC-TILES)
|
(internal-render (js/performance.now) RENDER-FLAG-SYNC-TILES)
|
||||||
(render-text-editor-overlay-after-frame!))
|
(render-text-editor-overlay-after-frame!))
|
||||||
(finalize-view-interaction!))))]
|
(finalize-view-interaction!))))]
|
||||||
(fns/debounce do-render DEBOUNCE_DELAY_MS)))
|
(fns/debounce do-render DEBOUNCE_DELAY_MS)))
|
||||||
|
|||||||
@ -2368,6 +2368,7 @@ impl RenderState {
|
|||||||
allow_stop: bool,
|
allow_stop: bool,
|
||||||
) -> Result<FrameType> {
|
) -> Result<FrameType> {
|
||||||
performance::begin_measure!("continue_render_loop");
|
performance::begin_measure!("continue_render_loop");
|
||||||
|
let timestamp = self.render_budget_start(timestamp);
|
||||||
let frame_type =
|
let frame_type =
|
||||||
self.render_shape_tree_partial(base_object, tree, timestamp, allow_stop)?;
|
self.render_shape_tree_partial(base_object, tree, timestamp, allow_stop)?;
|
||||||
|
|
||||||
@ -2433,6 +2434,7 @@ impl RenderState {
|
|||||||
tree: ShapesPoolRef,
|
tree: ShapesPoolRef,
|
||||||
timestamp: i32,
|
timestamp: i32,
|
||||||
) -> Result<FrameType> {
|
) -> Result<FrameType> {
|
||||||
|
let timestamp = self.render_budget_start(timestamp);
|
||||||
self.render_shape_tree_partial(base_object, tree, timestamp, false)?;
|
self.render_shape_tree_partial(base_object, tree, timestamp, false)?;
|
||||||
|
|
||||||
// Same composition as `continue_render_loop` for full frames: snapshot only the
|
// Same composition as `continue_render_loop` for full frames: snapshot only the
|
||||||
@ -2567,6 +2569,24 @@ impl RenderState {
|
|||||||
Ok((data.as_bytes().to_vec(), width, height))
|
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]
|
#[inline]
|
||||||
pub fn should_stop_rendering(&self, iteration: i32, timestamp: i32) -> bool {
|
pub fn should_stop_rendering(&self, iteration: i32, timestamp: i32) -> bool {
|
||||||
if iteration % self.options.node_batch_threshold != 0 {
|
if iteration % self.options.node_batch_threshold != 0 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user