diff --git a/frontend/render_v2/rs/src/main.rs b/frontend/render_v2/rs/src/main.rs index b32948d2f3..68537373ba 100644 --- a/frontend/render_v2/rs/src/main.rs +++ b/frontend/render_v2/rs/src/main.rs @@ -109,16 +109,6 @@ pub unsafe extern "C" fn resize_surface(state: *mut State, width: i32, height: i state.set_surface(surface); } -#[no_mangle] -pub extern "C" fn make_color(r: i32, g: i32, b: i32, a: f32) -> Box { - Box::new(Color { - r: r as u8, - g: g as u8, - b: b as u8, - a, - }) -} - #[repr(C)] pub struct Color { r: u8, @@ -133,16 +123,10 @@ pub struct Rect { top: f32, right: f32, bottom: f32, -} - -#[no_mangle] -pub extern "C" fn make_rect(left: f32, top: f32, right: f32, bottom: f32) -> Box { - Box::new(Rect { - left, - top, - right, - bottom, - }) + r: f32, + g: f32, + b: f32, + a: f32, } #[no_mangle] @@ -156,6 +140,13 @@ pub extern "C" fn alloc_rects(len: usize) -> *mut Rect { return ptr; } +#[no_mangle] +pub unsafe fn free_rects(ptr: *mut Rect, len: usize) { + let buf = Vec::::from_raw_parts(ptr, len, len); + std::mem::forget(buf); +} + + /// Draws a rect at the specified coordinates with the give ncolor /// # Safety #[no_mangle] @@ -163,7 +154,6 @@ pub unsafe extern "C" fn draw_rect(state: *mut State, rect: &Rect, color: &Color let state = unsafe { state.as_mut() }.expect("got an invalid state pointer"); let r = skia::Rect::new(rect.left, rect.top, rect.right, rect.bottom); let color = skia::Color::from_argb((color.a * 255.0) as u8, color.r, color.g, color.b); - render_rect(&mut state.surface, r, color); } @@ -201,7 +191,7 @@ pub unsafe fn draw_shapes(state: *mut State, ptr: *mut Rect, len: usize, zoom: f let buf = Vec::::from_raw_parts(ptr, len, len); for rect in buf.iter() { let r = skia::Rect::new(rect.left, rect.top, rect.right, rect.bottom); - let color = skia::Color::from_argb(255, 0, 0, 0); + let color = skia::Color::from_argb((rect.a * 255.0) as u8, rect.r as u8, rect.g as u8, rect.b as u8); render_rect(&mut state.surface, r, color); } flush(state); diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs index a3db4c4520..0425f9e903 100644 --- a/frontend/src/app/main/ui/workspace/viewport.cljs +++ b/frontend/src/app/main/ui/workspace/viewport.cljs @@ -283,11 +283,14 @@ ;; redraw when vbox or shapes change (mf/with-effect - [vbox base-objects canvas-init? zoom] - (js/console.log "jibiri") + [vbox canvas-init? zoom] (when (mf/ref-val canvas-init?) - (js/console.log "jibiri ho") - (render-v2/draw-canvas vbox zoom base-objects)))) + (render-v2/draw-canvas vbox zoom base-objects))) + + (mf/with-effect + [base-objects] + (when (mf/ref-val canvas-init?) + (render-v2/set-objects vbox zoom base-objects)))) (hooks/setup-dom-events zoom disable-paste in-viewport? workspace-read-only? drawing-tool drawing-path?) (hooks/setup-viewport-size vport viewport-ref) diff --git a/frontend/src/app/render_v2.cljs b/frontend/src/app/render_v2.cljs index 87e56e4066..2f2e23e845 100644 --- a/frontend/src/app/render_v2.cljs +++ b/frontend/src/app/render_v2.cljs @@ -42,3 +42,9 @@ ;; Rust (contains? cf/flags :render-v2-rs) (render-v2-rs/draw-canvas vbox zoom base-objects))) + +(defn set-objects [vbox zoom base-objects] + (cond + ;; Rust + (contains? cf/flags :render-v2-rs) + (render-v2-rs/set-objects vbox zoom base-objects))) diff --git a/frontend/src/app/render_v2/rs.cljs b/frontend/src/app/render_v2/rs.cljs index 00c180974f..35dc861b7a 100644 --- a/frontend/src/app/render_v2/rs.cljs +++ b/frontend/src/app/render_v2/rs.cljs @@ -29,6 +29,32 @@ (js/requestAnimationFrame (fn [] (draw-shapes gpu-state shapes-ptr shapes-size zoom (- (:x vbox)) (- (:y vbox))))))) +(defn set-objects + [vbox zoom objects] + (let [alloc-rects (gobj/get ^js internal-module "_alloc_rects") + free_rects (gobj/get ^js internal-module "_free_rects") + supported-shapes (filter (fn [shape] (not= (:type shape) :frame)) (vals objects)) + heap (gobj/get ^js internal-module "HEAPF32") + ;; Each F32 are 4 bytes + ;; Each rect has: + ;; - 4 F32 for points coordinates + ;; - 4 F32 for color + ;; rect-size (* 8 4) + rect-size (* 8 4)] + (when shapes-ptr + (free_rects shapes-ptr shapes-size)) + + (let [ptr (alloc-rects (count supported-shapes))] + (doseq [[shape index] (zipmap supported-shapes (range))] + (let [sr (:selrect shape) + [r g b] (cc/hex->rgb (-> shape :fills first :fill-color)) + alpha (-> shape :fills first :fill-opacity) + mem (js/Float32Array. (.-buffer heap) (+ ptr (* rect-size index)) rect-size)] + (set! shapes-ptr ptr) + (set! shapes-size (count supported-shapes)) + (.set mem (js/Float32Array. (clj->js [(:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr) r g b (or alpha 1)])))))) + (draw-canvas vbox zoom objects))) + (defn set-canvas [canvas vbox zoom objects] (let [gl (gobj/get ^js internal-module "GL") @@ -40,32 +66,12 @@ handle (.registerContext gl context {"majorVersion" 2}) _ (.makeContextCurrent gl handle) ;; Initialize Skia - state (._init ^js internal-module (.-width canvas) (.-height canvas)) - translate (gobj/get ^js internal-module "_translate") - scale (gobj/get ^js internal-module "_scale") - alloc-rects (gobj/get ^js internal-module "_alloc_rects") - heap (gobj/get ^js internal-module "HEAPF32") - supported-shapes (filter (fn [shape] (not= (:type shape) :frame)) (vals objects)) - ptr (alloc-rects (count supported-shapes))] + state (._init ^js internal-module (.-width canvas) (.-height canvas))] (set! (.-width canvas) (.-clientWidth canvas)) (set! (.-height canvas) (.-clientHeight canvas)) (set! gpu-state state) - (set! shapes-ptr ptr) - (set! shapes-size (count supported-shapes)) - - (doseq [[shape index] (zipmap supported-shapes (range))] - (let [sr (:selrect shape) - [r g b] (cc/hex->rgb (-> shape :fills first :fill-color)) - alpha (-> shape :fills first :fill-opacity) - ;; color (make-color r g b alpha) - ;; rect (make-rect (:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr)) - ;; Each F32 are 4 bytes and each rect has 4 F32 - mem (js/Float32Array. (.-buffer heap) (+ ptr (* (* 4 4) index)) (* 4 4))] - ;; (js-debugger) - (.set mem (js/Float32Array. (clj->js [(:x1 sr) (:y1 sr) (:x2 sr) (:y2 sr)]))))) - - (draw-canvas vbox zoom objects) + (set-objects vbox zoom objects) (println "set-canvas ok" (.-width canvas) (.-height canvas)))) (defn on-init diff --git a/frontend/src/app/render_v2/rs.js b/frontend/src/app/render_v2/rs.js index 527c9fed54..7095b2b58c 100644 --- a/frontend/src/app/render_v2/rs.js +++ b/frontend/src/app/render_v2/rs.js @@ -28,7 +28,7 @@ var readyPromise = new Promise((resolve, reject) => { readyPromiseResolve = resolve; readyPromiseReject = reject; }); -["_alloc_rects","_draw_rect","_draw_shapes","_flush","_init","_main","_make_color","_make_rect","_reset_canvas","_resize_surface","_scale","_translate","getExceptionMessage","incrementExceptionRefcount","decrementExceptionRefcount","_memory","___indirect_function_table","onRuntimeInitialized"].forEach((prop) => { +["_alloc_rects","_draw_rect","_draw_shapes","_flush","_free_rects","_init","_main","_reset_canvas","_resize_surface","_scale","_translate","getExceptionMessage","incrementExceptionRefcount","decrementExceptionRefcount","_memory","___indirect_function_table","onRuntimeInitialized"].forEach((prop) => { if (!Object.getOwnPropertyDescriptor(readyPromise, prop)) { Object.defineProperty(readyPromise, prop, { get: () => abort('You are getting ' + prop + ' on the Promise object, instead of the instance. Use .then() to get called back with the instance, see the MODULARIZE docs in src/settings.js'), @@ -8563,9 +8563,8 @@ var wasmExports = createWasm(); var ___wasm_call_ctors = createExportWrapper('__wasm_call_ctors', 0); var _init = Module['_init'] = createExportWrapper('init', 2); var _resize_surface = Module['_resize_surface'] = createExportWrapper('resize_surface', 3); -var _make_color = Module['_make_color'] = createExportWrapper('make_color', 4); -var _make_rect = Module['_make_rect'] = createExportWrapper('make_rect', 4); var _alloc_rects = Module['_alloc_rects'] = createExportWrapper('alloc_rects', 1); +var _free_rects = Module['_free_rects'] = createExportWrapper('free_rects', 2); var _draw_rect = Module['_draw_rect'] = createExportWrapper('draw_rect', 3); var _flush = Module['_flush'] = createExportWrapper('flush', 1); var _translate = Module['_translate'] = createExportWrapper('translate', 3);