Ground Station OSD data model and always-visible overlay renderer #15

Open
grzesiu wants to merge 6 commits from issue-3-osd-overlay into main
Collaborator

Closes #3

Summary

  • publish immutable, latest-wins OSD snapshots without blocking UART/WFB/video
  • keep OperatorConfig, GSPolicy, VTXAck, and GSObservedLink distinct, with an explicit versioned seam for future FlightTelemetry from #19/#20
  • render ARM, adaptive-link state, and authoritative VIDEO ON/OFF from startup; show NO DATA before the first snapshot and visibly retain stale last-known data
  • map fallback fullscreen/below and transparent input-pass-through OSD fullscreen/above from the first frame
  • keep OSD above fallback when video is absent and above tracked fullscreen video when present
  • hide the cursor natively from the first mapped frame on both Ground Station layers, without relying on wfb-ng/unclutter
  • treat CH6 only as temporary maxPower; never present static configuration as VTX-applied state

Validation

  • gofmt -l .
  • go vet ./...
  • go test ./...
  • go test -race ./...
  • both linux/arm64 binaries with CI-parity settings
  • git diff --check, cumulative issue-only path review, added-lines secret/security scan

Hardware acceptance

Install both binaries from the current head. Expected before video: immediate fullscreen fallback, hidden cursor, visible OSD with VIDEO OFF and explicit no-data/fresh/stale state. Expected after WFB video starts/stops: OSD remains visible above video or fallback and VIDEO ON/OFF follows the display-observed lifecycle. Fresh Orange Pi confirmation remains required.

X11 hardware root-cause correction

Orange Pi logs proved the blank-cursor regression used root-depth (24) pixmaps where X11 CreateCursor requires depth-1 bitmaps. The unchecked cursor failure invalidated the unchecked CreateWindow; the later checked Shape request only surfaced a downstream BadWindow. The current head uses checked depth-1 cursor construction, checked window creation before any Shape/Map request, complete cleanup, and a fail-open default cursor so optional cursor hiding can never suppress either Ground Station layer.

OSD timer starvation correction

Live X11 evidence showed the OSD mapped and topmost but its bounding Shape remained 0x0+0+0 across multiple refresh periods with no errors. The event loop drained a continuous non-Expose root-event stream without returning to timer checks, starving the only 1 Hz redraw that can punch an initially empty Shape. The current head bounds each drain batch to 32 processed events, guaranteeing refresh/liveness/cancellation fairness while preserving event-driven canvas behavior and serialized X11 access.

Closes #3 ## Summary - publish immutable, latest-wins OSD snapshots without blocking UART/WFB/video - keep `OperatorConfig`, `GSPolicy`, `VTXAck`, and `GSObservedLink` distinct, with an explicit versioned seam for future `FlightTelemetry` from #19/#20 - render ARM, adaptive-link state, and authoritative `VIDEO ON/OFF` from startup; show `NO DATA` before the first snapshot and visibly retain stale last-known data - map fallback fullscreen/below and transparent input-pass-through OSD fullscreen/above from the first frame - keep OSD above fallback when video is absent and above tracked fullscreen video when present - hide the cursor natively from the first mapped frame on both Ground Station layers, without relying on wfb-ng/unclutter - treat CH6 only as temporary `maxPower`; never present static configuration as VTX-applied state ## Validation - `gofmt -l .` - `go vet ./...` - `go test ./...` - `go test -race ./...` - both linux/arm64 binaries with CI-parity settings - `git diff --check`, cumulative issue-only path review, added-lines secret/security scan ## Hardware acceptance Install both binaries from the current head. Expected before video: immediate fullscreen fallback, hidden cursor, visible OSD with `VIDEO OFF` and explicit no-data/fresh/stale state. Expected after WFB video starts/stops: OSD remains visible above video or fallback and `VIDEO ON/OFF` follows the display-observed lifecycle. Fresh Orange Pi confirmation remains required. ## X11 hardware root-cause correction Orange Pi logs proved the blank-cursor regression used root-depth (24) pixmaps where X11 `CreateCursor` requires depth-1 bitmaps. The unchecked cursor failure invalidated the unchecked `CreateWindow`; the later checked Shape request only surfaced a downstream `BadWindow`. The current head uses checked depth-1 cursor construction, checked window creation before any Shape/Map request, complete cleanup, and a fail-open default cursor so optional cursor hiding can never suppress either Ground Station layer. ## OSD timer starvation correction Live X11 evidence showed the OSD mapped and topmost but its bounding Shape remained `0x0+0+0` across multiple refresh periods with no errors. The event loop drained a continuous non-Expose root-event stream without returning to timer checks, starving the only 1 Hz redraw that can punch an initially empty Shape. The current head bounds each drain batch to 32 processed events, guaranteeing refresh/liveness/cancellation fairness while preserving event-driven canvas behavior and serialized X11 access.
piotr was assigned by grzesiu 2026-10-17 08:49:56 +02:00
grzesiu added 1 commit 2026-10-17 08:49:56 +02:00
grzesiu added 1 commit 2026-10-18 08:02:19 +02:00
grzesiu added 1 commit 2026-11-03 13:11:17 +01:00
grzesiu changed title from Ground Station OSD data model and overlay renderer to Ground Station OSD data model and always-visible overlay renderer 2026-11-03 13:11:57 +01:00
grzesiu added 1 commit 2026-11-03 22:49:38 +01:00
grzesiu added 1 commit 2026-11-05 14:56:19 +01:00
grzesiu added 1 commit 2026-11-06 16:37:40 +01:00
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-3-osd-overlay:issue-3-osd-overlay
git checkout issue-3-osd-overlay
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: piotr/groundstation#15