perf: Mipmaps importierter PDF-Seiten im Render-Thread (Issue #28)

Beim Scrollen durch große PDFs stockte die Anzeige bei jeder neu
gerenderten Seite: Der Haupt-Thread erzeugte die Mipmaps, bei 2560 px
etwa 100–200 ms, beim Hineinzoomen (5120 px) bis zu 1 s.

- Der PDF-Render-Thread liefert die fertigen Mipmap-Stufen mit; der
  Haupt-Thread lädt sie nur noch hoch (TextureSource::ReadyMips).
- mip_chain halbiert mit einem 2×2-Mittelwert statt imageops::resize:
  etwa 7-mal schneller (2560 px: ~15 ms statt ~100–200 ms).
- Belegter Grafikspeicher wird aus den tatsächlichen Stufen berechnet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haraldandClaude Opus 5.5 committed 2026-10-12 22:22:21 +02:00
1 parent 097933882c
commit f24e7750e6
3 files changed
+123 -51

No files matched your search

+14 -18
View File
@@ -941,25 +941,21 @@ fn texture_for(
assets: &AssetStore,
pdf_renderer: &mut PdfRenderService,
) -> TextureSource {
let result = match key.contains('#') {
true => {
let Some((Ok(path), page, max_pixels)) = ink_notes::pdf_doc::parse_page_key(key)
.map(|(asset, page, px)| (assets.path_of(asset), page, px))
else {
return TextureSource::Failed(t!("Ungültiger PDF-Verweis '{key}'", key = key));
};
match pdf_renderer.take(key, path, page, max_pixels) {
Some(result) => result,
None => return TextureSource::Pending,
}
}
false => assets
.load_rgba(key, ink_notes::assets::MAX_DISPLAY_DIMENSION)
.map_err(|e| e.to_string()),
if !key.contains('#') {
return match assets.load_rgba(key, ink_notes::assets::MAX_DISPLAY_DIMENSION) {
Ok(image) => TextureSource::Ready(image),
Err(err) => TextureSource::Failed(err.to_string()),
};
}
let Some((Ok(path), page, max_pixels)) = ink_notes::pdf_doc::parse_page_key(key)
.map(|(asset, page, px)| (assets.path_of(asset), page, px))
else {
return TextureSource::Failed(t!("Ungültiger PDF-Verweis '{key}'", key = key));
};
match result {
Ok(image) => TextureSource::Ready(image),
Err(err) => TextureSource::Failed(err),
match pdf_renderer.take(key, path, page, max_pixels) {
Some(Ok(levels)) => TextureSource::ReadyMips(levels),
Some(Err(err)) => TextureSource::Failed(err),
None => TextureSource::Pending,
}
}