QWidgetTextControl: port to new-style connects (faster)

This speeds up creating a QGraphicsTextItem by 14% in an optimized build
Before: 0.070 msecs per iteration
After: 0.060 msecs per iteration

Those connects were showing up when profiling, because of the string
parsing that is necessary when using SIGNAL/SLOT macros.
The stacktrace was connect() => decodeMethodSignature() => argumentTypesFromString()
=> QArgumentType constructor => qMetaTypeInternal(const char*).

Pick-to: 6.3 6.2 5.15
Change-Id: I3cf5655c5450f121005140bdb587fafa083cce6a
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
David Faure 2022-04-29 17:20:42 +02:00
parent b51712f136
commit 3bc80195df
7 changed files with 45 additions and 33 deletions

View File

@ -435,7 +435,8 @@ void QAbstractTextDocumentLayout::registerHandler(int objectType, QObject *compo
if (!iface) if (!iface)
return; // ### print error message on terminal? return; // ### print error message on terminal?
connect(component, SIGNAL(destroyed(QObject*)), this, SLOT(_q_handlerDestroyed(QObject*))); QObjectPrivate::connect(component, &QObject::destroyed, d,
&QAbstractTextDocumentLayoutPrivate::_q_handlerDestroyed);
QTextObjectHandler h; QTextObjectHandler h;
h.iface = iface; h.iface = iface;
@ -456,7 +457,8 @@ void QAbstractTextDocumentLayout::unregisterHandler(int objectType, QObject *com
const auto it = d->handlers.constFind(objectType); const auto it = d->handlers.constFind(objectType);
if (it != d->handlers.cend() && (!component || component == it->component)) { if (it != d->handlers.cend() && (!component || component == it->component)) {
if (component) if (component)
disconnect(component, SIGNAL(destroyed(QObject*)), this, SLOT(_q_handlerDestroyed(QObject*))); QObjectPrivate::disconnect(component, &QObject::destroyed, d,
&QAbstractTextDocumentLayoutPrivate::_q_handlerDestroyed);
d->handlers.erase(it); d->handlers.erase(it);
} }
} }

View File

@ -129,7 +129,6 @@ private:
friend class QTextEngine; friend class QTextEngine;
friend class QTextLayout; friend class QTextLayout;
friend class QTextLine; friend class QTextLine;
Q_PRIVATE_SLOT(d_func(), void _q_handlerDestroyed(QObject *obj))
Q_PRIVATE_SLOT(d_func(), int _q_dynamicPageCountSlot()) Q_PRIVATE_SLOT(d_func(), int _q_dynamicPageCountSlot())
Q_PRIVATE_SLOT(d_func(), QSizeF _q_dynamicDocumentSizeSlot()) Q_PRIVATE_SLOT(d_func(), QSizeF _q_dynamicDocumentSizeSlot())
}; };

View File

@ -10399,16 +10399,16 @@ QWidgetTextControl *QGraphicsTextItemPrivate::textControl() const
control = new QWidgetTextControl(that); control = new QWidgetTextControl(that);
control->setTextInteractionFlags(Qt::NoTextInteraction); control->setTextInteractionFlags(Qt::NoTextInteraction);
QObject::connect(control, SIGNAL(updateRequest(QRectF)), QObject::connect(control, &QWidgetTextControl::updateRequest, qq,
qq, SLOT(_q_update(QRectF))); [dd = that->dd](const QRectF &rect) { dd->_q_update(rect); });
QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), QObject::connect(control, &QWidgetTextControl::documentSizeChanged, qq,
qq, SLOT(_q_updateBoundingRect(QSizeF))); [dd = that->dd](QSizeF size) { dd->_q_updateBoundingRect(size); });
QObject::connect(control, SIGNAL(visibilityRequest(QRectF)), QObject::connect(control, &QWidgetTextControl::visibilityRequest, qq,
qq, SLOT(_q_ensureVisible(QRectF))); [dd = that->dd](const QRectF &rect) { dd->_q_ensureVisible(rect); });
QObject::connect(control, SIGNAL(linkActivated(QString)), QObject::connect(control, &QWidgetTextControl::linkActivated, qq,
qq, SIGNAL(linkActivated(QString))); &QGraphicsTextItem::linkActivated);
QObject::connect(control, SIGNAL(linkHovered(QString)), QObject::connect(control, &QWidgetTextControl::linkHovered, qq,
qq, SIGNAL(linkHovered(QString))); &QGraphicsTextItem::linkHovered);
const QSizeF pgSize = control->document()->pageSize(); const QSizeF pgSize = control->document()->pageSize();
if (pgSize.height() != -1) { if (pgSize.height() != -1) {

View File

@ -941,9 +941,6 @@ protected:
private: private:
Q_DISABLE_COPY(QGraphicsTextItem) Q_DISABLE_COPY(QGraphicsTextItem)
Q_PRIVATE_SLOT(dd, void _q_updateBoundingRect(const QSizeF &))
Q_PRIVATE_SLOT(dd, void _q_update(QRectF))
Q_PRIVATE_SLOT(dd, void _q_ensureVisible(QRectF))
QGraphicsTextItemPrivate *dd; QGraphicsTextItemPrivate *dd;
friend class QGraphicsTextItemPrivate; friend class QGraphicsTextItemPrivate;
}; };

View File

@ -458,15 +458,20 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
// #### doc->documentLayout()->setPaintDevice(viewport); // #### doc->documentLayout()->setPaintDevice(viewport);
QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection())); QObjectPrivate::connect(doc, &QTextDocument::contentsChanged, this,
QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor))); &QWidgetTextControlPrivate::_q_updateCurrentCharFormatAndSelection);
QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged())); QObjectPrivate::connect(doc, &QTextDocument::cursorPositionChanged, this,
&QWidgetTextControlPrivate::_q_emitCursorPosChanged);
QObjectPrivate::connect(doc, &QTextDocument::documentLayoutChanged, this,
&QWidgetTextControlPrivate::_q_documentLayoutChanged);
// convenience signal forwards // convenience signal forwards
QObject::connect(doc, SIGNAL(undoAvailable(bool)), q, SIGNAL(undoAvailable(bool))); QObject::connect(doc, &QTextDocument::undoAvailable, q, &QWidgetTextControl::undoAvailable);
QObject::connect(doc, SIGNAL(redoAvailable(bool)), q, SIGNAL(redoAvailable(bool))); QObject::connect(doc, &QTextDocument::redoAvailable, q, &QWidgetTextControl::redoAvailable);
QObject::connect(doc, SIGNAL(modificationChanged(bool)), q, SIGNAL(modificationChanged(bool))); QObject::connect(doc, &QTextDocument::modificationChanged, q,
QObject::connect(doc, SIGNAL(blockCountChanged(int)), q, SIGNAL(blockCountChanged(int))); &QWidgetTextControl::modificationChanged);
QObject::connect(doc, &QTextDocument::blockCountChanged, q,
&QWidgetTextControl::blockCountChanged);
} }
bool previousUndoRedoState = doc->isUndoRedoEnabled(); bool previousUndoRedoState = doc->isUndoRedoEnabled();
@ -528,7 +533,8 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
q->ensureCursorVisible(); q->ensureCursorVisible();
emit q->cursorPositionChanged(); emit q->cursorPositionChanged();
QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)), Qt::UniqueConnection); QObjectPrivate::connect(doc, &QTextDocument::contentsChange, this,
&QWidgetTextControlPrivate::_q_contentsChanged, Qt::UniqueConnection);
} }
void QWidgetTextControlPrivate::startDrag() void QWidgetTextControlPrivate::startDrag()
@ -708,10 +714,12 @@ void QWidgetTextControlPrivate::_q_documentLayoutChanged()
{ {
Q_Q(QWidgetTextControl); Q_Q(QWidgetTextControl);
QAbstractTextDocumentLayout *layout = doc->documentLayout(); QAbstractTextDocumentLayout *layout = doc->documentLayout();
QObject::connect(layout, SIGNAL(update(QRectF)), q, SIGNAL(updateRequest(QRectF))); QObject::connect(layout, &QAbstractTextDocumentLayout::update, q,
QObject::connect(layout, SIGNAL(updateBlock(QTextBlock)), q, SLOT(_q_updateBlock(QTextBlock))); &QWidgetTextControl::updateRequest);
QObject::connect(layout, SIGNAL(documentSizeChanged(QSizeF)), q, SIGNAL(documentSizeChanged(QSizeF))); QObjectPrivate::connect(layout, &QAbstractTextDocumentLayout::updateBlock, this,
&QWidgetTextControlPrivate::_q_updateBlock);
QObject::connect(layout, &QAbstractTextDocumentLayout::documentSizeChanged, q,
&QWidgetTextControl::documentSizeChanged);
} }
void QWidgetTextControlPrivate::setCursorVisible(bool visible) void QWidgetTextControlPrivate::setCursorVisible(bool visible)

View File

@ -276,13 +276,8 @@ protected:
private: private:
Q_DISABLE_COPY_MOVE(QWidgetTextControl) Q_DISABLE_COPY_MOVE(QWidgetTextControl)
Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentCharFormatAndSelection())
Q_PRIVATE_SLOT(d_func(), void _q_emitCursorPosChanged(const QTextCursor &))
Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected()) Q_PRIVATE_SLOT(d_func(), void _q_deleteSelected())
Q_PRIVATE_SLOT(d_func(), void _q_copyLink()) Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int))
}; };

View File

@ -57,6 +57,7 @@ private slots:
void scale(); void scale();
void shear(); void shear();
void translate(); void translate();
void createTextItem();
}; };
tst_QGraphicsItem::tst_QGraphicsItem() tst_QGraphicsItem::tst_QGraphicsItem()
@ -230,5 +231,15 @@ void tst_QGraphicsItem::translate()
} }
} }
void tst_QGraphicsItem::createTextItem()
{
// Ensure QFontDatabase loaded the font beforehand
QFontInfo(qApp->font()).family();
const QString text = "This is some text";
QBENCHMARK {
QGraphicsTextItem item(text);
}
}
QTEST_MAIN(tst_QGraphicsItem) QTEST_MAIN(tst_QGraphicsItem)
#include "tst_qgraphicsitem.moc" #include "tst_qgraphicsitem.moc"