mirror of
https://github.com/penpot/penpot.git
synced 2025-01-19 21:22:31 -05:00
Merge pull request #5529 from penpot/azazeln28-refactor-panning-perf
♻️ Refactor panning perf
This commit is contained in:
commit
4d4bf1edd1
7 changed files with 70 additions and 23 deletions
|
@ -292,19 +292,23 @@
|
|||
(when @canvas-init?
|
||||
(wasm.api/resize-viewbox (:width vport) (:height vport))))
|
||||
|
||||
(mf/with-effect [base-objects @canvas-init?]
|
||||
(mf/with-effect [@canvas-init? base-objects]
|
||||
(when @canvas-init?
|
||||
(wasm.api/set-objects base-objects)))
|
||||
|
||||
(mf/with-effect [preview-blend @canvas-init?]
|
||||
(mf/with-effect [@canvas-init? preview-blend]
|
||||
(when (and @canvas-init? preview-blend)
|
||||
(wasm.api/request-render)))
|
||||
(wasm.api/request-render "with-effect")))
|
||||
|
||||
(mf/with-effect [vbox @canvas-init?]
|
||||
(mf/with-effect [@canvas-init? vbox]
|
||||
(when @canvas-init?
|
||||
(wasm.api/set-view zoom vbox)))
|
||||
(wasm.api/set-view-zoom zoom vbox)))
|
||||
|
||||
(mf/with-effect [background]
|
||||
(mf/with-effect [@canvas-init? vbox]
|
||||
(when @canvas-init?
|
||||
(wasm.api/set-view-box zoom vbox)))
|
||||
|
||||
(mf/with-effect [@canvas-init? background]
|
||||
(when @canvas-init?
|
||||
(wasm.api/set-canvas-background background)))
|
||||
|
||||
|
|
|
@ -61,15 +61,16 @@
|
|||
[r g b a]))
|
||||
|
||||
(defn cancel-render
|
||||
[]
|
||||
[_]
|
||||
(when internal-frame-id
|
||||
(js/cancelAnimationFrame internal-frame-id)
|
||||
(set! internal-frame-id nil)))
|
||||
|
||||
(defn request-render
|
||||
[]
|
||||
(when internal-frame-id (cancel-render))
|
||||
(set! internal-frame-id (js/requestAnimationFrame render)))
|
||||
[requester]
|
||||
(when internal-frame-id (cancel-render requester))
|
||||
(let [frame-id (js/requestAnimationFrame render)]
|
||||
(set! internal-frame-id frame-id)))
|
||||
|
||||
(defn use-shape
|
||||
[id]
|
||||
|
@ -386,10 +387,15 @@
|
|||
|
||||
(def debounce-render-without-cache (fns/debounce render-without-cache 100))
|
||||
|
||||
(defn set-view
|
||||
(defn set-view-box
|
||||
[zoom vbox]
|
||||
(h/call internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(h/call internal-module "_navigate")
|
||||
(h/call internal-module "_pan"))
|
||||
|
||||
(defn set-view-zoom
|
||||
[zoom vbox]
|
||||
(h/call internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(h/call internal-module "_zoom")
|
||||
(debounce-render-without-cache))
|
||||
|
||||
(defn set-objects
|
||||
|
@ -441,7 +447,7 @@
|
|||
(let [pending' (concat (set-shape-fills fills) (set-shape-strokes strokes))]
|
||||
(recur (inc index) (into pending pending'))))
|
||||
pending))]
|
||||
(request-render)
|
||||
(request-render "set-objects")
|
||||
(when-let [pending (seq pending)]
|
||||
(->> (rx/from pending)
|
||||
(rx/mapcat identity)
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
;; when something synced with wasm
|
||||
;; is modified, we need to request
|
||||
;; a new render.
|
||||
(api/request-render)))
|
||||
(api/request-render "set-wasm-attrs")))
|
||||
|
||||
(defn- impl-assoc
|
||||
[self k v]
|
||||
|
|
|
@ -70,9 +70,16 @@ pub unsafe extern "C" fn render_without_cache() {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn navigate() {
|
||||
pub unsafe extern "C" fn zoom() {
|
||||
let state: &mut Box<State<'_>> =
|
||||
unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
state.zoom();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn pan() {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
state.navigate();
|
||||
state.pan();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
|
@ -36,9 +36,13 @@ pub(crate) struct CachedSurfaceImage {
|
|||
}
|
||||
|
||||
impl CachedSurfaceImage {
|
||||
fn is_dirty(&self, viewbox: &Viewbox) -> bool {
|
||||
fn is_dirty_for_zooming(&mut self, viewbox: &Viewbox) -> bool {
|
||||
!self.has_all_shapes && !self.viewbox.area.contains(viewbox.area)
|
||||
}
|
||||
|
||||
fn is_dirty_for_panning(&mut self, _viewbox: &Viewbox) -> bool {
|
||||
!self.has_all_shapes
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct RenderState {
|
||||
|
@ -168,9 +172,23 @@ impl RenderState {
|
|||
.clear(skia::Color::TRANSPARENT);
|
||||
}
|
||||
|
||||
pub fn navigate(&mut self, tree: &HashMap<Uuid, impl Renderable>) -> Result<(), String> {
|
||||
if let Some(cached_surface_image) = self.cached_surface_image.as_ref() {
|
||||
if cached_surface_image.is_dirty(&self.viewbox) {
|
||||
pub fn zoom(&mut self, tree: &HashMap<Uuid, impl Renderable>) -> Result<(), String> {
|
||||
if let Some(cached_surface_image) = self.cached_surface_image.as_mut() {
|
||||
let is_dirty = cached_surface_image.is_dirty_for_zooming(&self.viewbox);
|
||||
if is_dirty {
|
||||
self.render_all(tree, true);
|
||||
} else {
|
||||
self.render_all_from_cache()?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn pan(&mut self, tree: &HashMap<Uuid, impl Renderable>) -> Result<(), String> {
|
||||
if let Some(cached_surface_image) = self.cached_surface_image.as_mut() {
|
||||
let is_dirty = cached_surface_image.is_dirty_for_panning(&self.viewbox);
|
||||
if is_dirty {
|
||||
self.render_all(tree, true);
|
||||
} else {
|
||||
self.render_all_from_cache()?;
|
||||
|
@ -192,6 +210,7 @@ impl RenderState {
|
|||
);
|
||||
self.translate(self.viewbox.pan_x, self.viewbox.pan_y);
|
||||
|
||||
// Reset shape tree
|
||||
let is_complete = self.render_shape_tree(&Uuid::nil(), tree);
|
||||
if generate_cached_surface_image || self.cached_surface_image.is_none() {
|
||||
self.cached_surface_image = Some(CachedSurfaceImage {
|
||||
|
@ -299,7 +318,7 @@ impl RenderState {
|
|||
if !root_id.is_nil() {
|
||||
if !element.bounds().intersects(self.viewbox.area) || element.hidden() {
|
||||
self.render_debug_element(element, false);
|
||||
// TODO: This means that not all the shapes are renderer so we
|
||||
// TODO: This means that not all the shapes are rendered so we
|
||||
// need to call a render_all on the zoom out.
|
||||
return is_complete; // TODO return is_complete or return false??
|
||||
} else {
|
||||
|
|
6
render-wasm/src/shapes/rects.rs
Normal file
6
render-wasm/src/shapes/rects.rs
Normal file
|
@ -0,0 +1,6 @@
|
|||
use crate::math::Point;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Rect {
|
||||
|
||||
}
|
|
@ -36,9 +36,14 @@ impl<'a> State<'a> {
|
|||
&mut self.render_state
|
||||
}
|
||||
|
||||
pub fn navigate(&mut self) {
|
||||
pub fn pan(&mut self) {
|
||||
// TODO: propagate error to main fn
|
||||
let _ = self.render_state.navigate(&self.shapes).unwrap();
|
||||
let _ = self.render_state.pan(&self.shapes).unwrap();
|
||||
}
|
||||
|
||||
pub fn zoom(&mut self) {
|
||||
// TODO: propagate error to main fn
|
||||
let _ = self.render_state.zoom(&self.shapes).unwrap();
|
||||
}
|
||||
|
||||
pub fn render_all(&mut self, generate_cached_surface_image: bool) {
|
||||
|
|
Loading…
Add table
Reference in a new issue