67 lines
2.8 KiB
Markdown
67 lines
2.8 KiB
Markdown
|
|
# 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 u8` yerine `usize` kullanarak `Send` trait'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_slice` ile 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** — `SendPtr` ile 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:
|
|||
|
|
```rust
|
|||
|
|
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) |
|