summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAntti Määttä <antti.maatta@qt.io>2021-05-06 11:00:08 +0300
committerAntti Määttä <antti.maatta@qt.io>2021-05-07 06:53:54 +0300
commit1fb4a3ef2bd86d650495e15a23c7efc1e600a59a (patch)
tree5cf1f04e886c1058f9b51e73be5da0fdaf90bb33
parent6128880ca270a0a6799b51a283596e5142d1a747 (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 Pick-to: 5.15 6.1 Change-Id: I8a2fd89f2f2076e0c9364618a4cdc2596e0087a1 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-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) {