mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
WIP
This commit is contained in:
parent
e3981a0cf3
commit
928fdd8bae
@ -135,6 +135,14 @@
|
||||
(wasm.mem/free)
|
||||
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
|
||||
"Logs the current render-wasm atlas as an image in the JS console (if present)."
|
||||
[]
|
||||
|
||||
@ -1035,6 +1035,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() {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
init_gl!();
|
||||
|
||||
@ -16,6 +16,7 @@ mod ui;
|
||||
use skia_safe::{self as skia, Matrix, RRect, Rect};
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use gpu_state::GpuState;
|
||||
|
||||
@ -289,9 +290,46 @@ fn sort_z_index(tree: ShapesPoolRef, element: &Shape, children_ids: Vec<Uuid>) -
|
||||
}
|
||||
}
|
||||
|
||||
struct RenderStats {
|
||||
pub counts: HashMap<Uuid, i32>,
|
||||
}
|
||||
|
||||
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 {
|
||||
gpu_state: GpuState,
|
||||
pub options: RenderOptions,
|
||||
stats: RenderStats,
|
||||
pub surfaces: Surfaces,
|
||||
pub fonts: FontStore,
|
||||
pub viewbox: Viewbox,
|
||||
@ -377,6 +415,7 @@ impl RenderState {
|
||||
Ok(RenderState {
|
||||
gpu_state: gpu_state.clone(),
|
||||
options,
|
||||
stats: RenderStats::new(),
|
||||
surfaces,
|
||||
fonts,
|
||||
viewbox,
|
||||
@ -851,6 +890,8 @@ impl RenderState {
|
||||
outset: Option<f32>,
|
||||
target_surface: SurfaceId,
|
||||
) -> Result<()> {
|
||||
self.stats.count(shape.id);
|
||||
|
||||
let surface_ids = fills_surface_id as u32
|
||||
| strokes_surface_id as u32
|
||||
| innershadows_surface_id as u32
|
||||
@ -1662,6 +1703,7 @@ impl RenderState {
|
||||
timestamp: i32,
|
||||
sync_render: bool,
|
||||
) -> Result<()> {
|
||||
self.stats.clear();
|
||||
let _start = performance::begin_timed_log!("start_render_loop");
|
||||
let scale = self.get_scale();
|
||||
|
||||
@ -3338,6 +3380,10 @@ impl RenderState {
|
||||
pub fn set_view(&mut self, zoom: f32, x: f32, y: f32) {
|
||||
self.viewbox.set_all(zoom, x, y);
|
||||
}
|
||||
|
||||
pub fn print_stats(&self) {
|
||||
self.stats.print();
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RenderState {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
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, DirectContext, ContextOptions};
|
||||
use skia_safe::{self as skia, ISize};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -13,7 +13,18 @@ impl GpuState {
|
||||
let interface = gpu::gl::Interface::new_native().ok_or(Error::CriticalError(
|
||||
"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();
|
||||
println!("context_options {:?}", context_options);
|
||||
// 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;
|
||||
println!("context_options {:?}", context_options);
|
||||
|
||||
let context = gpu::direct_contexts::make_gl(interface, Some(&context_options)).ok_or(
|
||||
Error::CriticalError("Failed to create GL context".to_string()),
|
||||
)?;
|
||||
let framebuffer_info = {
|
||||
|
||||
@ -7,7 +7,7 @@ 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 VIEWPORT_INTEREST_AREA_THRESHOLD: i32 = 1;
|
||||
const MAX_BLOCKING_TIME_MS: i32 = 32;
|
||||
const NODE_BATCH_THRESHOLD: i32 = 3;
|
||||
const BLUR_DOWNSCALE_THRESHOLD: f32 = 8.0;
|
||||
|
||||
@ -10,6 +10,9 @@ use crate::error::{Error, Result};
|
||||
use crate::render::filters::compose_filters;
|
||||
use crate::render::{get_dest_rect, get_source_rect};
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use crate::run_script;
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn draw_stroke_on_rect(
|
||||
canvas: &skia::Canvas,
|
||||
@ -229,21 +232,21 @@ fn draw_stroke_on_path(
|
||||
if let Some(pt) = path_transform {
|
||||
canvas.concat(pt);
|
||||
}
|
||||
let skia_path = path.to_skia_path();
|
||||
|
||||
let skia_path = path.to_skia_path();
|
||||
match stroke.render_kind(is_open) {
|
||||
StrokeKind::Inner => {
|
||||
draw_inner_stroke_path(canvas, &skia_path, &draw_paint, blur, antialias);
|
||||
draw_inner_stroke_path(canvas, skia_path, &draw_paint, blur, antialias);
|
||||
}
|
||||
StrokeKind::Center => {
|
||||
canvas.draw_path(&skia_path, &draw_paint);
|
||||
canvas.draw_path(skia_path, &draw_paint);
|
||||
}
|
||||
StrokeKind::Outer => {
|
||||
draw_outer_stroke_path(canvas, &skia_path, &draw_paint, blur, antialias);
|
||||
draw_outer_stroke_path(canvas, skia_path, &draw_paint, blur, antialias);
|
||||
}
|
||||
}
|
||||
|
||||
handle_stroke_caps(&skia_path, stroke, canvas, is_open, paint, blur, antialias);
|
||||
handle_stroke_caps(skia_path, stroke, canvas, is_open, paint, blur, antialias);
|
||||
|
||||
canvas.restore_to_count(save_count);
|
||||
}
|
||||
|
||||
@ -463,6 +463,7 @@ impl Surfaces {
|
||||
}
|
||||
|
||||
pub fn flush_and_submit(&mut self, gpu_state: &mut GpuState, id: SurfaceId) {
|
||||
println!("flush_and_submit");
|
||||
let surface = self.get_mut(id);
|
||||
gpu_state.context.flush_and_submit_surface(surface, None);
|
||||
}
|
||||
|
||||
@ -2,6 +2,9 @@ use skia_safe::{self as skia};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use crate::run_script;
|
||||
|
||||
use crate::uuid::Uuid;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{OnceCell, RefCell};
|
||||
@ -1349,7 +1352,7 @@ impl Shape {
|
||||
|
||||
pub fn get_skia_path(&self) -> Option<skia::Path> {
|
||||
if let Some(path) = self.shape_type.path() {
|
||||
let mut skia_path = path.to_skia_path();
|
||||
let mut skia_path = path.to_skia_path().clone();
|
||||
if let Some(path_transform) = self.to_path_transform() {
|
||||
skia_path = skia_path.make_transform(&path_transform);
|
||||
}
|
||||
@ -1392,6 +1395,8 @@ impl Shape {
|
||||
|
||||
if let shape_type @ (Type::Path(_) | Type::Bool(_)) = &mut self.shape_type {
|
||||
if let Some(path) = shape_type.path_mut() {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
run_script!("console.count('path.transform')");
|
||||
path.transform(transform);
|
||||
}
|
||||
} else if let Type::Text(text) = &mut self.shape_type {
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
use skia_safe::{self as skia, Matrix};
|
||||
|
||||
use std::{ops::Deref, rc::Rc};
|
||||
use skia_safe::{self as skia, Matrix, wrapper::ValueWrapper};
|
||||
use crate::math;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use crate::run_script;
|
||||
|
||||
mod subpaths;
|
||||
|
||||
type Point = (f32, f32);
|
||||
@ -19,7 +22,7 @@ impl Segment {}
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct Path {
|
||||
segments: Vec<Segment>,
|
||||
skia_path: skia::Path,
|
||||
pub skia_path: skia::Path,
|
||||
open: bool,
|
||||
}
|
||||
|
||||
@ -217,8 +220,8 @@ impl Path {
|
||||
Path::new(segments)
|
||||
}
|
||||
|
||||
pub fn to_skia_path(&self) -> skia::Path {
|
||||
self.skia_path.snapshot()
|
||||
pub fn to_skia_path(&self) -> &skia::Path {
|
||||
&self.skia_path
|
||||
}
|
||||
|
||||
pub fn contains(&self, p: skia::Point) -> bool {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user