[graphics/krita] libs/ui/tool: Thread-safe zoom preview
Emmet O'Neill <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 2e7505044d162dd9d91ed4b8391710911fd5c871 by Emmet O'Neill, on behalf of Dat Le.
Committed on 13/08/2026 at 23:16.
Pushed by emmetoneill into branch 'master'.
Thread-safe zoom preview
M +12 -12 libs/ui/tool/KisAsyncColorSamplerHelper.cpp
M +2 -1 libs/ui/tool/KisAsyncColorSamplerHelper.h
https://invent.kde.org/graphics/krita/-/commit/2e7505044d162dd9d91ed4b8391710911fd5c871
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
index 7a250fd107f..520d1fd608b 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.cpp
@@ -727,28 +727,28 @@ QImage KisAsyncColorSamplerHelper::cacheCanvasImage(QRect &canvasPixelRect) {
if (m_d->cacheCanvasPreviewRect.isEmpty() || !m_d->cacheCanvasPreviewRect.contains(canvasPixelRect)) {
// Cache an area larger than the needed preview area to avoid rapid small dynamic allocations
- // Attempt to reduce cache size when sample size is big to reduce delay
- qreal cacheScale = 1000;
- // if (canvasPixelRect.width() < 250) cacheScale = 4;
- // else if (canvasPixelRect.width() < 500) cacheScale = 2;
+ // And also avoid frequent preview delay from fetching canvas image asynchronously repeatedly
+ qreal cacheScale = 4;
QRect cacheCanvasRect = canvasPixelRect;
cacheCanvasRect.setSize(canvasPixelRect.size() * cacheScale);
cacheCanvasRect.moveCenter(canvasPixelRect.center());
- // if cache larger than canvas, then just copy whole canvas
+ // if cache requirement is larger than canvas, then just copy whole canvas
if (cacheCanvasRect.width() >= canvasImage->width() || cacheCanvasRect.height() >= canvasImage->height()) {
cacheCanvasRect = canvasImage->bounds();
}
- // If already fetching, then do nothing
- if (m_d->canvasPreviewFetchingStarted) return QImage();
-
- m_d->canvasPreviewFetchingStarted = true;
- m_d->strokesFacade()->addJob(m_d->strokeId,
- new KisColorSamplerStrokeStrategy::GenerateCanvasZoomPreviewData(canvasImage, cacheCanvasRect, canvasImage->profile()));
+ // If not already have a job fetching canvas image, then do it
+ // TODO: There's probably a better way to do this
+ if (!m_d->canvasPreviewFetchingStarted) {
+ m_d->canvasPreviewFetchingStarted = true;
+ m_d->strokesFacade()->addJob(m_d->strokeId,
+ new KisColorSamplerStrokeStrategy::GenerateCanvasZoomPreviewData(canvasImage, cacheCanvasRect, canvasImage->profile()));
+ }
- return QImage();
+ // Instead of returning an empty QImage and cause painful flickering
+ // Just return old cache, it's not really noticeable normally. In extreme cases, we have a cool lazy loading effect :D
}
canvasPixelRect.translate(-m_d->cacheCanvasPreviewRect.topLeft());
diff --git a/libs/ui/tool/KisAsyncColorSamplerHelper.h b/libs/ui/tool/KisAsyncColorSamplerHelper.h
index 4b0513f8b32..13a955f24c3 100644
--- a/libs/ui/tool/KisAsyncColorSamplerHelper.h
+++ b/libs/ui/tool/KisAsyncColorSamplerHelper.h
@@ -83,8 +83,9 @@ private:
void paintCircle(QPainter &gc, const QRectF &viewRectF, const QColor ¤tColor, const QColor &baseColor);
void paintCircleCrosshair(QPainter &gc, const QRectF &viewRectF, const QColor ¤tColor);
+ // Return true if cache miss, will repaint later when canvas image is fetched
+ // Return false if cache hit, and painted
bool paintCircleCanvasPreview(QPainter &gc, const QRectF &viewRectF, const QRectF &zoomDocRectF, const QPainterPath &clip);
- // Return true if at least one reference image preview was drawn
void paintCircleReferenceImagePreview(QPainter &gc, const QRectF &viewRectF, const QRectF &zoomDocRectF, const QPainterPath &clip);
// Returns a QImage that should either contain the canvasPixelRectF, or the whole canvas if canvasPixelRectF > canvas size.