Render visible pages before thumbnails and text extraction (#950)
* Linux: the tab strip carries the window controls, as in Acrobat On X11 and Wayland the window manager drew its own title bar above the tab strip, so every PdfCraft window had two bars and the controls the user clicked were the window manager's, not ours. `ViewportBuilder::with_decorations(false)` turns the frame off, and `chrome::window_frame` draws minimize, maximize and close at the top right of the tab strip, plus a hairline border and resizing from the edges and corners, so a frameless window behaves like a framed one. Close still goes through the unsaved-changes check, and full screen and the in-app full-screen page view draw no controls over the page. Drawing it last keeps the controls reachable from every overlay that covers the tab strip. `PDFCRAFT_SYSTEM_TITLEBAR=1` puts the window manager's frame back for anyone who wants it. * Render visible pages before thumbnails and text extraction Opening a document queued its visible page pixels together with Pages-panel thumbnails and background text extraction, so the render workers spent the first seconds on background work while the visible page stayed blank. Hold thumbnails and text until no visible main-page raster is still missing; errored pages never block. * Render visible pages before thumbnails and text extraction Opening a document queued its visible page pixels together with Pages-panel thumbnails and background text extraction, so the render workers spent the first seconds on background work while the visible page stayed blank. Hold thumbnails and text until no visible main-page raster is still missing; errored pages never block. --------- Co-authored-by: GyuriX <gyurix@users.noreply.github.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
parent
8983f05c78
commit
9564ed6885
|
|
@ -1348,6 +1348,21 @@ impl DocView {
|
|||
// bounded few under a page whose current tiles are still missing (OLD_TILES).
|
||||
self.tiles.retain(|key, _| tiles.contains(key) || !tile_tags.contains(&key.1));
|
||||
queue.extend(grid);
|
||||
// Opening (or turning to) a page queues its pixels alongside thumbnails and
|
||||
// text extraction. The workers would otherwise spend the first seconds on
|
||||
// thumbnails and search text while the visible page stays blank: hold those
|
||||
// until no visible main-page raster is still missing. Errored pages never
|
||||
// block: they are never re-requested.
|
||||
let visible_mains_pending = queue.iter().any(|r| {
|
||||
r.kind == RequestKind::Pixels
|
||||
&& r.tag & (GRID_TAG | PRINT_TAG | THUMB_TAG | TEXT_TAG) == 0
|
||||
&& self.frame_visible.contains(&r.page)
|
||||
&& !self.errors.contains_key(&r.page)
|
||||
});
|
||||
if visible_mains_pending {
|
||||
// Caches are kept; demand is re-evaluated next frame once pixels arrive.
|
||||
return queue;
|
||||
}
|
||||
let thumbs = self.thumbnail_requests(info, ppp);
|
||||
let mut thumb_bytes = 0usize;
|
||||
let mut admitted = HashSet::new();
|
||||
|
|
@ -4192,6 +4207,48 @@ trailer << /Root 1 0 R >>
|
|||
assert!(v.prepare_render_queue(&info, 1.0).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn visible_pages_render_before_thumbnails_and_text() {
|
||||
let ctx = egui::Context::default();
|
||||
let info = thumbnail_info(4);
|
||||
let mut v = DocView::new(DocId(1), &info, ViewDefaults::default());
|
||||
let main = RenderRequest { page: 0, scale: 1.0, tag: 1000, ..Default::default() };
|
||||
let text = RenderRequest { page: 0, kind: RequestKind::Text, scale: 1.0, tag: TEXT_TAG, ..Default::default() };
|
||||
// Opening page 0 queues its pixels and text alongside Pages-panel thumbnails.
|
||||
v.begin_render_frame();
|
||||
v.frame_visible = [0].into();
|
||||
v.frame_queue = vec![main, text];
|
||||
for p in 1..4 {
|
||||
v.need_thumbnail(p, true);
|
||||
}
|
||||
let queue = v.prepare_render_queue(&info, 1.0);
|
||||
assert_eq!(queue, vec![main], "visible pixels first: no thumbnails or text yet");
|
||||
// Once the visible raster arrives, background work is admitted.
|
||||
v.last_queue = queue;
|
||||
assert!(v.receive_result(&ctx, solid_result(main, 100, 130)) > 0);
|
||||
v.begin_render_frame();
|
||||
v.frame_visible = [0].into();
|
||||
v.frame_queue = vec![text];
|
||||
for p in 1..4 {
|
||||
v.need_thumbnail(p, true);
|
||||
}
|
||||
let queue = v.prepare_render_queue(&info, 1.0);
|
||||
assert!(queue.iter().any(|r| r.kind == RequestKind::Text), "text admitted after pixels");
|
||||
assert!(queue.iter().any(|r| r.tag & THUMB_TAG != 0), "thumbnails admitted after pixels");
|
||||
assert!(!queue.iter().any(|r| r.kind == RequestKind::Pixels && r.tag & THUMB_TAG == 0), "no main pixels re-requested");
|
||||
// An errored visible page never holds background work back.
|
||||
v.errors.insert(0, "gone".to_string());
|
||||
v.begin_render_frame();
|
||||
v.frame_visible = [0].into();
|
||||
v.frame_queue = vec![main, text];
|
||||
for p in 1..4 {
|
||||
v.need_thumbnail(p, true);
|
||||
}
|
||||
let queue = v.prepare_render_queue(&info, 1.0);
|
||||
assert!(queue.iter().any(|r| r.kind == RequestKind::Text), "text admitted despite the error");
|
||||
assert!(queue.iter().any(|r| r.tag & THUMB_TAG != 0), "thumbnails still admitted");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thumbnail_tags_do_not_change_as_a_row_scrolls_in_or_out() {
|
||||
let info = thumbnail_info(10_000);
|
||||
|
|
|
|||
Loading…
Reference in New Issue