mirror of
https://github.com/penpot/penpot.git
synced 2026-01-27 15:51:32 -05:00
Compare commits
4 Commits
eva-extrac
...
superalex-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a904857a97 | ||
|
|
cb5674831a | ||
|
|
02065559da | ||
|
|
c291329fb4 |
@@ -258,10 +258,12 @@ pub extern "C" fn set_view_end() {
|
||||
with_state_mut!(state, {
|
||||
let _end_start = performance::begin_timed_log!("set_view_end");
|
||||
performance::begin_measure!("set_view_end");
|
||||
|
||||
state.render_state.options.set_fast_mode(false);
|
||||
state.render_state.cancel_animation_frame();
|
||||
|
||||
let zoom_changed = state.render_state.zoom_changed();
|
||||
|
||||
// Only rebuild tile indices when zoom has changed.
|
||||
// During pan-only operations, shapes stay in the same tiles
|
||||
// because tile_size = 1/scale * TILE_SIZE (depends only on zoom).
|
||||
@@ -284,6 +286,10 @@ pub extern "C" fn set_view_end() {
|
||||
performance::end_measure!("set_view_end::clear_tile_index");
|
||||
performance::end_timed_log!("clear_tile_index", _clear_start);
|
||||
}
|
||||
// Sync cached_viewbox with current viewbox to ensure accurate
|
||||
// comparison in subsequent calls, especially during rapid zoom+pan
|
||||
// interactions where multiple set_view calls occur before set_view_end.
|
||||
// state.render_state.sync_cached_viewbox();
|
||||
performance::end_measure!("set_view_end");
|
||||
performance::end_timed_log!("set_view_end", _end_start);
|
||||
#[cfg(feature = "profile-macros")]
|
||||
|
||||
@@ -1136,6 +1136,23 @@ impl RenderState {
|
||||
) -> Result<(), String> {
|
||||
let _start = performance::begin_timed_log!("start_render_loop");
|
||||
let scale = self.get_scale();
|
||||
let zoom_changed = self.zoom_changed();
|
||||
// CRITICAL FIX: If zoom changed, we MUST rebuild the tile index before using it.
|
||||
// Otherwise, the index will have tiles from the old zoom level, causing visible
|
||||
// tiles to appear empty. This can happen if start_render_loop() is called before
|
||||
// set_view_end() finishes rebuilding the index, or if set_view_end() hasn't been
|
||||
// called yet. We have access to tree here, so we can rebuild the index ourselves.
|
||||
//
|
||||
// IMPORTANT: If there's a render in progress, we must cancel it first because
|
||||
// rebuild_tiles_shallow() will invalidate the tile index, causing tiles already
|
||||
// in pending_tiles to lose their shapes.
|
||||
if zoom_changed {
|
||||
if self.render_in_progress {
|
||||
self.cancel_animation_frame();
|
||||
}
|
||||
self.rebuild_tiles_shallow(tree);
|
||||
}
|
||||
|
||||
self.tile_viewbox.update(self.viewbox, scale);
|
||||
|
||||
self.focus_mode.reset();
|
||||
@@ -1988,7 +2005,6 @@ impl RenderState {
|
||||
self.background_color,
|
||||
);
|
||||
performance::end_measure!("render_shape_tree::cached");
|
||||
|
||||
if self.options.is_debug_visible() {
|
||||
debug::render_workspace_current_tile(
|
||||
self,
|
||||
@@ -2001,7 +2017,6 @@ impl RenderState {
|
||||
performance::begin_measure!("render_shape_tree::uncached");
|
||||
let (is_empty, early_return) =
|
||||
self.render_shape_tree_partial_uncached(tree, timestamp, allow_stop)?;
|
||||
|
||||
if early_return {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -2027,7 +2042,6 @@ impl RenderState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.surfaces
|
||||
.canvas(SurfaceId::Current)
|
||||
.clear(self.background_color);
|
||||
@@ -2066,19 +2080,14 @@ impl RenderState {
|
||||
self.render_in_progress = false;
|
||||
|
||||
self.surfaces.gc();
|
||||
|
||||
// Cache target surface in a texture
|
||||
self.cached_viewbox = self.viewbox;
|
||||
|
||||
self.cached_target_snapshot = Some(self.surfaces.snapshot(SurfaceId::Cache));
|
||||
|
||||
if self.options.is_debug_visible() {
|
||||
debug::render(self);
|
||||
}
|
||||
|
||||
ui::render(self, tree);
|
||||
debug::render_wasm_label(self);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2162,13 +2171,11 @@ impl RenderState {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the changed tiles
|
||||
self.surfaces.remove_cached_tiles(self.background_color);
|
||||
for tile in all_tiles {
|
||||
self.remove_cached_tile(tile);
|
||||
}
|
||||
|
||||
performance::end_measure!("rebuild_tiles_shallow");
|
||||
}
|
||||
|
||||
@@ -2292,6 +2299,13 @@ impl RenderState {
|
||||
(self.viewbox.zoom - self.cached_viewbox.zoom).abs() > f32::EPSILON
|
||||
}
|
||||
|
||||
/// Updates the cached viewbox to match the current viewbox.
|
||||
/// This should be called at the end of view interactions to ensure
|
||||
/// that cached_viewbox reflects the most recent state for the next comparison.
|
||||
pub fn sync_cached_viewbox(&mut self) {
|
||||
self.cached_viewbox = self.viewbox;
|
||||
}
|
||||
|
||||
pub fn mark_touched(&mut self, uuid: Uuid) {
|
||||
self.touched_ids.insert(uuid);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user