mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 19:28:12 +00:00
🔧 Add loading between pages using previous thumbnail
This commit is contained in:
parent
8b06adbb28
commit
47ce2ad6cd
@ -991,7 +991,11 @@
|
||||
(letfn [(do-render []
|
||||
;; Check if context is still initialized before executing
|
||||
;; to prevent errors when navigating quickly
|
||||
(when (and wasm/context-initialized? (not @wasm/context-lost?))
|
||||
(when (and wasm/context-initialized? (not @wasm/context-lost?)
|
||||
;; Skip during bulk loading — the blurred previous-page
|
||||
;; preview must stay visible until set-objects finishes
|
||||
;; and renders synchronously.
|
||||
(not @shapes-loading?))
|
||||
(perf/begin-measure "render-finish")
|
||||
(h/call wasm/internal-module "_set_view_end")
|
||||
(perf/end-measure "render-finish")
|
||||
@ -1007,15 +1011,17 @@
|
||||
|
||||
(defn set-view-box
|
||||
[zoom vbox]
|
||||
(perf/begin-measure "set-view-box")
|
||||
(h/call wasm/internal-module "_set_view_start")
|
||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(perf/end-measure "set-view-box")
|
||||
;; Skip during bulk loading — preserve blurred previous-page preview
|
||||
(when-not @shapes-loading?
|
||||
(perf/begin-measure "set-view-box")
|
||||
(h/call wasm/internal-module "_set_view_start")
|
||||
(h/call wasm/internal-module "_set_view" zoom (- (:x vbox)) (- (:y vbox)))
|
||||
(perf/end-measure "set-view-box")
|
||||
|
||||
(perf/begin-measure "render-from-cache")
|
||||
(h/call wasm/internal-module "_render_from_cache" 0)
|
||||
(render-finish)
|
||||
(perf/end-measure "render-from-cache"))
|
||||
(perf/begin-measure "render-from-cache")
|
||||
(h/call wasm/internal-module "_render_from_cache" 0)
|
||||
(render-finish)
|
||||
(perf/end-measure "render-from-cache")))
|
||||
|
||||
(defn update-text-rect!
|
||||
[id]
|
||||
@ -1204,7 +1210,23 @@
|
||||
(update-text-layouts text-ids)))
|
||||
(if render-callback
|
||||
(render-callback)
|
||||
(request-render "set-objects-complete"))
|
||||
;; When on-shapes-ready is set (page transition), use
|
||||
;; synchronous render so the complete scene appears in
|
||||
;; one frame right after the blur is cleared. Without
|
||||
;; this, the async _render path flushes partial tiles
|
||||
;; progressively, causing visible tile-by-tile loading.
|
||||
(if on-shapes-ready
|
||||
(do
|
||||
;; Cancel the rAF that end-shapes-loading! just
|
||||
;; scheduled — we are about to render synchronously
|
||||
;; and don't want a redundant progressive render on
|
||||
;; the next frame.
|
||||
(when-let [fid wasm/internal-frame-id]
|
||||
(js/cancelAnimationFrame fid)
|
||||
(set! wasm/internal-frame-id nil)
|
||||
(reset! pending-render false))
|
||||
(render-sync))
|
||||
(request-render "set-objects-complete")))
|
||||
(ug/dispatch! (ug/event "penpot:wasm:set-objects"))
|
||||
(resolve nil)
|
||||
|
||||
@ -1252,11 +1274,25 @@
|
||||
;; Rebuild the tile index so _render knows which shapes
|
||||
;; map to which tiles after a page switch.
|
||||
(h/call wasm/internal-module "_set_view_end")
|
||||
|
||||
;; Run text layouts before the first render so text shapes
|
||||
;; are correctly sized immediately.
|
||||
(let [text-ids (into [] (comp (filter cfh/text-shape?) (map :id)) shapes)]
|
||||
(when (seq text-ids)
|
||||
(update-text-layouts text-ids)))
|
||||
|
||||
;; When doing a page transition, render immediately with whatever
|
||||
;; content is available (shapes without images). Images load in
|
||||
;; the background and trigger a re-render when ready.
|
||||
(when on-shapes-ready
|
||||
(render-sync))
|
||||
|
||||
(process-pending shapes thumbnails full
|
||||
(fn []
|
||||
(if render-callback
|
||||
(render-callback)
|
||||
(request-render "set-objects-sync-complete"))
|
||||
(when-not on-shapes-ready
|
||||
(if render-callback
|
||||
(render-callback)
|
||||
(request-render "set-objects-sync-complete")))
|
||||
(ug/dispatch! (ug/event "penpot:wasm:set-objects"))))))
|
||||
|
||||
(defn- shapes-in-tree-order
|
||||
|
||||
@ -48,11 +48,28 @@
|
||||
|
||||
;; FIXME: temporary function until we are able to keep the same <canvas> across pages.
|
||||
(defn- draw-imagedata-to-webgl
|
||||
"Draws ImageData to a WebGL2 context by creating a texture"
|
||||
"Draws ImageData to a WebGL2 context by creating a texture.
|
||||
After _init, Skia owns the GL context and may have left a non-default
|
||||
FBO bound plus scissor/stencil/depth enabled. We must reset all
|
||||
relevant GL state so the full-screen quad actually lands on the
|
||||
default framebuffer (the visible canvas)."
|
||||
[gl image-data]
|
||||
(let [width (.-width ^js image-data)
|
||||
height (.-height ^js image-data)
|
||||
texture (.createTexture ^js gl)]
|
||||
|
||||
;; Bind the default framebuffer (FBO 0) — Skia may have left one
|
||||
;; of its offscreen FBOs bound.
|
||||
(.bindFramebuffer ^js gl (.-FRAMEBUFFER ^js gl) nil)
|
||||
|
||||
;; Disable GPU tests that Skia may have enabled — any of these
|
||||
;; can silently discard our fragments.
|
||||
(.disable ^js gl (.-SCISSOR_TEST ^js gl))
|
||||
(.disable ^js gl (.-STENCIL_TEST ^js gl))
|
||||
(.disable ^js gl (.-DEPTH_TEST ^js gl))
|
||||
(.disable ^js gl (.-BLEND ^js gl))
|
||||
(.colorMask ^js gl true true true true)
|
||||
|
||||
;; Bind texture and set parameters
|
||||
(.bindTexture ^js gl (.-TEXTURE_2D ^js gl) texture)
|
||||
(.texParameteri ^js gl (.-TEXTURE_2D ^js gl) (.-TEXTURE_WRAP_S ^js gl) (.-CLAMP_TO_EDGE ^js gl))
|
||||
@ -156,6 +173,9 @@ void main() {
|
||||
[]
|
||||
(when wasm/canvas
|
||||
(let [context wasm/gl-context]
|
||||
;; Bind default framebuffer so we clear the visible canvas,
|
||||
;; not whichever offscreen FBO Skia may have left active.
|
||||
(.bindFramebuffer ^js context (.-FRAMEBUFFER ^js context) nil)
|
||||
(.clearColor ^js context 0 0 0 0.0)
|
||||
(.clear ^js context (.-COLOR_BUFFER_BIT ^js context))
|
||||
(.clear ^js context (.-DEPTH_BUFFER_BIT ^js context))
|
||||
@ -172,10 +192,11 @@ void main() {
|
||||
(let [context wasm/gl-context
|
||||
width (.-width wasm/canvas)
|
||||
height (.-height wasm/canvas)
|
||||
buffer (js/Uint8ClampedArray. (* width height 4))
|
||||
_ (.readPixels ^js context 0 0 width height (.-RGBA ^js context) (.-UNSIGNED_BYTE ^js context) buffer)
|
||||
image-data (js/ImageData. buffer width height)]
|
||||
(set! wasm/canvas-pixels image-data))))
|
||||
buffer (js/Uint8ClampedArray. (* width height 4))]
|
||||
;; Bind default framebuffer — Skia may have left an offscreen FBO active.
|
||||
(.bindFramebuffer ^js context (.-FRAMEBUFFER ^js context) nil)
|
||||
(.readPixels ^js context 0 0 width height (.-RGBA ^js context) (.-UNSIGNED_BYTE ^js context) buffer)
|
||||
(set! wasm/canvas-pixels (js/ImageData. buffer width height)))))
|
||||
|
||||
(defn draw-thumbnail-to-canvas
|
||||
"Loads an image from `uri` and draws it stretched to fill the WebGL canvas.
|
||||
|
||||
@ -2779,8 +2779,13 @@ impl RenderState {
|
||||
}
|
||||
} else {
|
||||
performance::begin_measure!("render_shape_tree::uncached");
|
||||
// Only allow stopping (yielding) if the current tile is NOT visible.
|
||||
// This ensures all visible tiles render synchronously before showing,
|
||||
// eliminating empty squares during zoom. Interest-area tiles can still yield.
|
||||
let tile_is_visible = self.tile_viewbox.is_visible(¤t_tile);
|
||||
let can_stop = allow_stop && !tile_is_visible;
|
||||
let (is_empty, early_return) = self
|
||||
.render_shape_tree_partial_uncached(tree, timestamp, allow_stop, false)?;
|
||||
.render_shape_tree_partial_uncached(tree, timestamp, can_stop, false)?;
|
||||
|
||||
if early_return {
|
||||
return Ok(());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user