Editor: optimize annotation cache cleanup

Looking up the last visible block is not for free since it calculates
the bounding rects for all blocks between the first and last visible
block. Avoid one calculation by postponing the annotation cleanup after
the paint event and only if we reach a certain amount of cached entries.

Change-Id: Ibfab49301f82237e16d5a69ce1531539907e7ed8
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
David Schulz
2023-06-30 10:37:53 +02:00
parent 1e6eb1ba28
commit b721d98476

View File

@@ -449,6 +449,7 @@ struct PaintEventData
, textCursorBlock(textCursor.block()) , textCursorBlock(textCursor.block())
, isEditable(!editor->isReadOnly()) , isEditable(!editor->isReadOnly())
, fontSettings(editor->textDocument()->fontSettings()) , fontSettings(editor->textDocument()->fontSettings())
, lineSpacing(fontSettings.lineSpacing())
, searchScopeFormat(fontSettings.toTextCharFormat(C_SEARCH_SCOPE)) , searchScopeFormat(fontSettings.toTextCharFormat(C_SEARCH_SCOPE))
, searchResultFormat(fontSettings.toTextCharFormat(C_SEARCH_RESULT)) , searchResultFormat(fontSettings.toTextCharFormat(C_SEARCH_RESULT))
, visualWhitespaceFormat(fontSettings.toTextCharFormat(C_VISUAL_WHITESPACE)) , visualWhitespaceFormat(fontSettings.toTextCharFormat(C_VISUAL_WHITESPACE))
@@ -469,6 +470,7 @@ struct PaintEventData
const QTextBlock textCursorBlock; const QTextBlock textCursorBlock;
const bool isEditable; const bool isEditable;
const FontSettings fontSettings; const FontSettings fontSettings;
const int lineSpacing;
const QTextCharFormat searchScopeFormat; const QTextCharFormat searchScopeFormat;
const QTextCharFormat searchResultFormat; const QTextCharFormat searchResultFormat;
const QTextCharFormat visualWhitespaceFormat; const QTextCharFormat visualWhitespaceFormat;
@@ -561,6 +563,7 @@ public:
QPainter &painter, QPainter &painter,
const PaintEventBlockData &blockData) const; const PaintEventBlockData &blockData) const;
QTextBlock nextVisibleBlock(const QTextBlock &block) const; QTextBlock nextVisibleBlock(const QTextBlock &block) const;
void scheduleCleanupAnnotationCache();
void cleanupAnnotationCache(); void cleanupAnnotationCache();
// extra area paint methods // extra area paint methods
@@ -706,6 +709,7 @@ public:
friend bool operator==(const AnnotationRect &a, const AnnotationRect &b) friend bool operator==(const AnnotationRect &a, const AnnotationRect &b)
{ return a.mark == b.mark && a.rect == b.rect; } { return a.mark == b.mark && a.rect == b.rect; }
}; };
bool cleanupAnnotationRectsScheduled = false;
QMap<int, QList<AnnotationRect>> m_annotationRects; QMap<int, QList<AnnotationRect>> m_annotationRects;
QRectF getLastLineLineRect(const QTextBlock &block); QRectF getLastLineLineRect(const QTextBlock &block);
@@ -4225,6 +4229,9 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data,
q->viewport()->update(annotationRect.rect.toAlignedRect()); q->viewport()->update(annotationRect.rect.toAlignedRect());
} }
m_annotationRects[data.block.blockNumber()] = newRects; m_annotationRects[data.block.blockNumber()] = newRects;
const int maxVisibleLines = data.viewportRect.height() / data.lineSpacing;
if (m_annotationRects.size() >= maxVisibleLines * 2)
scheduleCleanupAnnotationCache();
} }
QColor blendRightMarginColor(const FontSettings &settings, bool areaColor) QColor blendRightMarginColor(const FontSettings &settings, bool areaColor)
@@ -4892,8 +4899,19 @@ QTextBlock TextEditorWidgetPrivate::nextVisibleBlock(const QTextBlock &block) co
return TextEditor::nextVisibleBlock(block, q->document()); return TextEditor::nextVisibleBlock(block, q->document());
} }
void TextEditorWidgetPrivate::scheduleCleanupAnnotationCache()
{
if (cleanupAnnotationRectsScheduled)
return;
QMetaObject::invokeMethod(this,
&TextEditorWidgetPrivate::cleanupAnnotationCache,
Qt::QueuedConnection);
cleanupAnnotationRectsScheduled = true;
}
void TextEditorWidgetPrivate::cleanupAnnotationCache() void TextEditorWidgetPrivate::cleanupAnnotationCache()
{ {
cleanupAnnotationRectsScheduled = false;
const int firstVisibleBlock = q->firstVisibleBlockNumber(); const int firstVisibleBlock = q->firstVisibleBlockNumber();
const int lastVisibleBlock = q->lastVisibleBlockNumber(); const int lastVisibleBlock = q->lastVisibleBlockNumber();
auto lineIsVisble = [&](int blockNumber){ auto lineIsVisble = [&](int blockNumber){
@@ -5015,8 +5033,6 @@ void TextEditorWidget::paintEvent(QPaintEvent *e)
} }
} }
d->cleanupAnnotationCache();
painter.setPen(data.context.palette.text().color()); painter.setPen(data.context.palette.text().color());
d->updateAnimator(d->m_bracketsAnimator, painter); d->updateAnimator(d->m_bracketsAnimator, painter);