mirror of
https://github.com/penpot/penpot.git
synced 2025-07-27 22:47:14 +02:00
🎉 Save shape data in rust memory
This commit is contained in:
parent
48909dc3c4
commit
65ee2f9081
13 changed files with 479 additions and 297 deletions
|
@ -9,12 +9,10 @@
|
|||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.files.helpers :as cfh]
|
||||
[app.common.types.shape.impl]
|
||||
[app.common.types.shape.impl :as ctsi]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.config :as cf]
|
||||
[app.main.data.render-wasm :as drw]
|
||||
[app.main.store :as st]
|
||||
[app.util.debug :as dbg]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.object :as obj]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(def enabled?
|
||||
|
@ -23,7 +21,6 @@
|
|||
(set! app.common.types.shape.impl/enabled-wasm-ready-shape enabled?)
|
||||
|
||||
(defonce internal-module #js {})
|
||||
(defonce internal-gpu-state #js {})
|
||||
|
||||
;; TODO: remove the `take` once we have the dynamic data structure in Rust
|
||||
(def xform
|
||||
|
@ -31,49 +28,70 @@
|
|||
(remove cfh/root?)
|
||||
(take 2048)))
|
||||
|
||||
;; Size in number of f32 values that represents the shape selrect (
|
||||
(def rect-size 4)
|
||||
(defn create-shape
|
||||
[id]
|
||||
(let [buffer (uuid/uuid->u32 id)]
|
||||
(._create_shape ^js internal-module (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))))
|
||||
|
||||
(defn use-shape
|
||||
[id]
|
||||
(let [buffer (uuid/uuid->u32 id)]
|
||||
(._use_shape ^js internal-module (aget buffer 0) (aget buffer 1) (aget buffer 2) (aget buffer 3))))
|
||||
|
||||
(defn set-shape-selrect
|
||||
[selrect]
|
||||
(let [x1 (:x1 selrect)
|
||||
y1 (:y1 selrect)
|
||||
x2 (:x2 selrect)
|
||||
y2 (:y2 selrect)]
|
||||
(._set_shape_selrect ^js internal-module x1 y1 x2 y2)))
|
||||
|
||||
(defn set-shape-transform
|
||||
[transform]
|
||||
(let [a (:a transform)
|
||||
b (:b transform)
|
||||
c (:c transform)
|
||||
d (:d transform)
|
||||
e (:e transform)
|
||||
f (:f transform)]
|
||||
(._set_shape_transform ^js internal-module a b c d e f)))
|
||||
|
||||
(defn set-shape-rotation
|
||||
[rotation]
|
||||
(._set_shape_rotation ^js internal-module rotation))
|
||||
|
||||
(defn set-shape-x
|
||||
[x]
|
||||
(._set_shape_x ^js internal-module x))
|
||||
|
||||
(defn set-shape-y
|
||||
[y]
|
||||
(._set_shape_y ^js internal-module y))
|
||||
|
||||
(defn set-objects
|
||||
[objects]
|
||||
;; FIXME: maybe change the name of `_shapes_buffer` (?)
|
||||
(let [get-shapes-buffer-ptr
|
||||
(unchecked-get internal-module "_shapes_buffer")
|
||||
|
||||
heap
|
||||
(unchecked-get internal-module "HEAPF32")
|
||||
|
||||
shapes
|
||||
(into [] xform (vals objects))
|
||||
|
||||
total-shapes
|
||||
(count shapes)
|
||||
|
||||
heap-offset
|
||||
(get-shapes-buffer-ptr)
|
||||
|
||||
heap-size
|
||||
(* rect-size total-shapes)
|
||||
|
||||
mem
|
||||
(js/Float32Array. (.-buffer heap)
|
||||
heap-offset
|
||||
heap-size)]
|
||||
|
||||
(let [shapes (into [] xform (vals objects))
|
||||
total-shapes (count shapes)]
|
||||
(loop [index 0]
|
||||
(when (< index total-shapes)
|
||||
(let [shape (nth shapes index)]
|
||||
(.set ^js mem (.-buffer shape) (* index rect-size))
|
||||
(let [shape (nth shapes index)
|
||||
id (dm/get-prop shape :id)
|
||||
selrect (dm/get-prop shape :selrect)
|
||||
rotation (dm/get-prop shape :rotation)
|
||||
transform (dm/get-prop shape :transform)]
|
||||
(use-shape id)
|
||||
(set-shape-selrect selrect)
|
||||
(set-shape-rotation rotation)
|
||||
(set-shape-transform transform)
|
||||
(recur (inc index)))))))
|
||||
|
||||
(defn draw-objects
|
||||
[zoom vbox]
|
||||
(let [draw-all-shapes (unchecked-get internal-module "_draw_all_shapes")]
|
||||
(js/requestAnimationFrame
|
||||
(fn []
|
||||
(let [pan-x (- (dm/get-prop vbox :x))
|
||||
pan-y (- (dm/get-prop vbox :y))]
|
||||
(draw-all-shapes internal-gpu-state zoom pan-x pan-y))))))
|
||||
(js/requestAnimationFrame
|
||||
(fn []
|
||||
(let [pan-x (- (dm/get-prop vbox :x))
|
||||
pan-y (- (dm/get-prop vbox :y))]
|
||||
(._draw_all_shapes ^js internal-module zoom pan-x pan-y)))))
|
||||
|
||||
(defn cancel-draw
|
||||
[frame-id]
|
||||
|
@ -86,67 +104,28 @@
|
|||
:stencil true
|
||||
:alpha true})
|
||||
|
||||
(defn init-skia
|
||||
[canvas]
|
||||
(let [init-fn (unchecked-get internal-module "_init")
|
||||
state (init-fn (.-width ^js canvas)
|
||||
(.-height ^js canvas))]
|
||||
(set! internal-gpu-state state)))
|
||||
|
||||
;; NOTE: This function can be called externally
|
||||
;; by the button in the context lost component (shown
|
||||
;; in viewport-wasm) or called internally by
|
||||
;; on-webgl-context
|
||||
(defn restore-canvas
|
||||
[canvas]
|
||||
(st/emit! (drw/context-restored))
|
||||
;; We need to reinitialize skia when the
|
||||
;; context is restored.
|
||||
(init-skia canvas))
|
||||
|
||||
;; Handles both events: webglcontextlost and
|
||||
;; webglcontextrestored
|
||||
(defn on-webgl-context
|
||||
[event]
|
||||
(dom/prevent-default event)
|
||||
(if (= (.-type event) "webglcontextlost")
|
||||
(st/emit! (drw/context-lost))
|
||||
(restore-canvas (dom/get-target event))))
|
||||
|
||||
(defn dispose-canvas
|
||||
[canvas]
|
||||
(defn clear-canvas
|
||||
[]
|
||||
;; TODO: perform corresponding cleaning
|
||||
(.removeEventListener canvas "webglcontextlost" on-webgl-context)
|
||||
(.removeEventListener canvas "webglcontextrestored" on-webgl-context))
|
||||
)
|
||||
|
||||
(defn init-debug-webgl-context-state
|
||||
[context]
|
||||
(let [context-extension (.getExtension ^js context "WEBGL_lose_context")
|
||||
info-extension (.getExtension ^js context "WEBGL_debug_renderer_info")]
|
||||
(set! (.-penpotGL js/window) #js {:context context-extension
|
||||
:renderer info-extension})
|
||||
(js/console.log "WEBGL_lose_context" context-extension)
|
||||
(js/console.log "WEBGL_debug_renderer_info" info-extension)))
|
||||
|
||||
(defn setup-canvas
|
||||
(defn assign-canvas
|
||||
[canvas]
|
||||
(let [gl (unchecked-get internal-module "GL")
|
||||
init-fn (unchecked-get internal-module "_init")
|
||||
|
||||
context (.getContext ^js canvas "webgl2" canvas-options)
|
||||
|
||||
;; Register the context with emscripten
|
||||
handle (.registerContext ^js gl context #js {"majorVersion" 2})
|
||||
_ (.makeContextCurrent ^js gl handle)]
|
||||
|
||||
(when (dbg/enabled? :gl-context)
|
||||
(init-debug-webgl-context-state context))
|
||||
|
||||
(.addEventListener canvas "webglcontextlost" on-webgl-context)
|
||||
(.addEventListener canvas "webglcontextrestored" on-webgl-context)
|
||||
|
||||
handle (.registerContext ^js gl context #js {"majorVersion" 2})]
|
||||
(.makeContextCurrent ^js gl handle)
|
||||
;; Initialize Skia
|
||||
(init-fn (.-width ^js canvas)
|
||||
(.-height ^js canvas))
|
||||
(set! (.-width canvas) (.-clientWidth ^js canvas))
|
||||
(set! (.-height canvas) (.-clientHeight ^js canvas))
|
||||
|
||||
(init-skia canvas)))
|
||||
(obj/set! js/window "shape_list" (fn [] ((unchecked-get internal-module "_shape_list"))))))
|
||||
|
||||
(defonce module
|
||||
(->> (js/dynamicImport "/js/render_wasm.js")
|
||||
|
@ -159,3 +138,9 @@
|
|||
(p/merr (fn [cause]
|
||||
(js/console.error cause)
|
||||
(p/resolved false)))))
|
||||
|
||||
(set! app.common.types.shape.impl/wasm-create-shape create-shape)
|
||||
(set! app.common.types.shape.impl/wasm-use-shape use-shape)
|
||||
(set! app.common.types.shape.impl/wasm-set-shape-selrect set-shape-selrect)
|
||||
(set! app.common.types.shape.impl/wasm-set-shape-transform set-shape-transform)
|
||||
(set! app.common.types.shape.impl/wasm-set-shape-rotation set-shape-rotation)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue