Skip to content

DisplayDriver seam: fold the bulge-exclude span into present() (#345) - #369

Merged
timohueser merged 2 commits into
developfrom
feat/345-present-exclude
Jul 3, 2026
Merged

DisplayDriver seam: fold the bulge-exclude span into present() (#345)#369
timohueser merged 2 commits into
developfrom
feat/345-present-exclude

Conversation

@timohueser

Copy link
Copy Markdown
Owner

Closes #345 (epic #353, phase 2).

What

  1. Trait: DisplayDriver::present(&mut self, exclude: Option<(u16, u16)>) -> bool — excluded rows are diffed (the store tracks the clean fb) but not pushed; the overlay plane owns repainting them. Contract documented on the trait.
  2. Shared skeleton hoisted: the diff → clip-around-exclude → whole-frame-minus-exclude-on-span-overflow logic moves from Ls021Flpr::present_within to obc_platform::RowDiff::diff_clipped(fb, stride, exclude, &mut spans) -> &[(u16,u16)] (caller-provided scratch, returns the filled prefix — no_std, no alloc). Four new host tests: clipping, store-updated-for-excluded-rows (a later un-excluded present doesn't re-push), priming-with-exclude, and the overflow fallback respecting the exclude.
  3. FLPR: present_within shrinks to diff_clipped + push_spans and goes pub(crate) (only the display::ls021_flpr adapter calls it); the map plane's match overlay_span + concrete present_within call is deleted — it calls the seam's present(overlay_span) unconditionally.
  4. ST7789: present(exclude) bands only the clipped spans — the documented "dev-only-best-effort" mid-hold flash is gone. The tft MapDisplay now holds the InputPlane handle: poll_overlay returns the live bulge span (read-only overlay_rows — the one-shot take_overlay_dirty edge stays with input_overlay_task, which still owns the bulge push), and hold_progress() returns the real value, so the in-screen Reset-bar fill finally moves on tft.
  5. Convergence: poll_overlay/hold_progress/render_present bodies are now near-identical across the two MapDisplays; the structs stay separate (bus-mutex vs owned-panel is the genuine asymmetry). Not folded further per the issue ("full merge optional stretch").

Note: render_present's FLPR-only reset_diff() fault-recovery call remains a concrete-type touch — that recovery shape is #349's remit.

Verification

  • 4 new diff_clipped host tests + all existing rowdiff/clip_span tests pass (workspace cargo test green).
  • grep present_within hits only ls021_flpr.rs + its seam adapter; the map plane has no concrete present call left.
  • All six board feature shapes build; clippy -D warnings-clean on default/tft/ble.
  • On-glass checks pending (no DK on my end): FLPR bulge-during-redraw parity, and tft mid-hold no-blank + Reset-bar fill.

Docs

docs/content/software/rendering.md credited only the FLPR with presenting around the bulge — updated in a separate docs: commit (link check passes). firmware/docs/ls021-flpr.md doesn't describe the present seam; the public display-protocol page is wire-level only — both unaffected.

🤖 Generated with Claude Code

timohueser and others added 2 commits July 4, 2026 00:38
The seam's present now takes exclude: Option<(u16, u16)> — "these rows
belong to the overlay plane this frame: keep the diff store current for
them, but don't push them". The diff/clip/overflow-fallback skeleton that
implemented this only inside Ls021Flpr::present_within moves to
obc-platform as RowDiff::diff_clipped (with host tests); both backends now
run it verbatim.

FLPR: present_within becomes the pub(crate) engine behind the seam method;
the map plane's `match overlay_span` on the concrete type is gone — it
calls present(overlay_span) unconditionally.

ST7789: present(exclude) clips a live bulge's rows out of the banded push,
fixing the documented mid-hold flash (a dirty.map redraw used to blank the
bulge until the overlay task's next ~8 ms tick). The tft MapDisplay now
holds the InputPlane handle, so poll_overlay reports the real live span
(read-only — the overlay task keeps the one-shot dirty edge) and
hold_progress returns the real value, un-breaking the in-screen
hold-to-confirm fills (the Reset bar) on tft.

Closes #345. Part of epic #353.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rendering page credited only the MIP/FLPR backend with clipping the
bulge's rows out of a mid-animation redraw; with present(exclude) in the
seam both panels share that discipline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@timohueser
timohueser merged commit be7e07c into develop Jul 3, 2026
16 checks passed
@timohueser
timohueser deleted the feat/345-present-exclude branch July 3, 2026 22:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DisplayDriver seam: fold the bulge-exclude span into present()

1 participant