Skip to content

Cursor motion over the panadapter re-bakes the whole overlay every frame (defeats #719 upload cache) #3779

Description

@svabi79

Report preparation

  • I used the AI-assisted bug report tool (Help → Support → File an Issue)
  • I have attached a support bundle or log file (aether.perf measurements below)

What happened?

Moving the mouse over the panadapter re-bakes the entire static overlay on every frame and re-uploads both framebuffer-sized overlay textures — even when nothing cursor-dependent is shown. With the cursor-frequency readout (#726) and tune guides both off (the default), the re-baked overlay is byte-for-byte identical, so this is pure waste. It silently defeats the GPU overlay-upload cache that was added for macOS in #719.

Root cause. SpectrumWidget::updateTrackedCursorState() calls markOverlayDirty() whenever the cursor position changes:

if (m_cursorPos != oldCursorPos
    || m_hoveredTnfId != oldHoveredTnfId
    || m_tuneGuideVisible != oldTuneGuideVisible) {
    markOverlayDirty();          // sets m_overlayStaticDirty = true
}

renderGpuFrame() also re-asserts the cursor position from QCursor::pos() every frame (the macOS tune-guide-recovery poll), so while the mouse is moving the static overlay is re-rastered and re-uploaded on every frame. But the only things in the static overlay that depend on m_cursorPos are the cursor-frequency label and the tune-guide line — both off by default. The bare cursor-position term invalidates unconditionally.

This is a regression of #719: that PR added overlay-upload caching specifically to "skip the 5.8 MB texture upload when overlay content is unchanged (only upload after m_overlayStaticDirty)". The cursor-position markOverlayDirty() was introduced later by the TNF-interaction refactor in #1547 (2026-04-17, after #719 on 2026-04-04), which re-introduced a per-mouse-move dirty and defeated the cache.

Measured (i9-13900K / RTX 4090, GPU path, 2 panadapters, dummy load, cursor-freq + tune-guides OFF = default; gated aether.perf + a temporary static-rebake counter):

condition static overlay re-bakes /s renderP95 (ms) overlay uploads /s
cursor idle 0 0.3 44 (flag sprites only)
cursor moving over pane ~55 (every frame) 6.2 ~150

That is a ~20× jump in main-thread render time purely from moving the mouse, producing no visible change. The cost scales with overlay content — with DX spots, an SWR sweep, or a busy band plan the per-frame re-raster is considerably more expensive than on this quiet dummy load, which is the likely source of "the waterfall feels choppy when I drag the mouse across it" reports.

What did you expect?

Moving the cursor over the panadapter should not re-bake/re-upload the overlay when neither the cursor-frequency readout nor a tune guide is shown — render time should stay at the idle ~0.3 ms. When a readout is active, the overlay should of course still update so the readout tracks the cursor.

Steps to reproduce

  1. Build the GPU path (AETHER_GPU_SPECTRUM), connect a radio (or a dummy load).
  2. Enable performance logging: Help → Support → "Performance".
  3. Leave "Show VFO frequency at cursor" and "Show Tune Guides" off (defaults).
  4. Move the mouse continuously across the panadapter spectrum/waterfall.
  5. In the log, watch renderP95Ms jump from ~0.3 ms (idle) to ~6 ms, and gpuOverlay uploads roughly triple, for the duration of the motion — with no visible change on screen.

AetherSDR version

26.6.3 (also reproduced on origin/main @ 65923163)

Radio model & firmware

FLEX-6600 (radio-agnostic; reproduced on a dummy load)

Operating system

Windows

OS version and hardware

Windows 11 Pro 24H2, Qt 6.8.3, i9-13900K / RTX 4090. Cross-platform — the defeated cache (#719) was added for macOS, where the wasted upload is most costly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfacebugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is takenpriority: mediumMedium priorityspectrumPanadapter and waterfall

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions