Files
hcie-rust-v3.05/.mimocode/plans/1783648258317-kind-wolf.md
T
phantom 0d1b0eae4c 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.
2026-07-11 08:53:17 +03:00

3.2 KiB

Brush Stroke End Freeze Fix + Cursor Preview Fix

Issue 1: Stroke End Freeze (Partially Fixed)

Current State

  • During drawing: canvas updates correctly (synchronous composite)
  • After stroke end: still freezes due to create_composite_snapshot() being expensive

Root Cause

create_composite_snapshot() in partial_composite.rs:354 clones ALL layers (33MB per layer on 4K) and ALL tile layers. For a 10-layer 4K document, this is ~330MB of cloning on the UI thread.

Fix: Skip background composite for brush strokes, use synchronous composite

File: hcie-egui-app/crates/hcie-gui-egui/src/canvas/render.rs

In render_composition(), the after-stroke-end path currently spawns a background thread. Instead:

  • Do the synchronous composite directly (like during drawing)
  • Only use background thread for very expensive operations (filters, fills)
  • This eliminates the freeze for brush strokes
// After stroke end: do synchronous composite (not background)
// Background thread is too expensive due to create_composite_snapshot()
let (region, buf_ptr, buf_size) = doc.engine.render_composite_region();
// ... upload to texture ...
doc.engine.clear_dirty_flags();

Issue 2: Brush Cursor Preview Shows Wrong Shape

Current State

  • ABR (bitmap) brushes: correct preview
  • Procedural brushes (Round, Square, Star, etc.): shows as small circle
  • After using ABR brush: preview gets stuck on ABR shape

Root Cause

The brushes_panel.rs changes (from other AI) added active_brush_preset_id sync that overrides the brush style. When a procedural style cell is clicked:

  1. state.tool_configs.brush.style is set correctly
  2. But then active_brush_preset_id is synced to a preset matching that style
  3. If no matching preset exists, or if the preset has a different style, the preview gets confused

Fix: Remove the active_brush_preset_id sync

File: hcie-egui-app/crates/hcie-gui-egui/src/app/tools/brushes_panel.rs

Remove the 7-line block that was added:

// Sync active_brush_preset_id to a preset matching this style
// so the cursor preview shows the correct brush tip.
if let Some(matching) = state.brush_presets.iter().find(|p| {
    to_tools_style(map_brush_style(p.tip.style)) == style
}) {
    state.active_brush_preset_id = matching.id.clone();
}

The cursor preview already uses state.tool_configs.brush.style directly, not the preset. This sync is unnecessary and causes the preview to get stuck.

Files to Modify

File Change
hcie-egui-app/crates/hcie-gui-egui/src/canvas/render.rs Use synchronous composite after stroke end
hcie-egui-app/crates/hcie-gui-egui/src/app/tools/brushes_panel.rs Remove active_brush_preset_id sync

Verification

  1. Stroke freeze test: Draw rapid brush strokes — no visible freeze on stroke end
  2. Cursor preview test: Switch between procedural brushes (Round, Square, Star) — preview should show correct shape
  3. ABR transition test: Use ABR brush, then switch to procedural — preview should update correctly
  4. Visual regression: cargo test -p hcie-engine-api --test visual_regression
  5. Performance test: cargo test -p hcie-engine-api --test performance_stroke_4k -- --nocapture