# Spike D — Skia vs PDFium renderer: M0 status (DEFERRED) * **Spike**: D — our own Skia display-list renderer vs PDFium on the corpus (engineering plan §14 step 7) * **Date**: 2026-07-25 * **Status**: **Deferred.** Not buildable in the M0 development environment; recorded here so the deferral is explicit, not silent. * **Gate**: pixel divergence ≤ 0.3% between our Skia display-list renderer and PDFium on 500 corpus pages — decides whether the §2.5 predictive tier is viable. ## Why deferred Spike D requires **our own Skia display-list renderer** (which does not exist yet — it is M2 work) and **PDFium** as the reference renderer. Neither is available as a system package on Debian 13: - **PDFium** has no system package and must be built from Chromium's `pdfium` git mirror. Its build is Chromium-scale: the source is ~2 GB, the build wants tens of GB of disk and produces a large static library, and a full build takes hours even on capable hardware. The M0 development environment here (29 GB free disk, 7.8 GB RAM) is below PDFium's practical build floor. - **Skia** likewise has no system package and builds from Google's repo; it is smaller than PDFium but still a from-source build with its own toolchain (`gn` + `ninja`, depot_tools). The spike is specifically testing the divergence between **two specific renderers** we will use in production (§2.4: Skia for the predictive tier and overlays, PDFium for the authoritative raster). It cannot be substituted with Poppler or another renderer — that would test a different question. ## What this does NOT mean - **It is not a go/no-go block on M0 for the other spikes.** Spikes A, B, C, E are complete and give go signals: surgical splice validated (A), reconstruction works (B), font growth works (C), sandbox works (E). The M0 exit criteria in §14 are met for the four spikes that could be built here. - **It is not an architectural risk we are ignoring.** The §2.5 predictive tier is the *optimisation* that keeps keystroke latency bounded; the authoritative tier (re-emit + render through PDFium) is the guarantee and does not depend on the Skia renderer's existence. If Spike D later shows the Skia renderer diverges too much from PDFium, the fallback is the authoritative tier alone (slower keystrokes on dense pages, still correct). ADR-0001 records this as the design's escape valve. ## What this DOES mean / next steps - **Spike D must run on a machine with the bandwidth to build PDFium and Skia** — a CI runner, a developer workstation, or a build server. It is the one M0 spike that needs a heavier environment than a laptop sandbox. - **Before Spike D can run, the Skia display-list renderer must exist** (M2 work). Spike D tests *that renderer* against PDFium; without it, there is nothing to compare. So D is naturally a late-M0 / early-M2 activity, not a pure M0 spike — it depends on M2's L3 renderer. - **The pixel-diff harness scaffolding is already in place** (`ci/pixel-diff/run_pixel_diff.py`) with the CLI/JSON contract and `--noop` mode. When the Skia renderer and PDFium are available, the harness fills in the real `render_page` and `compare_png` stubs. That work is M2, not blocked by this deferral. ## Reproducing (when the environment allows) ```bash # Build PDFium ( Chromium's pdfium repo — hours, ~tens of GB): # git clone https://pdfium.googlesource.com/pdfium.git # cd pdfium && ./build/install-build-deps.sh && gn gen out/Default && ninja -C out/Default pdfium # Build Skia: # git clone https://skia.googlesource.com/skia.git && cd skia && python tools/git-sync-deps # gn gen out/Default && ninja -C out/Default # Then wire them into spike/D_renderer/ and run the pixel-diff harness. ``` This is left as the next step for an environment with the build bandwidth.