diff --git a/common/src/app/common/types/path.cljc b/common/src/app/common/types/path.cljc index b43e149ddf..8f6d2c7b5a 100644 --- a/common/src/app/common/types/path.cljc +++ b/common/src/app/common/types/path.cljc @@ -216,23 +216,26 @@ :content (vec contents) :cause cause))))) +(def wasm:calc-bool-content + "A overwrite point for setup a WASM version of the `calc-bool-content*` function" + nil) + (defn calc-bool-content "Calculate the boolean content from shape and objects. Returns a packed PathData instance" [shape objects] - (-> (calc-bool-content* shape objects) - (impl/path-data))) - -(def update-bool-shape* nil) + (let [content (if (fn? wasm:calc-bool-content) + (wasm:calc-bool-content (get shape :bool-type) + (get shape :shapes)) + (calc-bool-content* shape objects))] + (impl/path-data content))) (defn update-bool-shape "Calculates the selrect+points for the boolean shape" [shape objects] - (if update-bool-shape* - (update-bool-shape* shape objects) - (let [content (calc-bool-content shape objects) - shape (assoc shape :content content)] - (update-geometry shape)))) + (let [content (calc-bool-content shape objects) + shape (assoc shape :content content)] + (update-geometry shape))) (defn shape-with-open-path? [shape] diff --git a/common/src/app/common/types/path/impl.cljc b/common/src/app/common/types/path/impl.cljc index 1efb35c152..09277b496b 100644 --- a/common/src/app/common/types/path/impl.cljc +++ b/common/src/app/common/types/path/impl.cljc @@ -609,6 +609,9 @@ (instance? js/Uint8Array buffer) (from-bytes (.-buffer buffer)) + (instance? js/Uint32Array buffer) + (from-bytes (.-buffer buffer)) + (instance? js/Int8Array buffer) (from-bytes (.-buffer buffer)) diff --git a/frontend/src/app/main/data/workspace/bool.cljs b/frontend/src/app/main/data/workspace/bool.cljs index d395fc1dd4..fe493660c5 100644 --- a/frontend/src/app/main/data/workspace/bool.cljs +++ b/frontend/src/app/main/data/workspace/bool.cljs @@ -21,24 +21,10 @@ [app.main.data.helpers :as dsh] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.shapes :as dwsh] - [app.main.features :as features] - [app.main.store :as st] - [app.render-wasm.api :as wasm.api] [beicon.v2.core :as rx] [cuerdas.core :as str] [potok.v2.core :as ptk])) -(defn update-bool-shape - [shape objects] - (let [content - (if (features/active-feature? @st/state "render-wasm/v1") - (wasm.api/calculate-bool (:bool-type shape) (reverse (:shapes shape))) - (path/calc-bool-content shape objects))] - (-> shape - (path/update-geometry content)))) - -(set! path/update-bool-shape* update-bool-shape) - (defn- create-bool-shape [id type name shapes objects] (let [shape-id @@ -65,7 +51,7 @@ (-> shape (merge (select-keys head path/bool-style-properties)) (cts/setup-shape) - (update-bool-shape objects))] + (path/update-bool-shape objects))] [shape (cph/get-position-on-parent objects (:id head))])) @@ -81,7 +67,7 @@ (assoc :type :bool) (assoc :bool-type type) (merge (select-keys head bool/style-properties)) - (update-bool-shape objects)))) + (path/update-bool-shape objects)))) (defn create-bool [type & {:keys [ids force-shape-id]}] diff --git a/frontend/src/app/render_wasm.cljs b/frontend/src/app/render_wasm.cljs index c0eb40231c..89642811bf 100644 --- a/frontend/src/app/render_wasm.cljs +++ b/frontend/src/app/render_wasm.cljs @@ -7,6 +7,7 @@ (ns app.render-wasm "A WASM based render API" (:require + [app.common.types.path] [app.common.types.shape :as shape] [app.render-wasm.api :as api] [app.render-wasm.shape :as wasm.shape])) @@ -15,5 +16,8 @@ (defn initialize [enabled?] + (if enabled? + (set! app.common.types.path/wasm:calc-bool-content api/calculate-bool) + (set! app.common.types.path/wasm:calc-bool-content nil)) (set! app.common.types.shape/wasm-enabled? enabled?) (set! app.common.types.shape/wasm-create-shape wasm.shape/create-shape)) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 0e5bdcb932..c6290c93b0 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -15,6 +15,7 @@ [app.common.types.fills :as types.fills] [app.common.types.fills.impl :as types.fills.impl] [app.common.types.path :as path] + [app.common.types.path.impl :as path.impl] [app.common.types.shape.layout :as ctl] [app.common.uuid :as uuid] [app.config :as cf] @@ -48,7 +49,7 @@ ;; All of these entries are in bytes so we need to adjust ;; these values to work with TypedArrays of 32 bits. ;; -(def CHILD-ENTRY-SIZE 16) +(def UUID-BYTE-SIZE 16) (def MODIFIER-ENTRY-SIZE 40) (def MODIFIER-ENTRY-TRANSFORM-OFFSET 16) (def GRID-LAYOUT-ROW-ENTRY-SIZE 5) @@ -174,7 +175,7 @@ (let [num-shapes (count shape-ids)] (perf/begin-measure "set-shape-children") (when (> num-shapes 0) - (let [offset (mem/alloc-bytes (* CHILD-ENTRY-SIZE num-shapes)) + (let [offset (mem/alloc-bytes (* UUID-BYTE-SIZE num-shapes)) heap (mem/get-heap-u32)] (loop [entries (seq shape-ids) @@ -182,7 +183,7 @@ (when-not (empty? entries) (let [id (first entries)] (sr/heapu32-set-uuid id heap (mem/ptr8->ptr32 current-offset)) - (recur (rest entries) (+ current-offset CHILD-ENTRY-SIZE))))))) + (recur (rest entries) (+ current-offset UUID-BYTE-SIZE))))))) (let [result (h/call wasm/internal-module "_set_children")] (perf/end-measure "set-shape-children") @@ -1060,17 +1061,14 @@ (defn shape-to-path [id] (use-shape id) - (let [offset (h/call wasm/internal-module "_current_to_path") - + (let [offset (h/call wasm/internal-module "_current_to_path") + offset (mem/ptr8->ptr32 offset) heapu32 (mem/get-heap-u32) - heapu8 (mem/get-heap-u8) - - len (aget heapu32 (mem/ptr8->ptr32 offset)) - from-offset (+ offset 4) - to-offset (+ offset 4 (* len RAW-SEGMENT-SIZE)) - - data (js/Uint8Array. (.slice heapu8 from-offset to-offset)) + length (aget heapu32 offset) + data (mem/slice heapu32 + (+ offset 1) + (+ offset 1 (* length (/ path.impl/SEGMENT-BYTE-SIZE 4)))) content (path/from-bytes data)] (h/call wasm/internal-module "_free_bytes") content)) @@ -1078,26 +1076,23 @@ (defn calculate-bool [bool-type ids] (let [num-ids (count ids) - offset (mem/alloc-bytes (* CHILD-ENTRY-SIZE num-ids)) - heap (mem/get-heap-u32)] + offset (mem/alloc-bytes-32 (* UUID-BYTE-SIZE num-ids)) + heap (mem/get-heap-u32)] - (loop [entries (seq ids) - current-offset offset] - (when-not (empty? entries) - (let [id (first entries)] - (sr/heapu32-set-uuid id heap (mem/ptr8->ptr32 current-offset)) - (recur (rest entries) (+ current-offset CHILD-ENTRY-SIZE)))))) + (reduce (fn [offset id] + (sr/heapu32-set-uuid id heap offset) + (+ offset (/ UUID-BYTE-SIZE 4))) + offset + (rseq ids))) - (let [offset (h/call wasm/internal-module "_calculate_bool" (sr/translate-bool-type bool-type)) + (let [offset (h/call wasm/internal-module "_calculate_bool" (sr/translate-bool-type bool-type)) + offset (mem/ptr8->ptr32 offset) heapu32 (mem/get-heap-u32) - heapu8 (mem/get-heap-u8) - - len (aget heapu32 (mem/ptr8->ptr32 offset)) - from-offset (+ offset 4) - to-offset (+ offset 4 (* len RAW-SEGMENT-SIZE)) - - data (js/Uint8Array. (.slice heapu8 from-offset to-offset)) + length (aget heapu32 offset) + data (mem/slice heapu32 + (+ offset 1) + (+ offset 1 (* length (/ path.impl/SEGMENT-BYTE-SIZE 4)))) content (path/from-bytes data)] (h/call wasm/internal-module "_free_bytes") content)) diff --git a/frontend/src/app/render_wasm/mem.cljs b/frontend/src/app/render_wasm/mem.cljs index ddfaf77c23..57db7d730f 100644 --- a/frontend/src/app/render_wasm/mem.cljs +++ b/frontend/src/app/render_wasm/mem.cljs @@ -59,3 +59,9 @@ "Returns a Float32Array view of the heap" [] (unchecked-get ^js wasm/internal-module "HEAPF32")) + +(defn slice + "Returns a copy of a portion of a typed array into a new typed array + object selected from start to end." + [heap start end] + (.slice ^js heap start end))