Skip to content

refactor(spectrum): excise GPU flag-sprite machinery, flags always live (#3777)#3806

Merged
ten9876 merged 1 commit into
mainfrom
refactor/excise-gpu-flag-sprites
Jun 26, 2026
Merged

refactor(spectrum): excise GPU flag-sprite machinery, flags always live (#3777)#3806
ten9876 merged 1 commit into
mainfrom
refactor/excise-gpu-flag-sprites

Conversation

@ten9876

@ten9876 ten9876 commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Strategy B of the GPU-flag reversion plan (attached to #3777) — the full excision that #3803 (the one-line default-flip) was the reversible precursor to. VFO slice flags are now unconditionally live child widgets; the off-screen-sprite + live-on-hover machinery is removed entirely, fixing the #3777 idle-flag blur and the Diversity-mode RX-antenna regression at the source.

Net −582 lines across SpectrumWidget.{cpp,h} and VfoWidget.{cpp,h}.

Relationship to #3803

These are alternatives — merge one, not both. #3803 flips the default but keeps the sprite path behind AETHER_GPU_FLAGS=1 (reversible, for measurement). This PR deletes the machinery (no env opt-in remains). Recommended sequence: validate live-flag behavior + the 4-panadapter re-profile via #3803 first; if the group commits to it, merge this as the clean removal and close #3803.

Removed (all sprite-path)

  • SpectrumWidget: m_gpuFlagMode + the env gate, m_flagRefreshTimer + lambda, grabFlagSprites/releaseFlagSprite, setLiveFlag/updateLiveFlag, updateFlagRefreshTimer/attachFlagTimerWindowWatcher + m_flagTimerFilteredWindow, FlagSprite + m_flagSprites/m_flagDrawOrder/m_flagQuadVbo/m_flagSampler/kMaxFlagSprites, the renderGpuFrame sprite draw-order/texture/quad blocks, and the QRhi flag-resource init/teardown.
  • VfoWidget: setButtonsOccluded + m_occludeRestore/m_buttonsOccluded.

Kept intact (verified)

Trade-off (unchanged from #3803)

Re-introduces the #3617 main-thread composite cost #3695 removed (~0.82 vs 0.45 cores, +0.37 ≈ +45% main-thread). Separate from and likely additive to #3797.

Test plan

  • Builds clean (cmake --build build --target AetherSDR); zero dangling references to removed symbols
  • Idle VFO-flag text crisp; no hover-pop (Windows)
  • Diversity-mode RX-antenna selection works
  • Flags position/move correctly with 1, 2, and N panadapters; split-partner side-locking intact (repositionVfoFlags path)
  • Dragging a flag: no audio crackle / re-raster crash (feat(spectrum): GPU-composite slice flags instead of raster siblings #3695's original concern)
  • 4-panadapter main-thread CPU re-profile (the decision gate)
  • a11y linter clean; SmartMTR meter renders correctly

Refs #3777, #3617. Supersedes #3803. Plan: see the #3777 comment.

🤖 Generated with Claude Code

…ve (#3777)

Strategy B of the #3617-lineage reversion plan (attached to #3777): the full
removal that #3803 (the default-flip) was the reversible precursor to. VFO slice
flags are now unconditionally ordinary live child widgets — the off-screen-sprite
+ live-on-hover path is gone, resolving the #3777 idle-flag text blur and the
Diversity-mode RX-antenna input regression at the source.

Removed (all gated on / part of the sprite path):
  - SpectrumWidget: m_gpuFlagMode + the AETHER_GPU_FLAGS/NO_GPU_FLAGS gate,
    m_flagRefreshTimer + its lambda, grabFlagSprites/releaseFlagSprite,
    setLiveFlag/updateLiveFlag, updateFlagRefreshTimer/attachFlagTimerWindowWatcher
    + m_flagTimerFilteredWindow, the FlagSprite struct + m_flagSprites/
    m_flagDrawOrder/m_flagQuadVbo/m_flagSampler/kMaxFlagSprites, the renderGpuFrame
    sprite draw-order/texture/quad blocks, and the QRhi flag-resource init/teardown.
  - VfoWidget: setButtonsOccluded + m_occludeRestore/m_buttonsOccluded.

Kept intact:
  - repositionVfoFlags() — the SHARED flag positioner (calls updatePosition() on
    every flag); only its trailing GPU-mode hide-block was removed. Still called
    each frame from renderGpuFrame, so live flags position correctly.
  - The entire GPU panadapter path (AETHER_GPU_SPECTRUM: FFT/waterfall/overlay).
  - The SmartMTR render-mode-agnostic fixes from #3771/#3773/#3775 (m_meterMenuOpen,
    setEnabled row dimming, ComboStyle :disabled, drawSmartMtrLabels size-gate).

Net -582 lines. Trade-off unchanged from #3803: re-introduces the #3617 main-thread
composite cost (~+0.37 cores) #3695 removed — separate from, and likely additive
to, #3797. Unlike #3803 there is no env opt-in to restore sprites; the machinery
is gone, so this is the commit-to-it option once the 4-panadapter re-profile
confirms the trade is acceptable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ten9876 ten9876 requested a review from a team as a code owner June 25, 2026 03:50

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ten9876 — this is a clean, well-scoped excision. I verified the mechanics rather than re-litigate the strategy:

Code review: clean ✅

  • No dangling references. Repo-wide grep for every removed symbol (m_gpuFlagMode, m_flagRefreshTimer, grabFlagSprites/releaseFlagSprite, setLiveFlag/updateLiveFlag, updateFlagRefreshTimer/attachFlagTimerWindowWatcher, m_flagTimerFilteredWindow, FlagSprite/m_flagSprites/m_flagDrawOrder/m_flagQuadVbo/m_flagSampler/kMaxFlagSprites, m_liveFlag*, setButtonsOccluded/m_occludeRestore/m_buttonsOccluded, AETHER_NO_GPU_FLAGS/AETHER_GPU_FLAGS) returns zero matches. The machinery was self-contained.
  • Header/impl parity. SpectrumWidget.h / VfoWidget.h declaration removals match the .cpp; the now-unused #include <QPointer> is correctly dropped from SpectrumWidget.h (no remaining QPointer use in that header or its .cpp — VfoWidget.h keeps its own QPointer members and include).
  • The correctness invariant holds. repositionVfoFlags() is intact, still invoked each frame from renderGpuFrame, and only calls updatePosition() per flag — it never hides anything. addVfoWidget() calls w->show()/raise() unconditionally, so with the sprite/hover-swap layer gone the flags are simply always-live child widgets, which is the documented baseline. No resource leak (the QRhiTexture/SRB teardown is removed only because the sprites it freed are gone).
  • CI green on this SHA: build, check-windows, check-macos, CodeQL, and Qt a11y static analysis all pass.

No convention, null-safety, or scope issues — all four touched files are in scope, and a pure removal touches no AppSettings/system boundaries.

One non-code note (process / merge-gating)

This is correct as code but, per your own plan, shouldn't land yet:

  1. It re-introduces the #3617 main-thread composite cost (~+0.37 cores / +45% main-thread) that #3695 removed — a real, deliberate regression that you've flagged as additive to #3797 on multi-panadapter setups.
  2. You've marked the 4-panadapter re-profile as the decision gate, and that box (plus the Windows crisp-text, Diversity-RX, multi-pan positioning, and drag-no-crackle checks) is still unchecked. The recommended sequence in the description — validate via the reversible #3803 first, then merge this as the clean removal and close #3803 — is the right call.

So: ✅ for the code itself; the gate is the perf re-profile + the validation checklist, not anything in the diff. Nice surgical work.


🤖 aethersdr-agent · cost: $7.7482 · model: claude-opus-4-8

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.

1 participant