From 5765d1c56c013bcc8ef9bdb2b2af52f978a0f02e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Tue, 15 Apr 2025 11:04:36 +0200 Subject: [PATCH] :recycle: Switch to a f32 offset for gradient stops --- frontend/src/app/render_wasm/api.cljs | 17 ++++------ .../app/render_wasm/serializers/fills.cljs | 32 +++++++++++-------- render-wasm/src/main.rs | 10 ++++-- render-wasm/src/shapes/fills.rs | 24 ++++++-------- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index cd3ebbeb5..3fc36ccce 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -51,7 +51,7 @@ (def GRID-LAYOUT-COLUMN-ENTRY-SIZE 5) (def GRID-LAYOUT-CELL-ENTRY-SIZE 37) - +;; FIXME: use `gradient-byte-size` instead (defn gradient-stop-get-entries-size [stops] (mem/get-list-size stops sr-fills/GRADIENT-STOP-SIZE)) @@ -238,7 +238,7 @@ :linear (let [size (gradient-byte-size gradient) offset (mem/alloc-bytes size) - heap (mem/get-heap-u8)] + heap (mem/get-heap-u32)] (sr-fills/serialize-linear-fill gradient opacity heap offset) (h/call wasm/internal-module "_add_shape_linear_fill")) :radial @@ -297,11 +297,10 @@ (cond (some? gradient) - (let [stops (:stops gradient) - size (gradient-stop-get-entries-size stops) + (let [stops (:stops gradient) + size (gradient-stop-get-entries-size stops) offset (mem/alloc-bytes size) - heap (mem/get-heap-u8) - mem (js/Uint8Array. (.-buffer heap) offset size)] + heap (mem/get-heap-u8)] (if (= (:type gradient) :linear) (h/call wasm/internal-module "_add_shape_stroke_linear_fill" (:start-x gradient) @@ -316,11 +315,7 @@ (:end-y gradient) opacity (:width gradient))) - (.set mem (js/Uint8Array. (clj->js (flatten (map (fn [stop] - (let [[r g b a] (sr-clr/rgba-bytes-from-hex (:color stop) (:opacity stop)) - offset (:offset stop)] - [r g b a (* 100 offset)])) - stops))))) + (sr-fills/serialize-gradient-stops stops heap offset) (h/call wasm/internal-module "_add_shape_stroke_stops")) (some? image) diff --git a/frontend/src/app/render_wasm/serializers/fills.cljs b/frontend/src/app/render_wasm/serializers/fills.cljs index 194080d23..d92079459 100644 --- a/frontend/src/app/render_wasm/serializers/fills.cljs +++ b/frontend/src/app/render_wasm/serializers/fills.cljs @@ -3,12 +3,26 @@ [app.common.data.macros :as dm] [app.render-wasm.serializers.color :as clr])) -(def GRADIENT-STOP-SIZE 5) +(def GRADIENT-STOP-SIZE 8) (def GRADIENT-BASE-SIZE 24) +(defn serialize-gradient-stops + [stops heap offset] + (let [dview (js/DataView. (.-buffer heap))] + (loop [stops (seq stops) offset offset] + (when-not (empty? stops) + (let [stop (first stops) + hex-color (dm/get-prop stop :color) + opacity (dm/get-prop stop :opacity) + argb (clr/hex->u32argb hex-color opacity) + stop-offset (dm/get-prop stop :offset)] + (.setUint32 dview offset argb true) + (.setFloat32 dview (+ offset 4) stop-offset true) + (recur (rest stops) (+ offset GRADIENT-STOP-SIZE))))))) + (defn serialize-linear-fill - [gradient opacity heap-u8 offset] - (let [dview (js/DataView. (.-buffer heap-u8)) + [gradient opacity heap offset] + (let [dview (js/DataView. (.-buffer heap)) start-x (dm/get-prop gradient :start-x) start-y (dm/get-prop gradient :start-y) end-x (dm/get-prop gradient :end-x) @@ -21,14 +35,4 @@ (.setFloat32 dview (+ offset 12) end-y true) (.setFloat32 dview (+ offset 16) opacity true) (.setFloat32 dview (+ offset 20) width true) - (loop [stops (seq stops) idx 0] - (when-not (empty? stops) - (let [stop (first stops) - hex-color (dm/get-prop stop :color) - opacity (dm/get-prop stop :opacity) - rgba (clr/hex->u32argb hex-color opacity) - stop-offset (* 100 (dm/get-prop stop :offset)) - dview-offset (+ (* idx 5) offset 24)] - (.setUint32 dview dview-offset rgba true) - (.setUint8 dview (+ dview-offset 4) stop-offset) - (recur (rest stops) (+ idx 1))))))) \ No newline at end of file + (serialize-gradient-stops stops heap (+ offset GRADIENT-BASE-SIZE)))) \ No newline at end of file diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index 291d76e79..d37088b10 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -306,7 +306,10 @@ pub extern "C" fn add_shape_fill_stops() { let entries: Vec<_> = bytes .chunks(size_of::()) - .map(|data| shapes::RawStopData::from_bytes(data.try_into().unwrap())) + .map(|data| { + let raw_stop_bytes: [u8; RAW_STOP_DATA_SIZE] = data.try_into().unwrap(); + shapes::RawStopData::from(raw_stop_bytes) + }) .collect(); with_current_shape!(state, |shape: &mut Shape| { @@ -523,7 +526,10 @@ pub extern "C" fn add_shape_stroke_stops() { let entries: Vec<_> = bytes .chunks(size_of::()) - .map(|data| shapes::RawStopData::from_bytes(data.try_into().unwrap())) + .map(|data| { + let raw_stop_bytes: [u8; RAW_STOP_DATA_SIZE] = data.try_into().unwrap(); + shapes::RawStopData::from(raw_stop_bytes) + }) .collect(); with_current_shape!(state, |shape: &mut Shape| { diff --git a/render-wasm/src/shapes/fills.rs b/render-wasm/src/shapes/fills.rs index af6daa84a..370d049fa 100644 --- a/render-wasm/src/shapes/fills.rs +++ b/render-wasm/src/shapes/fills.rs @@ -43,13 +43,13 @@ impl RawGradientData { } } -pub const RAW_STOP_DATA_SIZE: usize = 5; +pub const RAW_STOP_DATA_SIZE: usize = 8; #[derive(Debug)] #[repr(C)] pub struct RawStopData { color: u32, - offset: u8, + offset: f32, } impl RawStopData { @@ -58,22 +58,16 @@ impl RawStopData { } pub fn offset(&self) -> f32 { - self.offset as f32 / 100.0 - } - - pub fn from_bytes(bytes: [u8; 5]) -> Self { - let color_bytes: [u8; 4] = bytes[0..4].try_into().unwrap(); - Self { - color: u32::from_le_bytes(color_bytes), - offset: bytes[4], - } + self.offset } } -impl From<[u8; 5]> for RawStopData { - // TODO: remove from_bytes and copy its implementation here - fn from(bytes: [u8; 5]) -> Self { - Self::from_bytes(bytes) +impl From<[u8; RAW_STOP_DATA_SIZE]> for RawStopData { + fn from(bytes: [u8; RAW_STOP_DATA_SIZE]) -> Self { + Self { + color: u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]), + offset: f32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]), + } } }