Files
imajviewer/docs/performance_llvmpipe_issue.md

72 lines
3.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Performans: llvmpipe (Yazılımsal Render) Altında Efekt Donmaları
Tarih: 2026-08-03
Durum: Uygulandı (ölçüm sonuçları bölüm 3'te)
## 1. Teşhis
- VM'de donanım GPU'su yok: `glxinfo -B``Device: llvmpipe (LLVM 21.1.8, 128 bits)`,
`/dev/dri` yok. Tüm çizim 4 CPU çekirdeğinde LLVM ile yapılıyor.
- Efekt sürüklemesi (contrast/saturation/brightness/rotate): her `PointerMoveEvent`
doğrudan `setState` → tüm görsel katman `ColorFiltered` ile yeniden boyanıyor.
- Fare sürüklemesinde olay hızı 100-250+/sn; llvmpipe kare süresi 20-100ms+.
Üretim > tüketim → kuyruk birikmesi → UI thread %100 → donma. Kuyruk boşalınca
arayüz yakalıyor ("1 dk sonra normale döndü").
- Rotate'in önce kilitlenmesi normal: `Transform` ikinci bir composite geçişi ekliyor.
Contrast aynı duvara galeri akışıyla (daha büyük görseller, dolu ImageCache) çarptı.
## 2. Uygulanan Değişiklikler
### Render izolasyonu ve kare hızı eşitleme — `lib/widgets/image_canvas.dart`
- Pointer move / scroll / pan / efekt işleyicilerinden `setState` kaldırıldı.
- `ValueNotifier<int> _renderTick` + `ValueListenableBuilder` — görsel katman yalnızca
tick ile yeniden kurulur.
- `SchedulerBinding.instance.scheduleFrameCallback` — saniyede en fazla 1 rebuild/kare
(ekran yenileme hızıyla sınırlı); olaylar kareye eşitlenir, kuyruk birikmez.
- `RepaintBoundary` — efekt repaint'i pencere/title bar/üst widget render'ını etkilemez.
- Not: per-efekt `ValueNotifier` yerine tek tick notifier kullanıldı. Nedeni:
`ValueListenableBuilder` her değer değişiminde yeniden kurulur (olay hızında kalır);
throttling için tek noktadan kare başına tick gerekli.
### Image pipeline — `lib/widgets/image_canvas.dart` + `lib/services/image_manager.dart`
- `ResizeImage.resizeIfNeeded(cacheWidth: viewport×2)` — yüksek çözünürlüklü görseller
görüntüleme boyutunun ~2 katıyla sınırlı decode edilir: decode süresi, bellek ve
llvmpipe CPU yükü düşer. (Zoom 2x'e kadar net; ötesi canlı önizleme için kabul edilen takas.)
- `configureCache`: 1000 görsel / 1GB → **16 görsel / 256MB**.
- Galeri/klasör geçişinde `imageCache.clear()` — canlı (gösterilen) görsel korunur,
eski klasörün decode edilmiş `ui.Image` nesneleri bellekten düşer.
## 3. Ölçüm (llvmpipe)
Ölçüm yöntemi: 4000×3000 PNG açıldı; kullanıcı elle contrast / saturation /
brightness sürüklemeleri yaptı. Kare süreleri `addTimingsCallback` ile (geçici
enstrümantasyon, sonra kaldırıldı), CPU `pidstat` ile örneklendi.
| Metrik | Değer |
|---|---|
| Kare sayısı (contrast turu) | 76 |
| build ort / max | 3.9 ms / 78 ms |
| raster ort / max | 15.1 ms / 52 ms |
| Kare sayısı (sat/brightness turu) | 133 |
| build ort / max | 3.0 ms / 82 ms |
| raster ort / max | 14.1 ms / 48 ms |
| CPU — boştayken | %0-14 |
| CPU — aktif sürüklemede | %100-163 (1-1.6 çekirdek) |
Değerlendirme: raster ort. ~14-15 ms (16.7 ms kare bütçesinin altında), sürükleme
sırasında maksimum ~50 ms → ara sıra kare atlanır ama **kuyruk birikmesi ve
dakikalarca süren donma yok**. CPU 4 çekirdeğin tamamını asla doyurmuyor
(önceki durumda sürükleme anında tam doygunluk + 1 dk donma vardı).
## 4. VM Sistem Gereksinimleri (öneri — uygulama dışı)
llvmpipe tamamen yazılımsal; kalıcı çözüm VM tarafında donanım hızlandırmasıdır:
- **virtio-gpu + VirGL**: QEMU/libvirt'ta `-device virtio-vga-gl` / `virtio-gpu-gl`
(mesa'nın VirGL yoluyla hızlandırılmış GL'si). `/dev/dri` görünür hale gelir.
- **PCIe Passthrough**: gerçek GPU'yı VM'e bağlama (en yüksek performans, donanım gerektirir).
- Bu olmadan uygulama yukarıdaki yazılımsal önlemlerle çalışır, ancak büyük görsellerde
efekt sürüklemesi yine de kare atlayabilir.