mirror of
https://github.com/penpot/penpot.git
synced 2026-05-25 09:53:44 +00:00
Merge pull request #9200 from penpot/azazeln28-build-time-performance-optimizations
🔧 Change build and cargo settings
This commit is contained in:
commit
1c129ded1f
@ -135,6 +135,14 @@
|
|||||||
(wasm.mem/free)
|
(wasm.mem/free)
|
||||||
text)))
|
text)))
|
||||||
|
|
||||||
|
(defn ^:export wasmRenderStats
|
||||||
|
[]
|
||||||
|
(let [module wasm/internal-module
|
||||||
|
f (when module (unchecked-get module "_render_stats"))]
|
||||||
|
(if (fn? f)
|
||||||
|
(wasm.h/call module "_render_stats")
|
||||||
|
(js/console.warn "[debug] render-wasm module not ready or missing _render_stats"))))
|
||||||
|
|
||||||
(defn ^:export wasmAtlasConsole
|
(defn ^:export wasmAtlasConsole
|
||||||
"Logs the current render-wasm atlas as an image in the JS console (if present)."
|
"Logs the current render-wasm atlas as an image in the JS console (if present)."
|
||||||
[]
|
[]
|
||||||
|
|||||||
@ -10,6 +10,7 @@ build = "build.rs"
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
stats = []
|
||||||
profile = ["profile-macros", "profile-raf"]
|
profile = ["profile-macros", "profile-raf"]
|
||||||
profile-macros = []
|
profile-macros = []
|
||||||
profile-raf = []
|
profile-raf = []
|
||||||
@ -36,4 +37,6 @@ thiserror = "2.0.18"
|
|||||||
uuid = { version = "1.11.0", features = ["v4", "js"] }
|
uuid = { version = "1.11.0", features = ["v4", "js"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = "s"
|
opt-level = 3
|
||||||
|
lto = "fat"
|
||||||
|
strip = true
|
||||||
|
|||||||
@ -31,8 +31,8 @@ export EM_MALLOC="dlmalloc"
|
|||||||
|
|
||||||
export EMCC_CFLAGS="--no-entry \
|
export EMCC_CFLAGS="--no-entry \
|
||||||
--js-library src/js/wapi.js \
|
--js-library src/js/wapi.js \
|
||||||
-sASSERTIONS=1 \
|
-sMALLOC=$EM_MALLOC \
|
||||||
-sALLOW_TABLE_GROWTH=1 \
|
-sALLOW_TABLE_GROWTH=0 \
|
||||||
-sALLOW_MEMORY_GROWTH=1 \
|
-sALLOW_MEMORY_GROWTH=1 \
|
||||||
-sINITIAL_HEAP=$EM_INITIAL_HEAP \
|
-sINITIAL_HEAP=$EM_INITIAL_HEAP \
|
||||||
-sMEMORY_GROWTH_GEOMETRIC_STEP=$EM_MEMORY_GROWTH_GEOMETRIC_STEP \
|
-sMEMORY_GROWTH_GEOMETRIC_STEP=$EM_MEMORY_GROWTH_GEOMETRIC_STEP \
|
||||||
@ -50,13 +50,13 @@ export CARGO_PARAMS="${@:2}";
|
|||||||
|
|
||||||
if [ "$BUILD_MODE" = "release" ]; then
|
if [ "$BUILD_MODE" = "release" ]; then
|
||||||
export CARGO_PARAMS="--release $CARGO_PARAMS"
|
export CARGO_PARAMS="--release $CARGO_PARAMS"
|
||||||
export EMCC_CFLAGS="-Os $EMCC_CFLAGS"
|
export EMCC_CFLAGS="-O3 -sASSERTIONS=0 $EMCC_CFLAGS"
|
||||||
else
|
else
|
||||||
# TODO: Extra parameters that could be good to look into:
|
# TODO: Extra parameters that could be good to look into:
|
||||||
# -gseparate-dwarf
|
# -gseparate-dwarf
|
||||||
# -gsplit-dwarf
|
# -gsplit-dwarf
|
||||||
# -gsource-map
|
# -gsource-map
|
||||||
export EMCC_CFLAGS="-g $EMCC_CFLAGS -sVERBOSE=1 -sMALLOC=$EM_MALLOC"
|
export EMCC_CFLAGS="-g -sASSERTIONS=1 -sVERBOSE=1 $EMCC_CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
function clean {
|
function clean {
|
||||||
|
|||||||
@ -1052,6 +1052,13 @@ pub extern "C" fn render_shape_pixels(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn render_stats() {
|
||||||
|
with_state!(state, {
|
||||||
|
state.render_state.print_stats();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
init_gl!();
|
init_gl!();
|
||||||
|
|||||||
@ -15,6 +15,7 @@ mod ui;
|
|||||||
|
|
||||||
use skia_safe::{self as skia, Matrix, RRect, Rect};
|
use skia_safe::{self as skia, Matrix, RRect, Rect};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use gpu_state::GpuState;
|
use gpu_state::GpuState;
|
||||||
@ -289,9 +290,47 @@ fn sort_z_index(tree: ShapesPoolRef, element: &Shape, children_ids: Vec<Uuid>) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RenderStats {
|
||||||
|
pub counts: HashMap<Uuid, i32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
impl RenderStats {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
counts: HashMap::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count(&mut self, id: Uuid) -> i32 {
|
||||||
|
let counter = self.counts.entry(id).or_insert(0);
|
||||||
|
*counter += 1;
|
||||||
|
*counter
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear(&mut self) {
|
||||||
|
self.counts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn get(&self, id: &Uuid) -> Option<&i32> {
|
||||||
|
self.counts.get(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(&self) {
|
||||||
|
let mut sum: i32 = 0;
|
||||||
|
for (&id, &count) in self.counts.iter() {
|
||||||
|
println!("{}: {}", id, count);
|
||||||
|
sum += count;
|
||||||
|
}
|
||||||
|
println!("{}: {}", self.counts.len(), sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) struct RenderState {
|
pub(crate) struct RenderState {
|
||||||
gpu_state: GpuState,
|
gpu_state: GpuState,
|
||||||
pub options: RenderOptions,
|
pub options: RenderOptions,
|
||||||
|
stats: RenderStats,
|
||||||
pub surfaces: Surfaces,
|
pub surfaces: Surfaces,
|
||||||
pub fonts: FontStore,
|
pub fonts: FontStore,
|
||||||
pub viewbox: Viewbox,
|
pub viewbox: Viewbox,
|
||||||
@ -388,6 +427,7 @@ impl RenderState {
|
|||||||
Ok(RenderState {
|
Ok(RenderState {
|
||||||
gpu_state: gpu_state.clone(),
|
gpu_state: gpu_state.clone(),
|
||||||
options,
|
options,
|
||||||
|
stats: RenderStats::new(),
|
||||||
surfaces,
|
surfaces,
|
||||||
fonts,
|
fonts,
|
||||||
viewbox,
|
viewbox,
|
||||||
@ -876,6 +916,9 @@ impl RenderState {
|
|||||||
outset: Option<f32>,
|
outset: Option<f32>,
|
||||||
target_surface: SurfaceId,
|
target_surface: SurfaceId,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
#[cfg(feature = "stats")]
|
||||||
|
self.stats.count(shape.id);
|
||||||
|
|
||||||
let surface_ids = fills_surface_id as u32
|
let surface_ids = fills_surface_id as u32
|
||||||
| strokes_surface_id as u32
|
| strokes_surface_id as u32
|
||||||
| innershadows_surface_id as u32
|
| innershadows_surface_id as u32
|
||||||
@ -1690,6 +1733,9 @@ impl RenderState {
|
|||||||
timestamp: i32,
|
timestamp: i32,
|
||||||
sync_render: bool,
|
sync_render: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
#[cfg(feature = "stats")]
|
||||||
|
self.stats.clear();
|
||||||
|
|
||||||
let _start = performance::begin_timed_log!("start_render_loop");
|
let _start = performance::begin_timed_log!("start_render_loop");
|
||||||
let scale = self.get_scale();
|
let scale = self.get_scale();
|
||||||
|
|
||||||
@ -3443,6 +3489,10 @@ impl RenderState {
|
|||||||
pub fn set_view(&mut self, zoom: f32, x: f32, y: f32) {
|
pub fn set_view(&mut self, zoom: f32, x: f32, y: f32) {
|
||||||
self.viewbox.set_all(zoom, x, y);
|
self.viewbox.set_all(zoom, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_stats(&self) {
|
||||||
|
self.stats.print();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for RenderState {
|
impl Drop for RenderState {
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use skia_safe::gpu::{self, gl::FramebufferInfo, gl::TextureInfo, DirectContext};
|
use skia_safe::gpu::{
|
||||||
|
self, ganesh::context_options::Enable, gl::FramebufferInfo, gl::TextureInfo, ContextOptions,
|
||||||
|
DirectContext,
|
||||||
|
};
|
||||||
use skia_safe::{self as skia, ISize};
|
use skia_safe::{self as skia, ISize};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -13,7 +16,16 @@ impl GpuState {
|
|||||||
let interface = gpu::gl::Interface::new_native().ok_or(Error::CriticalError(
|
let interface = gpu::gl::Interface::new_native().ok_or(Error::CriticalError(
|
||||||
"Failed to create GL interface".to_string(),
|
"Failed to create GL interface".to_string(),
|
||||||
))?;
|
))?;
|
||||||
let context = gpu::direct_contexts::make_gl(interface, None).ok_or(
|
|
||||||
|
// We tweak some options to enhance performance.
|
||||||
|
let mut context_options = ContextOptions::default();
|
||||||
|
// context_options.reduce_ops_task_splitting = Enable::Yes;
|
||||||
|
context_options.skip_gl_error_checks = Enable::Yes;
|
||||||
|
// context_options.runtime_program_cache_size = 1024;
|
||||||
|
// context_options.allow_multiple_glyph_cache_textures = Enable::Yes;
|
||||||
|
// context_options.allow_path_mask_caching = false;
|
||||||
|
|
||||||
|
let context = gpu::direct_contexts::make_gl(interface, Some(&context_options)).ok_or(
|
||||||
Error::CriticalError("Failed to create GL context".to_string()),
|
Error::CriticalError("Failed to create GL context".to_string()),
|
||||||
)?;
|
)?;
|
||||||
let framebuffer_info = {
|
let framebuffer_info = {
|
||||||
|
|||||||
@ -231,8 +231,8 @@ fn draw_stroke_on_path(
|
|||||||
if let Some(pt) = path_transform {
|
if let Some(pt) = path_transform {
|
||||||
canvas.concat(pt);
|
canvas.concat(pt);
|
||||||
}
|
}
|
||||||
let skia_path = path.to_skia_path(svg_attrs);
|
|
||||||
|
|
||||||
|
let skia_path = path.to_skia_path(svg_attrs);
|
||||||
match stroke.render_kind(is_open) {
|
match stroke.render_kind(is_open) {
|
||||||
StrokeKind::Inner => {
|
StrokeKind::Inner => {
|
||||||
draw_inner_stroke_path(canvas, &skia_path, &draw_paint, blur, antialias);
|
draw_inner_stroke_path(canvas, &skia_path, &draw_paint, blur, antialias);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use skia_safe::{self as skia, Matrix};
|
|
||||||
|
|
||||||
use crate::math;
|
use crate::math;
|
||||||
use crate::shapes::svg_attrs::{FillRule, SvgAttrs};
|
use crate::shapes::svg_attrs::{FillRule, SvgAttrs};
|
||||||
|
use skia_safe::{self as skia, Matrix};
|
||||||
|
|
||||||
mod subpaths;
|
mod subpaths;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user