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)
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;
h.iface = iface;
@ -456,7 +457,8 @@ void QAbstractTextDocumentLayout::unregisterHandler(int objectType, QObject *com
const auto it = d->handlers.constFind(objectType);
if (it != d->handlers.cend() && (!component || component == it->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);
}
}

View File

@ -129,7 +129,6 @@ private:
friend class QTextEngine;
friend class QTextLayout;
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(), QSizeF _q_dynamicDocumentSizeSlot())
};

View File

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

View File

@ -941,9 +941,6 @@ protected:
private:
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;
friend class QGraphicsTextItemPrivate;
};

View File

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

View File

@ -276,13 +276,8 @@ protected:
private:
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_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 shear();
void translate();
void createTextItem();
};
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)
#include "tst_qgraphicsitem.moc"