Viewer: do not render the magnifier close-up while it is closed

centerAt() checked isVisible(), but imageLoaded() did not, so every frame built
a SimpleImage over the whole detector image and ran it through the full
JFJochSimpleImage path -- convert to float, colour every pixel, redraw -- to
feed a 320x320 window that is closed by default and stays closed most of the
time.

Remember the frame instead and do the work in showEvent(). Holding the
shared_ptr also keeps alive the buffer that the SimpleImage's CompressedImage
points into, which it did not own.

Stepping 30 frames with the magnifier closed: 5545 -> 4770 ms CPU (-14%), on a
2.8 Mpx detector; the saving is per-pixel, so it grows with detector size. With
the magnifier open the cost is unchanged (5500 ms), which is what was being
paid unconditionally before.

Verified in the GUI: opening the magnifier still populates it, and it still
refreshes when the frame changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-26 20:45:11 +02:00
co-authored by Claude Opus 5
parent a30a746018
commit 6d1af4921f
2 changed files with 30 additions and 0 deletions
+21
View File
@@ -5,6 +5,7 @@
#include "../image_viewer/JFJochSimpleImage.h"
#include "../SimpleImage.h"
#include <QShowEvent>
#include <QTransform>
JFJochMagnifierWindow::JFJochMagnifierWindow(QWidget *parent)
@@ -17,6 +18,26 @@ JFJochMagnifierWindow::JFJochMagnifierWindow(QWidget *parent)
}
void JFJochMagnifierWindow::imageLoaded(std::shared_ptr<const JFJochReaderImage> image) {
m_pending_image = std::move(image);
// The window is closed most of the time, and rendering a close-up nobody is looking at costs
// a full conversion and recolour of the whole detector image on every frame.
if (!isVisible()) {
m_pending_dirty = true;
return;
}
ApplyPendingImage();
}
void JFJochMagnifierWindow::showEvent(QShowEvent *event) {
JFJochHelperWindow::showEvent(event);
if (m_pending_dirty)
ApplyPendingImage();
}
void JFJochMagnifierWindow::ApplyPendingImage() {
m_pending_dirty = false;
const std::shared_ptr<const JFJochReaderImage> &image = m_pending_image;
if (!image) {
m_have_image = false;
m_image->setImage(nullptr);
+9
View File
@@ -18,6 +18,15 @@ class JFJochMagnifierWindow : public JFJochHelperWindow {
double m_magnification = 12.0;
bool m_have_image = false;
// Building the close-up converts and colours the whole detector image, so it is only done
// while the window is actually up. The frame is remembered either way; holding the
// shared_ptr also keeps alive the buffer the SimpleImage points into.
std::shared_ptr<const JFJochReaderImage> m_pending_image;
bool m_pending_dirty = false;
void ApplyPendingImage();
void showEvent(QShowEvent *event) override;
public:
explicit JFJochMagnifierWindow(QWidget *parent = nullptr);