Merge pull request #9622 from penpot/superalex-fix-grid-not-visible-2

🐛 Fix grid not visible
This commit is contained in:
Alejandro Alonso 2026-05-14 10:56:18 +02:00 committed by GitHub
commit 4bd0049ddf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 35 deletions

View File

@ -809,7 +809,19 @@ impl RenderState {
} }
pub fn flush_and_submit(&mut self) { pub fn flush_and_submit(&mut self) {
self.surfaces.flush_and_submit(SurfaceId::Target);
}
/// Copy the clean (no UI overlay) Backbuffer to Target, draw UI/debug overlays
/// on top of Target, then present. Backbuffer is left clean so it can be reused
/// as-is across interactive-transform frames without stale overlay pixels.
pub fn present_frame(&mut self, tree: ShapesPoolRef) {
self.surfaces.copy_backbuffer_to_target(); self.surfaces.copy_backbuffer_to_target();
if self.options.is_debug_visible() {
debug::render(self);
}
ui::render(self, tree);
debug::render_wasm_label(self);
self.surfaces.flush_and_submit(SurfaceId::Target); self.surfaces.flush_and_submit(SurfaceId::Target);
} }
@ -1771,14 +1783,7 @@ impl RenderState {
self.surfaces self.surfaces
.draw_atlas_to_backbuffer(self.viewbox, self.options.dpr, bg_color); .draw_atlas_to_backbuffer(self.viewbox, self.options.dpr, bg_color);
if self.options.is_debug_visible() { self.present_frame(shapes);
debug::render(self);
}
ui::render(self, shapes);
debug::render_wasm_label(self);
self.flush_and_submit();
performance::end_measure!("render_from_cache"); performance::end_measure!("render_from_cache");
performance::end_timed_log!("render_from_cache", _start); performance::end_timed_log!("render_from_cache", _start);
return; return;
@ -1843,13 +1848,7 @@ impl RenderState {
bg_color, bg_color,
); );
if self.options.is_debug_visible() { self.present_frame(shapes);
debug::render(self);
}
ui::render(self, shapes);
debug::render_wasm_label(self);
self.flush_and_submit();
performance::end_measure!("render_from_cache"); performance::end_measure!("render_from_cache");
performance::end_timed_log!("render_from_cache", _start); performance::end_timed_log!("render_from_cache", _start);
return; return;
@ -1902,14 +1901,7 @@ impl RenderState {
} }
} }
if self.options.is_debug_visible() { self.present_frame(shapes);
debug::render(self);
}
ui::render(self, shapes);
debug::render_wasm_label(self);
self.flush_and_submit();
} }
performance::end_measure!("render_from_cache"); performance::end_measure!("render_from_cache");
@ -2103,17 +2095,21 @@ impl RenderState {
self.render_shape_tree_partial(base_object, tree, timestamp, true)?; self.render_shape_tree_partial(base_object, tree, timestamp, true)?;
if self.render_in_progress { if self.render_in_progress {
// Partial frame: just flush GPU work. The display shows the last
// fully submitted frame; no need to copy or draw UI overlays here.
self.flush(); self.flush();
self.cancel_animation_frame(); self.cancel_animation_frame();
self.render_request_id = Some(wapi::request_animation_frame!()); self.render_request_id = Some(wapi::request_animation_frame!());
} else { } else {
// A full-quality frame is now complete. Refresh Backbuffer and regenerate // A full-quality frame is now complete. Rebuild the per-shape crop
// the per-shape crop cache so interactive drags can reuse pixels. // cache from the clean Backbuffer (no UI overlay yet) so that
// interactive drag backgrounds don't include the grid overlay.
if !self.options.is_fast_mode() && !self.options.is_interactive_transform() { if !self.options.is_fast_mode() && !self.options.is_interactive_transform() {
self.surfaces.copy_backbuffer_to_target();
self.rebuild_backbuffer_crop_cache(tree); self.rebuild_backbuffer_crop_cache(tree);
} }
self.flush_and_submit(); // present_frame: copy clean Backbuffer → Target, draw UI/debug
// overlays on Target only, then flush. Backbuffer stays overlay-free.
self.present_frame(tree);
wapi::notify_tiles_render_complete!(); wapi::notify_tiles_render_complete!();
performance::end_measure!("render"); performance::end_measure!("render");
} }
@ -2129,7 +2125,7 @@ impl RenderState {
timestamp: i32, timestamp: i32,
) -> Result<()> { ) -> Result<()> {
self.render_shape_tree_partial(base_object, tree, timestamp, false)?; self.render_shape_tree_partial(base_object, tree, timestamp, false)?;
self.flush_and_submit(); self.present_frame(tree);
Ok(()) Ok(())
} }
@ -3415,13 +3411,6 @@ impl RenderState {
self.cached_viewbox = self.viewbox; self.cached_viewbox = self.viewbox;
} }
if self.options.is_debug_visible() {
debug::render(self);
}
ui::render(self, tree);
debug::render_wasm_label(self);
Ok(()) Ok(())
} }

View File

@ -1495,6 +1495,8 @@ impl Shape {
// Outsets (strokes, shadows, blur, children) are translation-invariant, // Outsets (strokes, shadows, blur, children) are translation-invariant,
// so the cached extrect can be shifted instead of invalidated. // so the cached extrect can be shifted instead of invalidated.
// The bounds cache must always be invalidated so that callers such as
// grid_cell_data get the updated position after a drag.
if math::is_move_only_matrix(transform) { if math::is_move_only_matrix(transform) {
let tx = transform.translate_x(); let tx = transform.translate_x();
let ty = transform.translate_y(); let ty = transform.translate_y();
@ -1506,6 +1508,7 @@ impl Shape {
rect.height(), rect.height(),
); );
} }
self.invalidate_bounds();
} else { } else {
self.invalidate_extrect(); self.invalidate_extrect();
self.invalidate_bounds(); self.invalidate_bounds();