fix: optimize brush stroke handling and improve cursor preview

- Changed default VISION_BACKEND from CPU to GPU for better performance.
- Made `map_brush_style` public to allow external access.
- Updated `Engine` struct to use pooled buffers for stroke snapshots, reducing memory allocations during brush strokes.
- Introduced `CompositeSnapshot` for efficient background compositing without blocking the UI thread.
- Implemented `SendPtr` for safe raw pointer handling across threads.
- Enhanced `commit_pending_history` to recycle buffers and improve performance.
- Fixed cursor preview issues for procedural brushes by removing unnecessary preset synchronization.
- Added tests and documentation for new features and performance improvements.
This commit is contained in:
2026-07-11 08:53:17 +03:00
parent 089ce00b49
commit 0d1b0eae4c
14 changed files with 1021 additions and 305 deletions
+11 -6
View File
@@ -1905,7 +1905,10 @@ pub fn draw_stipple_brush(
) {
let mut rng = rand::thread_rng();
let effective_size = size * pressure;
let spread = effective_size * 2.2;
// Spread controls how far particles scatter from the center.
// Previous value (2.2×) caused the brush to paint ~4.4× the nominal
// diameter. 0.65× keeps the footprint close to the user-specified size.
let spread = effective_size * 0.65;
let particle_opacity = opacity * pressure;
let count = (effective_size / 4.0).max(3.0) as u32;
@@ -1914,16 +1917,18 @@ pub fn draw_stipple_brush(
let theta = rng.gen::<f32>() * std::f32::consts::PI * 2.0;
let px = cx + r * theta.cos();
let py = cy + r * theta.sin();
let star_size = rng.gen_range(3.0..(effective_size * 0.22).max(4.0));
// Smaller star particles to match the tighter spread.
let star_size = rng.gen_range(2.0..(effective_size * 0.15).max(3.0));
// A. Small soft center core
draw_dab(pixels, width, height, px, py, star_size * 0.35, hardness, color, particle_opacity, is_eraser, mask);
// B. Long, tapering arm dabs stretching out along X and Y axes
for i in 1..=4 {
let arm_dist = star_size * 0.45 * i as f32;
let arm_size = star_size * 0.30 * (1.0 - (i as f32 / 5.5)); // Tapering diameter
let arm_op = particle_opacity * (1.0 - (i as f32 / 6.0)); // Concentric opacity decay
// Arm distance scaled down to keep the star within the spread radius.
for i in 1..=3 {
let arm_dist = star_size * 0.35 * i as f32;
let arm_size = star_size * 0.25 * (1.0 - (i as f32 / 4.5)); // Tapering diameter
let arm_op = particle_opacity * (1.0 - (i as f32 / 5.0)); // Concentric opacity decay
draw_dab(pixels, width, height, px + arm_dist, py, arm_size, hardness, color, arm_op, is_eraser, mask);
draw_dab(pixels, width, height, px - arm_dist, py, arm_size, hardness, color, arm_op, is_eraser, mask);