mirror of
https://github.com/penpot/penpot.git
synced 2026-08-01 19:06:18 +00:00
⚡ capture transition snapshot only on page change
This commit is contained in:
parent
d0465e3601
commit
875171ee86
@ -86,10 +86,6 @@
|
|||||||
(defonce transition-image-url* (atom nil))
|
(defonce transition-image-url* (atom nil))
|
||||||
(defonce transition-epoch* (atom 0))
|
(defonce transition-epoch* (atom 0))
|
||||||
(defonce transition-tiles-handler* (atom nil))
|
(defonce transition-tiles-handler* (atom nil))
|
||||||
(defonce snapshot-tiles-handler* (atom nil))
|
|
||||||
|
|
||||||
(def ^:private snapshot-capture-debounce-ms 250)
|
|
||||||
|
|
||||||
|
|
||||||
(defn initialized?
|
(defn initialized?
|
||||||
"True when the WASM render context is ready to receive design-state
|
"True when the WASM render context is ready to receive design-state
|
||||||
@ -173,31 +169,6 @@
|
|||||||
(f))
|
(f))
|
||||||
#js {:once true}))
|
#js {:once true}))
|
||||||
|
|
||||||
(defonce ^:private schedule-canvas-snapshot-capture!
|
|
||||||
(fns/debounce
|
|
||||||
(fn []
|
|
||||||
(when (and (initialized?)
|
|
||||||
(some? wasm/canvas))
|
|
||||||
(-> (webgl/capture-canvas-snapshot-url)
|
|
||||||
(p/catch (fn [_] nil)))))
|
|
||||||
snapshot-capture-debounce-ms))
|
|
||||||
|
|
||||||
(defn- start-canvas-snapshot-listener!
|
|
||||||
[]
|
|
||||||
(when-let [prev @snapshot-tiles-handler*]
|
|
||||||
(.removeEventListener ^js ug/document "penpot:wasm:tiles-complete" prev))
|
|
||||||
(let [handler (fn [_] (schedule-canvas-snapshot-capture!))]
|
|
||||||
(reset! snapshot-tiles-handler* handler)
|
|
||||||
(.addEventListener ^js ug/document "penpot:wasm:tiles-complete" handler)))
|
|
||||||
|
|
||||||
(defn- stop-canvas-snapshot-listener!
|
|
||||||
[]
|
|
||||||
(when-let [prev @snapshot-tiles-handler*]
|
|
||||||
(.removeEventListener ^js ug/document "penpot:wasm:tiles-complete" prev))
|
|
||||||
(reset! snapshot-tiles-handler* nil)
|
|
||||||
(when-let [cancel (unchecked-get schedule-canvas-snapshot-capture! "cancel")]
|
|
||||||
(cancel)))
|
|
||||||
|
|
||||||
(defn text-editor-wasm?
|
(defn text-editor-wasm?
|
||||||
[]
|
[]
|
||||||
(or (contains? cf/flags :feature-text-editor-wasm)
|
(or (contains? cf/flags :feature-text-editor-wasm)
|
||||||
@ -224,7 +195,11 @@
|
|||||||
|
|
||||||
(def ^:const DEBOUNCE_DELAY_MS 100)
|
(def ^:const DEBOUNCE_DELAY_MS 100)
|
||||||
|
|
||||||
(defonce ^:private view-interaction-active? (atom false))
|
;; Public so the viewport can gate heavy overlays (flex controls, frame grid,
|
||||||
|
;; measurements) during pan/zoom — they otherwise re-render + recompute geometry
|
||||||
|
;; on every viewbox change. Set by `set-view-box` (pan AND zoom), cleared on
|
||||||
|
;; interaction end.
|
||||||
|
(defonce view-interaction-active? (atom false))
|
||||||
|
|
||||||
;; Time budget (ms) per chunk of shape processing before yielding to browser
|
;; Time budget (ms) per chunk of shape processing before yielding to browser
|
||||||
(def ^:private ^:const CHUNK_TIME_BUDGET_MS 8)
|
(def ^:private ^:const CHUNK_TIME_BUDGET_MS 8)
|
||||||
@ -270,7 +245,6 @@
|
|||||||
(def noop-fn
|
(def noop-fn
|
||||||
(constantly nil))
|
(constantly nil))
|
||||||
|
|
||||||
;;
|
|
||||||
(def shape-wrapper-factory nil)
|
(def shape-wrapper-factory nil)
|
||||||
|
|
||||||
(let [^js ch (js/MessageChannel.)]
|
(let [^js ch (js/MessageChannel.)]
|
||||||
@ -1270,17 +1244,34 @@
|
|||||||
(internal-render)))]
|
(internal-render)))]
|
||||||
(fns/debounce do-render DEBOUNCE_DELAY_MS)))
|
(fns/debounce do-render DEBOUNCE_DELAY_MS)))
|
||||||
|
|
||||||
|
(defonce ^:private pending-cache-render? (atom false))
|
||||||
|
|
||||||
|
(defn- flush-cache-render!
|
||||||
|
[]
|
||||||
|
(reset! pending-cache-render? false)
|
||||||
|
(when (initialized?)
|
||||||
|
(perf/begin-measure "render-from-cache")
|
||||||
|
(h/call wasm/internal-module "_render_from_cache" 0)
|
||||||
|
(render-finish)
|
||||||
|
(perf/end-measure "render-from-cache")))
|
||||||
|
|
||||||
(defn set-view-box
|
(defn set-view-box
|
||||||
[zoom vbox]
|
[zoom vbox]
|
||||||
(perf/begin-measure "set-view-box")
|
(perf/begin-measure "set-view-box")
|
||||||
(view-interaction-start!)
|
(view-interaction-start!)
|
||||||
|
;; `_set_view` is cheap and must run per event so the renderer always has the
|
||||||
|
;; latest viewbox.
|
||||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||||
(perf/end-measure "set-view-box")
|
(perf/end-measure "set-view-box")
|
||||||
|
|
||||||
(perf/begin-measure "render-from-cache")
|
;; Coalesce the cache-preview render to one per animation frame. Wheel/trackpad
|
||||||
(h/call wasm/internal-module "_render_from_cache" 0)
|
;; momentum (and any batched viewport updates) fire many `set-view-box` calls
|
||||||
(render-finish)
|
;; per frame; calling `_render_from_cache` synchronously on each piled up to
|
||||||
(perf/end-measure "render-from-cache"))
|
;; ~17 renders × tens-to-hundreds of ms in a single RAF (1.5s handlers that
|
||||||
|
;; froze input). One coalesced render per frame uses the latest viewbox.
|
||||||
|
(when-not @pending-cache-render?
|
||||||
|
(reset! pending-cache-render? true)
|
||||||
|
(timers/raf (fn [_] (flush-cache-render!)))))
|
||||||
|
|
||||||
(defn sync-workspace-local-viewport!
|
(defn sync-workspace-local-viewport!
|
||||||
"Pushes `[:workspace-local :zoom]` and `:vbox` into WASM."
|
"Pushes `[:workspace-local :zoom]` and `:vbox` into WASM."
|
||||||
@ -1981,7 +1972,6 @@
|
|||||||
(set! wasm/canvas canvas)
|
(set! wasm/canvas canvas)
|
||||||
(.addEventListener canvas "webglcontextlost" on-webgl-context-lost)
|
(.addEventListener canvas "webglcontextlost" on-webgl-context-lost)
|
||||||
(.addEventListener canvas "webglcontextrestored" on-webgl-context-restored)
|
(.addEventListener canvas "webglcontextrestored" on-webgl-context-restored)
|
||||||
(start-canvas-snapshot-listener!)
|
|
||||||
(reset! wasm/context-lost? false)
|
(reset! wasm/context-lost? false)
|
||||||
(set! wasm/context-initialized? true)))
|
(set! wasm/context-initialized? true)))
|
||||||
|
|
||||||
@ -2008,7 +1998,6 @@
|
|||||||
(when wasm/canvas
|
(when wasm/canvas
|
||||||
(.removeEventListener wasm/canvas "webglcontextlost" on-webgl-context-lost)
|
(.removeEventListener wasm/canvas "webglcontextlost" on-webgl-context-lost)
|
||||||
(.removeEventListener wasm/canvas "webglcontextrestored" on-webgl-context-restored))
|
(.removeEventListener wasm/canvas "webglcontextrestored" on-webgl-context-restored))
|
||||||
(stop-canvas-snapshot-listener!)
|
|
||||||
|
|
||||||
(when (wasm/module-ready?)
|
(when (wasm/module-ready?)
|
||||||
(free-gpu-resources)
|
(free-gpu-resources)
|
||||||
@ -2083,8 +2072,10 @@
|
|||||||
(wasm-gesture/reset-after-wasm-reload!))))
|
(wasm-gesture/reset-after-wasm-reload!))))
|
||||||
;; Ensure render surfaces are blank before replay to avoid overpainting.
|
;; Ensure render surfaces are blank before replay to avoid overpainting.
|
||||||
(p/then (fn [_] (h/call wasm/internal-module "_reset_canvas")))
|
(p/then (fn [_] (h/call wasm/internal-module "_reset_canvas")))
|
||||||
(p/then (fn [_] (replay-font-resources! fonts)))
|
(p/then (fn [_]
|
||||||
(p/then (fn [_] (replay-image-resources! image-resources)))
|
(replay-font-resources! fonts)))
|
||||||
|
(p/then (fn [_]
|
||||||
|
(replay-image-resources! image-resources)))
|
||||||
(p/then
|
(p/then
|
||||||
(fn []
|
(fn []
|
||||||
(initialize-viewport base-objects zoom vbox
|
(initialize-viewport base-objects zoom vbox
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user