diff options
| author | Gabriel Schneider <[email protected]> | 2026-09-22 17:43:57 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-10-01 00:12:14 -0300 |
| commit | 9695cb098c784792af79c22d46a17f7bc7247d33 (patch) | |
| tree | fa446f3cb588b3184b7914b3f50c36cd3e5ece7b /build.zig | |
| parent | f962de52df4b3d33438150920ae95b8708b0dde0 (diff) | |
| download | pardes-9695cb098c784792af79c22d46a17f7bc7247d33.tar.gz pardes-9695cb098c784792af79c22d46a17f7bc7247d33.zip | |
Repaint PDF highlights by row, send rasters by shared memory, and animate messages
PDF highlights (hover preview, search, selection) are baked into page rasters,
and any change re-rendered the whole page with MuPDF; the TTY then re-sent it
as base64 (4.7 MB a page), the GUI as a new texture. Worse, a pointer motion
over a PDF invalidated the page even when no preview was shown, so every
motion paid that. Now:
- A raster whose baked highlight set equals the wanted one is left alone.
- A highlighted page keeps its clean rows (before highlights and tint); a
change repaints only the rows of quads that differ, running MuPDF's
highlight pass (pardes_pdf_paint_highlights) over those clean rows and
tinting them: the operations a full render performs, so the pixels are
identical. MuPDF band renders are NOT bit-identical to a whole page (edge
rows, resampled images), so they are never used to patch; the comment
claiming otherwise is corrected.
- ImagePlace.patch hands shells the changed rows; the GUI uploads just those
rows into the texture it holds.
- The TTY probes kitty shared memory (t=s) with an id vaxis never reaches and
sends rasters as a /dev/shm name when the terminal reads it; direct base64
otherwise (ssh).
- Shells that take row patches (GUI, TTY with shm) repaint a selection while
it is dragged instead of only on release.
Latency elsewhere:
- TTY: an animating frame no longer sleeps 16 ms blind; a tick thread posts
into the input queue, so input inside the frame is handled at once.
- TTY and GUI: queued pointer motions coalesce to the last.
- GUI: a skipped swapchain image re-arms the frame (3 retries); animations
still tick while nothing presents.
- Editing: the line index is carried across an edit instead of rebuilt from
a scan of the whole file per keystroke.
Messages fall into their row (ease-in; the GUI slides the band out from under
the tagline, a terminal fades it), stay until the next input as before, linger
MessageLinger ms (default 800), and dissolve (ease-out). MessageAnimation
toggles it; both are settings, in Config and startup files. The snapshot
harness pins the old behaviour. The detached server now ticks animations.
A restored terminal comes back live: the old screen and scrollback (dumped
as clean VT by ghostty's formatter, replayed at the new size; older dumps
fall back to their rendered text), a dim
"restored history" marker, then a new shell in the directory it was in.
Right-click on a line number in a file pane looks at that line (a sticky
context header's number included).
Measured with an external pty driver (TTY), an in-process fence trace
(GUI, PARDES_TEST_LATENCY), and test/pdf_pointer_bench.zig (pixel identity
against the baseline and a whole-page oracle); balanced A/A/B rounds, paired
per-round statistics.
Messages stack: each event gets its own row and its own fall, linger and
dissolve; a line keeps its row until it leaves and a new one fills the first
free row. Announcements and statuses are replaced in place, not stacked.
MessageFall, MessageDissolve and DumpDir are settings Config reports.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Diffstat (limited to 'build.zig')
| -rw-r--r-- | build.zig | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -142,6 +142,7 @@ pub fn build(b: *std.Build) void { const mupdf_check = b.step("mupdf-check", "compile, link, render, and search docs/design.pdf with MuPDF"); const pdf_bench_step = b.step("pdf-bench", "benchmark real MuPDF page rendering (-- [--json] [--reps N] [--warmup N] [--path FILE] [--page N] [--pages N])"); const pdf_sections_bench_step = b.step("pdf-sections-bench", "benchmark PDF outline/sections paths in ReleaseFast (-Doptimize=ReleaseFast -- [--json] [--reps N] [--warmup N])"); + const pdf_pointer_bench_step = b.step("pdf-pointer-bench", "time PDF hover and selection gestures and prove their pixels (-Doptimize=ReleaseFast -- [--label L] [--reps N] [--path FILE] [--cell WxH])"); const pdf_scroll_bench_step = b.step("pdf-scroll-bench", "benchmark fast continuous-strip PDF scrolling in ReleaseFast (-Doptimize=ReleaseFast -- [--json] [--reps N] [--warmup N] [--path FILE])"); if (!enable_mupdf) mupdf_check.dependOn(&b.addFail("mupdf-check is unavailable with -Dmupdf=false").step); @@ -151,6 +152,8 @@ pub fn build(b: *std.Build) void { pdf_sections_bench_step.dependOn(&b.addFail("pdf-sections-bench is unavailable with -Dmupdf=false").step); if (!enable_mupdf) pdf_scroll_bench_step.dependOn(&b.addFail("pdf-scroll-bench is unavailable with -Dmupdf=false").step); + if (!enable_mupdf) + pdf_pointer_bench_step.dependOn(&b.addFail("pdf-pointer-bench is unavailable with -Dmupdf=false").step); const shaders_step = b.step("shaders", "refresh paired shaders/prebuilt/*.spv + *.glsl snapshots (glslc)"); const update_shaders = b.addUpdateSourceFiles(); @@ -482,6 +485,22 @@ pub fn build(b: *std.Build) void { run_pdf_sections_bench.setCwd(b.path(".")); pdf_sections_bench_step.dependOn(&run_pdf_sections_bench.step); + const pdf_pointer_bench = b.addExecutable(.{ + .name = "pardes-pdf-pointer-bench", + .root_module = b.createModule(.{ + .target = target, + .optimize = .ReleaseFast, + .root_source_file = b.path("test/pdf_pointer_bench.zig"), + .link_libc = true, + }), + }); + pdf_pointer_bench.root_module.addImport("pardes", core_module); + pdf_pointer_bench.root_module.addImport("mupdf", mupdf_mod); + const run_pdf_pointer_bench = b.addRunArtifact(pdf_pointer_bench); + if (b.args) |args| run_pdf_pointer_bench.addArgs(args); + run_pdf_pointer_bench.setCwd(b.path(".")); + pdf_pointer_bench_step.dependOn(&run_pdf_pointer_bench.step); + const pdf_scroll_bench = b.addExecutable(.{ .name = "pardes-pdf-scroll-bench", .root_module = b.createModule(.{ |
