mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🎉 Add render perf options
This commit is contained in:
parent
62ec66b974
commit
612855452a
@ -1599,6 +1599,42 @@
|
||||
(when (and (number? n) (not (js/isNaN n)) (pos? n))
|
||||
n))))
|
||||
|
||||
(defn- wasm-blur-downscale-threshold-from-route-params
|
||||
"Reads optional `aa_threshold` query param from the router"
|
||||
[]
|
||||
(when-let [raw (let [p (rt/get-params @st/state)]
|
||||
(:blur_downscale_threshold p))]
|
||||
(let [n (if (string? raw) (js/parseFloat raw) raw)]
|
||||
(when (and (number? n) (not (js/isNaN n)) (pos? n))
|
||||
n))))
|
||||
|
||||
(defn- wasm-max-blocking-time-ms-from-route-params
|
||||
"Reads optional `aa_threshold` query param from the router"
|
||||
[]
|
||||
(when-let [raw (let [p (rt/get-params @st/state)]
|
||||
(:max_blocking_time_ms p))]
|
||||
(let [n (if (string? raw) (js/parseInt raw 10) raw)]
|
||||
(when (and (number? n) (not (js/isNaN n)) (pos? n))
|
||||
n))))
|
||||
|
||||
(defn- wasm-node-batch-threshold-from-route-params
|
||||
"Reads optional `aa_threshold` query param from the router"
|
||||
[]
|
||||
(when-let [raw (let [p (rt/get-params @st/state)]
|
||||
(:node_batch_threshold p))]
|
||||
(let [n (if (string? raw) (js/parseInt raw 10) raw)]
|
||||
(when (and (number? n) (not (js/isNaN n)) (pos? n))
|
||||
n))))
|
||||
|
||||
(defn- wasm-viewport-interest-area-threshold-from-route-params
|
||||
"Reads optional `aa_threshold` query param from the router"
|
||||
[]
|
||||
(when-let [raw (let [p (rt/get-params @st/state)]
|
||||
(:viewport_interest_area_threshold p))]
|
||||
(let [n (if (string? raw) (js/parseInt raw 10) raw)]
|
||||
(when (and (number? n) (not (js/isNaN n)) (pos? n))
|
||||
n))))
|
||||
|
||||
(defn set-canvas-size
|
||||
[canvas]
|
||||
(let [width (or (.-clientWidth ^js canvas) (.-width ^js canvas))
|
||||
@ -1636,6 +1672,14 @@
|
||||
(h/call wasm/internal-module "_set_render_options" flags dpr)
|
||||
(when-let [t (wasm-aa-threshold-from-route-params)]
|
||||
(h/call wasm/internal-module "_set_antialias_threshold" t))
|
||||
(when-let [t (wasm-viewport-interest-area-threshold-from-route-params)]
|
||||
(h/call wasm/internal-module "_set_viewport_interest_area_threshold" t))
|
||||
(when-let [t (wasm-max-blocking-time-ms-from-route-params)]
|
||||
(h/call wasm/internal-module "_set_max_blocking_time_ms" t))
|
||||
(when-let [t (wasm-node-batch-threshold-from-route-params)]
|
||||
(h/call wasm/internal-module "_set_node_batch_threshold" t))
|
||||
(when-let [t (wasm-blur-downscale-threshold-from-route-params)]
|
||||
(h/call wasm/internal-module "_set_blur_downscale_threshold" t))
|
||||
(when-let [max-tex (webgl/max-texture-size context)]
|
||||
(h/call wasm/internal-module "_set_max_atlas_texture_size" max-tex))
|
||||
|
||||
|
||||
@ -145,6 +145,48 @@ pub extern "C" fn set_render_options(debug: u32, dpr: f32) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[wasm_error]
|
||||
pub extern "C" fn set_viewport_interest_area_threshold(
|
||||
viewport_interest_area_threshold: i32,
|
||||
) -> Result<()> {
|
||||
with_state_mut!(state, {
|
||||
let render_state = state.render_state_mut();
|
||||
render_state.set_viewport_interest_area_threshold(viewport_interest_area_threshold);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[wasm_error]
|
||||
pub extern "C" fn set_max_blocking_time_ms(max_blocking_time_ms: i32) -> Result<()> {
|
||||
with_state_mut!(state, {
|
||||
let render_state = state.render_state_mut();
|
||||
render_state.set_max_blocking_time_ms(max_blocking_time_ms);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[wasm_error]
|
||||
pub extern "C" fn set_node_batch_threshold(node_batch_threshold: i32) -> Result<()> {
|
||||
with_state_mut!(state, {
|
||||
let render_state = state.render_state_mut();
|
||||
render_state.set_node_batch_threshold(node_batch_threshold);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[wasm_error]
|
||||
pub extern "C" fn set_blur_downscale_threshold(blur_downscale_threshold: f32) -> Result<()> {
|
||||
with_state_mut!(state, {
|
||||
let render_state = state.render_state_mut();
|
||||
render_state.set_blur_downscale_threshold(blur_downscale_threshold);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[wasm_error]
|
||||
pub extern "C" fn set_antialias_threshold(threshold: f32) -> Result<()> {
|
||||
|
||||
@ -37,15 +37,6 @@ use crate::wapi;
|
||||
pub use fonts::*;
|
||||
pub use images::*;
|
||||
|
||||
// This is the extra area used for tile rendering (tiles beyond viewport).
|
||||
// Higher values pre-render more tiles, reducing empty squares during pan but using more memory.
|
||||
const VIEWPORT_INTEREST_AREA_THRESHOLD: i32 = 3;
|
||||
|
||||
const MAX_BLOCKING_TIME_MS: i32 = 32;
|
||||
const NODE_BATCH_THRESHOLD: i32 = 3;
|
||||
|
||||
const BLUR_DOWNSCALE_THRESHOLD: f32 = 8.0;
|
||||
|
||||
type ClipStack = Vec<(Rect, Option<Corners>, Matrix)>;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -345,9 +336,8 @@ pub(crate) struct RenderState {
|
||||
pub cache_cleared_this_render: bool,
|
||||
}
|
||||
|
||||
pub fn get_cache_size(viewbox: Viewbox, scale: f32) -> skia::ISize {
|
||||
pub fn get_cache_size(viewbox: Viewbox, scale: f32, interest: i32) -> skia::ISize {
|
||||
// First we retrieve the extended area of the viewport that we could render.
|
||||
let interest = VIEWPORT_INTEREST_AREA_THRESHOLD;
|
||||
let TileRect(isx, isy, iex, iey) =
|
||||
tiles::get_tiles_for_viewbox_with_interest(viewbox, interest, scale);
|
||||
|
||||
@ -382,10 +372,11 @@ impl RenderState {
|
||||
|
||||
let viewbox = Viewbox::new(width as f32, height as f32);
|
||||
let tiles = tiles::TileHashMap::new();
|
||||
let options = RenderOptions::default();
|
||||
|
||||
Ok(RenderState {
|
||||
gpu_state: gpu_state.clone(),
|
||||
options: RenderOptions::default(),
|
||||
options,
|
||||
surfaces,
|
||||
fonts,
|
||||
viewbox,
|
||||
@ -402,7 +393,7 @@ impl RenderState {
|
||||
tiles,
|
||||
tile_viewbox: tiles::TileViewbox::new_with_interest(
|
||||
viewbox,
|
||||
VIEWPORT_INTEREST_AREA_THRESHOLD,
|
||||
options.viewport_interest_area_threshold,
|
||||
1.0,
|
||||
),
|
||||
pending_tiles: PendingTiles::new_empty(),
|
||||
@ -631,6 +622,22 @@ impl RenderState {
|
||||
self.options.set_antialias_threshold(value);
|
||||
}
|
||||
|
||||
pub fn set_viewport_interest_area_threshold(&mut self, value: i32) {
|
||||
self.options.set_viewport_interest_area_threshold(value);
|
||||
}
|
||||
|
||||
pub fn set_node_batch_threshold(&mut self, value: i32) {
|
||||
self.options.set_node_batch_threshold(value);
|
||||
}
|
||||
|
||||
pub fn set_max_blocking_time_ms(&mut self, value: i32) {
|
||||
self.options.set_max_blocking_time_ms(value);
|
||||
}
|
||||
|
||||
pub fn set_blur_downscale_threshold(&mut self, value: f32) {
|
||||
self.options.set_blur_downscale_threshold(value);
|
||||
}
|
||||
|
||||
pub fn set_background_color(&mut self, color: skia::Color) {
|
||||
self.background_color = color;
|
||||
}
|
||||
@ -1495,7 +1502,7 @@ impl RenderState {
|
||||
// Scale and translate the target according to the cached data
|
||||
let navigate_zoom = self.viewbox.zoom / self.cached_viewbox.zoom;
|
||||
|
||||
let interest = VIEWPORT_INTEREST_AREA_THRESHOLD;
|
||||
let interest = self.options.viewport_interest_area_threshold;
|
||||
let TileRect(start_tile_x, start_tile_y, _, _) =
|
||||
tiles::get_tiles_for_viewbox_with_interest(
|
||||
self.cached_viewbox,
|
||||
@ -1692,15 +1699,25 @@ impl RenderState {
|
||||
s.canvas().scale((scale, scale));
|
||||
});
|
||||
|
||||
let viewbox_cache_size = get_cache_size(self.viewbox, scale);
|
||||
let cached_viewbox_cache_size = get_cache_size(self.cached_viewbox, scale);
|
||||
let viewbox_cache_size = get_cache_size(
|
||||
self.viewbox,
|
||||
scale,
|
||||
self.options.viewport_interest_area_threshold,
|
||||
);
|
||||
let cached_viewbox_cache_size = get_cache_size(
|
||||
self.cached_viewbox,
|
||||
scale,
|
||||
self.options.viewport_interest_area_threshold,
|
||||
);
|
||||
// Only resize cache if the new size is larger than the cached size
|
||||
// This avoids unnecessary surface recreations when the cache size decreases
|
||||
if viewbox_cache_size.width > cached_viewbox_cache_size.width
|
||||
|| viewbox_cache_size.height > cached_viewbox_cache_size.height
|
||||
{
|
||||
self.surfaces
|
||||
.resize_cache(viewbox_cache_size, VIEWPORT_INTEREST_AREA_THRESHOLD)?;
|
||||
self.surfaces.resize_cache(
|
||||
viewbox_cache_size,
|
||||
self.options.viewport_interest_area_threshold,
|
||||
)?;
|
||||
}
|
||||
|
||||
// FIXME - review debug
|
||||
@ -1909,10 +1926,10 @@ impl RenderState {
|
||||
|
||||
#[inline]
|
||||
pub fn should_stop_rendering(&self, iteration: i32, timestamp: i32) -> bool {
|
||||
if iteration % NODE_BATCH_THRESHOLD != 0 {
|
||||
if iteration % self.options.node_batch_threshold != 0 {
|
||||
return false;
|
||||
}
|
||||
if performance::get_time() - timestamp <= MAX_BLOCKING_TIME_MS {
|
||||
if performance::get_time() - timestamp <= self.options.max_blocking_time_ms {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2303,9 +2320,10 @@ impl RenderState {
|
||||
// Bounds above were computed from the original sigma so filter surface coverage is correct.
|
||||
// Maximum downscale is 1/BLUR_DOWNSCALE_THRESHOLD (i.e. 8x): beyond that the
|
||||
// filter surface becomes too small and quality degrades noticeably.
|
||||
const MIN_BLUR_DOWNSCALE: f32 = 1.0 / BLUR_DOWNSCALE_THRESHOLD;
|
||||
let blur_downscale = if shadow.blur > BLUR_DOWNSCALE_THRESHOLD {
|
||||
(BLUR_DOWNSCALE_THRESHOLD / shadow.blur).max(MIN_BLUR_DOWNSCALE)
|
||||
let blur_downscale_threshold: f32 = self.options.blur_downscale_threshold;
|
||||
let min_blur_downscale: f32 = 1.0 / blur_downscale_threshold;
|
||||
let blur_downscale = if shadow.blur > blur_downscale_threshold {
|
||||
(blur_downscale_threshold / shadow.blur).max(min_blur_downscale)
|
||||
} else {
|
||||
1.0
|
||||
};
|
||||
|
||||
@ -4,6 +4,14 @@ const PROFILE_REBUILD_TILES: u32 = 0x02;
|
||||
const TEXT_EDITOR_V3: u32 = 0x04;
|
||||
const SHOW_WASM_INFO: u32 = 0x08;
|
||||
|
||||
// Render performance options
|
||||
// This is the extra area used for tile rendering (tiles beyond viewport).
|
||||
// Higher values pre-render more tiles, reducing empty squares during pan but using more memory.
|
||||
const VIEWPORT_INTEREST_AREA_THRESHOLD: i32 = 3;
|
||||
const MAX_BLOCKING_TIME_MS: i32 = 32;
|
||||
const NODE_BATCH_THRESHOLD: i32 = 3;
|
||||
const BLUR_DOWNSCALE_THRESHOLD: f32 = 8.0;
|
||||
const ANTIALIAS_THRESHOLD: f32 = 7.0;
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub struct RenderOptions {
|
||||
pub flags: u32,
|
||||
@ -16,6 +24,10 @@ pub struct RenderOptions {
|
||||
interactive_transform: bool,
|
||||
/// Minimum on-screen size (CSS px at 1:1 zoom) above which vector antialiasing is enabled.
|
||||
pub antialias_threshold: f32,
|
||||
pub viewport_interest_area_threshold: i32,
|
||||
pub max_blocking_time_ms: i32,
|
||||
pub node_batch_threshold: i32,
|
||||
pub blur_downscale_threshold: f32,
|
||||
}
|
||||
|
||||
impl Default for RenderOptions {
|
||||
@ -25,7 +37,11 @@ impl Default for RenderOptions {
|
||||
dpr: None,
|
||||
fast_mode: false,
|
||||
interactive_transform: false,
|
||||
antialias_threshold: 7.0,
|
||||
antialias_threshold: ANTIALIAS_THRESHOLD,
|
||||
viewport_interest_area_threshold: VIEWPORT_INTEREST_AREA_THRESHOLD,
|
||||
max_blocking_time_ms: MAX_BLOCKING_TIME_MS,
|
||||
node_batch_threshold: NODE_BATCH_THRESHOLD,
|
||||
blur_downscale_threshold: BLUR_DOWNSCALE_THRESHOLD,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -85,4 +101,28 @@ impl RenderOptions {
|
||||
self.antialias_threshold = value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_blur_downscale_threshold(&mut self, value: f32) {
|
||||
if value.is_finite() && value > 0.0 {
|
||||
self.blur_downscale_threshold = value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_viewport_interest_area_threshold(&mut self, value: i32) {
|
||||
if value >= 0 {
|
||||
self.viewport_interest_area_threshold = value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_node_batch_threshold(&mut self, value: i32) {
|
||||
if value > 0 {
|
||||
self.node_batch_threshold = value;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_max_blocking_time_ms(&mut self, value: i32) {
|
||||
if value > 0 {
|
||||
self.max_blocking_time_ms = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user