perf: Veraltete PDF-Render-Aufträge beim Scrollen verwerfen (Issue #28)

Beim schnellen Scrollen durch ein großes PDF hat der Render-Thread jede
vorbeigezogene Seite der Reihe nach gerendert; die gerade sichtbare
Seite musste warten.

- Gemeinsame Warteschlange (Mutex + Condvar) statt Kanal: Der
  Render-Thread nimmt den wichtigsten wartenden Auftrag zuerst.
- Je Bild meldet der Event-Loop zwischen begin_frame und end_frame die
  benötigten Seiten an (die aktuelle zuerst); end_frame verwirft
  wartende Aufträge und fertige Ergebnisse für Seiten, die nicht mehr
  gebraucht werden. Die vorab gerenderte nächste Seite bleibt erhalten.

Gemessen (Xvfb, Debug-Build, PDF mit 60 Seiten, 400 Mausrad-Schritte):
die letzte Seite erscheint nach 0,12–0,16 s statt 0,63–1,56 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haraldandClaude Opus 5.5 committed 2026-10-12 22:48:31 +02:00
1 parent f24e7750e6
commit ade20ab3dc
2 files changed
+228 -23

No files matched your search

+4
View File
@@ -3920,6 +3920,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
canvas.set_neighbor_pages(&[]);
}
let assets = AssetStore::new(&storage_dir);
// PDF-Seiten, die nach diesem Bild nicht mehr gebraucht werden (schnelles
// Scrollen), verwirft end_frame, bevor sie gerendert werden
pdf_renderer.begin_frame();
canvas.prepare_images(&mut |key| texture_for(key, &assets, &mut pdf_renderer));
// Nächste PDF-Seite vorab rendern, damit Blättern sofort klappt
if !canvas.is_waiting_for_images() {
@@ -3930,6 +3933,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
}
pdf_renderer.end_frame();
match canvas.render(&clipped_primitives, &screen_descriptor, &full_output.textures_delta) {
Ok(_) => {}
Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => {