0d1b0eae4c
- 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.
2.8 KiB
2.8 KiB
Double-Buffering Plan: Çizim Bitimindeki Takılmayı Giderme — TAMAMLANDI (Katman 1+2+3)
Yapılan Değişiklikler
1. Engine Struct Güncellendi (lib.rs)
stroke_before: Option<(u64, Vec<u8>, ...)>→stroke_before: Option<(u64, Option<Vec<VectorShape>>)>- Yeni:
stroke_before_buf: Option<Vec<u8>>— havuzlu before buffer
2. SendPtr Wrapper Eklendi (stroke_cache.rs)
*const u8yerineusizekullanarakSendtrait'ini çözdük- Background thread'e raw pointer güvenli bir şekilde gönderiliyor
3. PendingHistoryItem Güncellendi (stroke_cache.rs)
return_before: Option<Vec<u8>>— background thread'den buffer geri dönüşü
4. begin_stroke() Güncellendi (stroke_cache.rs)
layer.pixels.clone()→copy_from_sliceile havuzlu buffer'a kopyalama- İlk stroke'ta ~33MB alloc, sonraki stroke'larda sadece copy
5. end_stroke() Güncellendi (stroke_cache.rs) — Katman 3
- Before buffer: havuzlu buffer'dan take (sıfır alloc)
- After buffer: sıfır kopya —
SendPtrile raw pointer background thread'e gönderiliyor - Background thread
unsafe { slice::from_raw_parts(...) }ile okuyor
6. commit_pending_history() Güncellendi (stroke_cache.rs)
- Return edilen before buffer'ı havuza geri koyar
7. stroke_brush.rs Güncellendi
stroke_before.as_ref().map(|(_, px, _)| px.as_slice())→stroke_before_buf.as_deref()
Performans Etkisi
| Metrik | Önce | Sonra (Katman 1+2+3) |
|---|---|---|
| begin_stroke alloc | ~33MB (her stroke) | İlk stroke'ta ~33MB, sonrasında 0 alloc |
| end_stroke alloc | ~33MB (her stroke) | Sıfır (pointer paylaşımı) |
| end_stroke kopya | ~33MB | Sıfır (zero-copy after snapshot) |
| Toplam alloc/stroke | ~66MB | ~33MB (sadece before) |
Katman 3 Kazanımı: end_stroke()'daki ~33MB alloc+copy tamamen ortadan kalktı.
Teknik Çözüm: SendPtr
Rust'ta *const u8 Send trait'ini implement etmiyor. Çözüm:
struct SendPtr(usize); // usize her zaman Send
impl SendPtr {
fn new(p: *const u8) -> Self { Self(p as usize) }
fn as_ptr(&self) -> *const u8 { self.0 as *const u8 }
}
unsafe impl Send for SendPtr {}
Test Sonuçları
- ✅
bitmap_brush_stamp_shape— başarılı - ✅
visual_regression(8 test) — başarılı - ✅
performance_stroke_4k— başarılı (1.95s toplam) - ✅ GUI derlemesi — başarılı
Dosya Değişiklikleri
| Dosya | Değişiklik |
|---|---|
hcie-engine-api/src/lib.rs |
Engine struct + init + docstring |
hcie-engine-api/src/stroke_cache.rs |
SendPtr + begin_stroke + end_stroke + commit_pending_history |
hcie-engine-api/src/stroke_brush.rs |
stroke_before referansı güncellendi |
docs/compose/specs/snapshot-freeze-analysis.md |
Bulgular dosyası (yeni) |