Viewer: lay out pixel labels only for the area being repainted
drawPixelLabels took its range from the whole viewport rather than from the exposed rect it was given, so a 200x40 px hover repaint still walked up to 5000 cells doing mapFromScene + QImage::pixel + drawText for each, only to have the result clipped away. With hover feedback now rate-limited to 15 Hz that ran ~75 times a second at high zoom, against once per overlay rebuild before the rendering rework. Intersect with the exposed rect; same in the magnifier. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -91,7 +91,8 @@ void JFJochFollowerImage::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
if (static_cast<int64_t>(pixels.size()) < static_cast<int64_t>(W) * H)
|
||||
return; // values belong to a different frame
|
||||
|
||||
const QRectF visible = mapToScene(viewport()->rect()).boundingRect();
|
||||
// Clipped to the exposed area, for the same reason as JFJochImage::drawPixelLabels.
|
||||
const QRectF visible = mapToScene(viewport()->rect()).boundingRect() & rect;
|
||||
const int x0 = std::max(0, static_cast<int>(std::floor(visible.left())));
|
||||
const int x1 = std::min(W, static_cast<int>(std::ceil(visible.right())));
|
||||
const int y0 = std::max(0, static_cast<int>(std::floor(visible.top())));
|
||||
|
||||
@@ -852,10 +852,13 @@ QString JFJochImage::PixelLabel(int x, int y) const {
|
||||
return QString::number(val, 'e', 1);
|
||||
}
|
||||
|
||||
void JFJochImage::drawPixelLabels(QPainter *painter) {
|
||||
void JFJochImage::drawPixelLabels(QPainter *painter, const QRectF &rect) {
|
||||
constexpr int kMaxLabels = 5000;
|
||||
|
||||
const QRectF visibleRect = mapToScene(viewport()->rect()).boundingRect();
|
||||
// Only the exposed area, not the whole viewport: a hover repaint dirties a couple of hundred
|
||||
// pixels, and laying out every visible cell for it would do thousands of mapFromScene / pixel /
|
||||
// drawText calls whose output is then clipped away - at up to 15 repaints a second.
|
||||
const QRectF visibleRect = mapToScene(viewport()->rect()).boundingRect() & rect;
|
||||
const int startX = std::max(0, static_cast<int>(std::floor(visibleRect.left())));
|
||||
const int endX = std::min(static_cast<int>(W), static_cast<int>(std::ceil(visibleRect.right())));
|
||||
const int startY = std::max(0, static_cast<int>(std::floor(visibleRect.top())));
|
||||
@@ -895,7 +898,7 @@ void JFJochImage::drawForeground(QPainter *painter, const QRectF &rect) {
|
||||
QGraphicsView::drawForeground(painter, rect);
|
||||
|
||||
if (scale_factor > 30.0 && W * H > 0 && frame_ && !frame_->isNull())
|
||||
drawPixelLabels(painter);
|
||||
drawPixelLabels(painter, rect);
|
||||
}
|
||||
|
||||
void JFJochImage::resetScenePointers() {
|
||||
|
||||
@@ -82,7 +82,7 @@ class JFJochImage : public QGraphicsView {
|
||||
void DrawROI();
|
||||
virtual void addCustomOverlay();
|
||||
void updateROI();
|
||||
void drawPixelLabels(QPainter *painter);
|
||||
void drawPixelLabels(QPainter *painter, const QRectF &rect);
|
||||
void wheelEvent(QWheelEvent* event) override;
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
|
||||
Reference in New Issue
Block a user