From 3e99de19f5c38c67dcc420a04ddc4b211e94aa8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Mon, 25 Nov 2024 15:39:19 +0100 Subject: [PATCH] :recycle: Refactor debug options into its own struct, along with dpr --- frontend/src/app/render_wasm/api.cljs | 12 ++++----- render-wasm/src/main.rs | 31 ++++++++++++++++-------- render-wasm/src/render.rs | 35 ++++++++++++++++++++++++--- render-wasm/src/state.rs | 15 +++--------- 4 files changed, 62 insertions(+), 31 deletions(-) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index 350de85aa..bc9adad33 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -181,17 +181,17 @@ (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) + dpr js/window.devicePixelRatio ;; Register the context with emscripten handle (.registerContext ^js gl context #js {"majorVersion" 2})] (.makeContextCurrent ^js gl handle) - ;; Initialize Skia - (^function init-fn (.-width ^js canvas) - (.-height ^js canvas) - 1) + + ;; Initialize Wasm Render Engine + (h/call internal-module "_init" (.-width ^js canvas) (.-height ^js canvas)) + (h/call internal-module "_set_render_options" 0x01 (or dpr 0)) + (set! (.-width canvas) (.-clientWidth ^js canvas)) (set! (.-height canvas) (.-clientHeight ^js canvas)))) diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs index ef91740b3..de5098fb3 100644 --- a/render-wasm/src/main.rs +++ b/render-wasm/src/main.rs @@ -1,11 +1,11 @@ -pub mod debug; -pub mod images; -pub mod math; -pub mod render; -pub mod shapes; -pub mod state; -pub mod utils; -pub mod view; +mod debug; +mod images; +mod math; +mod render; +mod shapes; +mod state; +mod utils; +mod view; use skia_safe as skia; @@ -31,13 +31,24 @@ fn init_gl() { /// This is called from JS after the WebGL context has been created. #[no_mangle] -pub extern "C" fn init(width: i32, height: i32, debug: u32) { - let state_box = Box::new(State::with_capacity(width, height, debug, 2048)); +pub extern "C" fn init(width: i32, height: i32) { + let state_box = Box::new(State::new(width, height, 2048)); unsafe { STATE = Some(state_box); } } +#[no_mangle] +pub extern "C" fn set_render_options(debug: u32, dpr: f32) { + let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); + let render_state = state.render_state(); + + render_state.set_debug_flags(debug); + if dpr > 1.0 { + render_state.set_dpr(Some(dpr)); + } +} + #[no_mangle] pub unsafe extern "C" fn render() { let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer"); diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs index 4c6074c8d..f1c2eed21 100644 --- a/render-wasm/src/render.rs +++ b/render-wasm/src/render.rs @@ -59,12 +59,25 @@ pub(crate) struct CachedSurfaceImage { pub is_complete: bool, } +#[derive(Debug, Default, Copy, Clone, PartialEq)] +struct RenderOptions { + debug_flags: u32, + dpr: Option, +} + +impl RenderOptions { + pub fn is_debug_visible(&self) -> bool { + self.debug_flags & debug::DEBUG_VISIBLE == debug::DEBUG_VISIBLE + } +} + pub(crate) struct RenderState { gpu_state: GpuState, pub final_surface: skia::Surface, pub drawing_surface: skia::Surface, pub debug_surface: skia::Surface, pub cached_surface_image: Option, + options: RenderOptions, } impl RenderState { @@ -85,9 +98,18 @@ impl RenderState { drawing_surface, debug_surface, cached_surface_image: None, + options: RenderOptions::default(), } } + pub fn set_debug_flags(&mut self, debug: u32) { + self.options.debug_flags = debug; + } + + pub fn set_dpr(&mut self, dpr: Option) { + self.options.dpr = dpr; + } + pub fn resize(&mut self, width: i32, height: i32) { let surface = self.gpu_state.create_target_surface(width, height); self.final_surface = surface; @@ -176,7 +198,7 @@ impl RenderState { .clear(skia::Color::TRANSPARENT); } - pub fn navigate(&mut self, viewbox: &Viewbox, shapes: &HashMap, debug: u32) { + pub fn navigate(&mut self, viewbox: &Viewbox, shapes: &HashMap) { self.reset_canvas(); if let Some(cached_surface_image) = &self.cached_surface_image { // If we are drawing something bigger than the visible let's do a redraw @@ -190,7 +212,7 @@ impl RenderState { > -cached_surface_image.viewbox.y + cached_surface_image.viewbox.area.height())) { - self.render_all(viewbox, shapes, true, debug); + self.render_all(viewbox, shapes, true); } else { let image = &cached_surface_image.image; let paint = skia::Paint::default(); @@ -226,11 +248,11 @@ impl RenderState { viewbox: &Viewbox, shapes: &HashMap, generate_cached_surface_image: bool, - debug: u32, // Debug flags ) { self.reset_canvas(); self.scale(viewbox.zoom, viewbox.zoom); self.translate(viewbox.x, viewbox.y); + let is_complete = self.render_shape_tree(&Uuid::nil(), viewbox, shapes); if generate_cached_surface_image || self.cached_surface_image.is_none() { self.cached_surface_image = Some(CachedSurfaceImage { @@ -239,7 +261,8 @@ impl RenderState { is_complete, }); } - if debug & debug::DEBUG_VISIBLE == debug::DEBUG_VISIBLE { + + if self.options.is_debug_visible() { self.render_debug(viewbox); } @@ -251,12 +274,14 @@ impl RenderState { paint.set_style(skia::PaintStyle::Stroke); paint.set_color(skia::Color::from_argb(255, 255, 0, 255)); paint.set_stroke_width(1.); + let mut scaled_rect = viewbox.area.clone(); let x = 100. + scaled_rect.x() * 0.2; let y = 100. + scaled_rect.y() * 0.2; let width = scaled_rect.width() * 0.2; let height = scaled_rect.height() * 0.2; scaled_rect.set_xywh(x, y, width, height); + self.debug_surface.canvas().draw_rect(scaled_rect, &paint); } @@ -269,12 +294,14 @@ impl RenderState { skia::Color::from_argb(255, 0, 255, 255) }); paint.set_stroke_width(1.); + let mut scaled_rect = shape.selrect.clone(); let x = 100. + scaled_rect.x() * 0.2; let y = 100. + scaled_rect.y() * 0.2; let width = scaled_rect.width() * 0.2; let height = scaled_rect.height() * 0.2; scaled_rect.set_xywh(x, y, width, height); + self.debug_surface.canvas().draw_rect(scaled_rect, &paint); } diff --git a/render-wasm/src/state.rs b/render-wasm/src/state.rs index 2f602c970..916a6ff85 100644 --- a/render-wasm/src/state.rs +++ b/render-wasm/src/state.rs @@ -12,7 +12,6 @@ use crate::view::Viewbox; /// Note that rust-skia data structures are not thread safe, so a state /// must not be shared between different Web Workers. pub(crate) struct State<'a> { - pub debug: u32, pub render_state: RenderState, pub current_id: Option, pub current_shape: Option<&'a mut Shape>, @@ -21,9 +20,8 @@ pub(crate) struct State<'a> { } impl<'a> State<'a> { - pub fn with_capacity(width: i32, height: i32, debug: u32, capacity: usize) -> Self { + pub fn new(width: i32, height: i32, capacity: usize) -> Self { State { - debug, render_state: RenderState::new(width, height), current_id: None, current_shape: None, @@ -49,17 +47,12 @@ impl<'a> State<'a> { } pub fn navigate(&mut self) { - self.render_state - .navigate(&self.viewbox, &self.shapes, self.debug); + self.render_state.navigate(&self.viewbox, &self.shapes); } pub fn render_all(&mut self, generate_cached_surface_image: bool) { - self.render_state.render_all( - &self.viewbox, - &self.shapes, - generate_cached_surface_image, - self.debug, - ); + self.render_state + .render_all(&self.viewbox, &self.shapes, generate_cached_surface_image); } pub fn use_shape(&'a mut self, id: Uuid) {