diff --git a/viewer/image_viewer/JFJochImage.cpp b/viewer/image_viewer/JFJochImage.cpp index ff5752e0..c266660b 100644 --- a/viewer/image_viewer/JFJochImage.cpp +++ b/viewer/image_viewer/JFJochImage.cpp @@ -43,7 +43,7 @@ JFJochImage::JFJochImage(QWidget *parent) : QGraphicsView(parent) { } void JFJochImage::onScroll(int value) { - updateOverlay(); + scheduleOverlayUpdate(); } void JFJochImage::changeBackground(float val) { @@ -122,7 +122,7 @@ void JFJochImage::wheelEvent(QWheelEvent *event) { QPointF delta = targetScenePos - updatedViewportCenter; translate(delta.x(), delta.y()); // Shift the view - updateOverlay(); + scheduleOverlayUpdate(); emitViewportChanged(); } } @@ -140,7 +140,7 @@ void JFJochImage::resizeEvent(QResizeEvent *event) { if (!initial_fit_done_) fitToViewShorterSideOnce(); - updateOverlay(); + scheduleOverlayUpdate(); } QPointF JFJochImage::RoundPoint(const QPointF &input) { @@ -221,7 +221,7 @@ void JFJochImage::mouseMoveEvent(QMouseEvent *event) { horizontalScrollBar()->setValue(horizontalScrollBar()->value() - viewDelta.x()); verticalScrollBar()->setValue(verticalScrollBar()->value() - viewDelta.y()); - updateOverlay(); + scheduleOverlayUpdate(); emitViewportChanged(); break; } @@ -272,7 +272,7 @@ void JFJochImage::mouseMoveEvent(QMouseEvent *event) { // Update hover state so overlay can draw arrows/handles accordingly if (h != hover_handle_) { hover_handle_ = h; - updateOverlay(); + scheduleOverlayUpdate(); } // Set an informative cursor switch (h) { @@ -837,6 +837,22 @@ void JFJochImage::resetScenePointers() { overlay_items_.clear(); } +void JFJochImage::scheduleOverlayUpdate() { + // Coalesce a burst of navigation events into one overlay rebuild. A single + // pan step, for instance, emits valueChanged on both scrollbars plus a + // direct call - 3 rebuilds for one visual change. Rebuilding tears down and + // recreates every spot/prediction/ROI item, so collapsing the duplicates to + // one rebuild on the next event-loop pass sharply cuts CPU and, over remote + // X forwarding, rasterised-pixel traffic. + if (overlay_update_scheduled_) + return; + overlay_update_scheduled_ = true; + QTimer::singleShot(0, this, [this]() { + overlay_update_scheduled_ = false; + updateOverlay(); + }); +} + void JFJochImage::updateOverlay() { if (!scene() || W * H <= 0) return; diff --git a/viewer/image_viewer/JFJochImage.h b/viewer/image_viewer/JFJochImage.h index a6955915..894ccd8b 100644 --- a/viewer/image_viewer/JFJochImage.h +++ b/viewer/image_viewer/JFJochImage.h @@ -17,6 +17,10 @@ class JFJochImage : public QGraphicsView { bool m_adjustForegroundWithWheel = false; + // Coalescing guard for scheduleOverlayUpdate(): collapses a burst of + // navigation events into a single overlay rebuild on the next event loop. + bool overlay_update_scheduled_ = false; + // Viewport-lock support: guard prevents the emit<->apply ping-pong between // two linked views, and the helper broadcasts the current transform+center. bool m_applyingViewport = false; @@ -104,6 +108,7 @@ protected: ResizeHandle hitTestROIHandle(const QPointF& scenePos, qreal tol = 3.0) const; void updateOverlay(); + void scheduleOverlayUpdate(); void GeneratePixmap(); void Redraw(); void CalcROI();