summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2021-05-06 11:00:08 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-05-07 04:27:27 +0000
commite292cd6249b347771006aa9bbeef735391e367ac (patch)
tree014dbeb0263ac2e42570035d7134087f146a933b
parent0e6be31982bad77b1f6bf23e5eadcddb062b9cac (diff)
Add text bounds cache
Improve performance by caching recently used text bounds. Charts keeps requesting bounds for the same text multiple times. Store the recently requested bounds to a cache to improve performance. In android device reduces the frame time by about 30 % and in windows reduces the total time spent in native text function used to get the bounds from 8.5% to 3.1%. Fixes: QTBUG-59040 Change-Id: I8a2fd89f2f2076e0c9364618a4cdc2596e0087a1 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> (cherry picked from commit 1fb4a3ef2bd86d650495e15a23c7efc1e600a59a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/charts/chartpresenter.cpp51
1 files changed, 46 insertions, 5 deletions
diff --git a/src/charts/chartpresenter.cpp b/src/charts/chartpresenter.cpp
index 2a704fa0..f9e7a481 100644
--- a/src/charts/chartpresenter.cpp
+++ b/src/charts/chartpresenter.cpp
@@ -478,18 +478,59 @@ ChartTitle *ChartPresenter::titleElement()
return m_title;
}
+template <int TSize>
+struct TextBoundCache
+{
+ struct element
+ {
+ quint32 lastUsed;
+ QRectF bounds;
+ };
+ QHash<QString, element> elements;
+ quint32 usedCounter = 0;
+ QGraphicsTextItem dummyText;
+
+ QRectF bounds(const QFont &font, const QString &text)
+ {
+ const QString key = font.key() + text;
+ auto elem = elements.find(key);
+ if (elem != elements.end()) {
+ usedCounter++;
+ elem->lastUsed = usedCounter;
+ return elem->bounds;
+ }
+ dummyText.setFont(font);
+ dummyText.setHtml(text);
+ const QRectF bounds = dummyText.boundingRect();
+ if (elements.size() >= TSize) {
+ auto elem = std::min_element(elements.begin(), elements.end(),
+ [](const element &a, const element &b) {
+ return a.lastUsed < b.lastUsed;
+ });
+ if (elem != elements.end()) {
+ const QString key = elem.key();
+ elements.remove(key);
+ }
+ }
+ elements.insert(key, {usedCounter++, bounds});
+ return bounds;
+ }
+ QTextDocument *document()
+ {
+ return dummyText.document();
+ }
+};
+
QRectF ChartPresenter::textBoundingRect(const QFont &font, const QString &text, qreal angle)
{
- static QGraphicsTextItem dummyTextItem;
+ static TextBoundCache<32> textBoundCache;
static bool initMargin = true;
if (initMargin) {
- dummyTextItem.document()->setDocumentMargin(textMargin());
+ textBoundCache.document()->setDocumentMargin(textMargin());
initMargin = false;
}
- dummyTextItem.setFont(font);
- dummyTextItem.setHtml(text);
- QRectF boundingRect = dummyTextItem.boundingRect();
+ QRectF boundingRect = textBoundCache.bounds(font, text);
// Take rotation into account
if (angle) {