QQuickDeliveryAgentPrivate: fix performance regression in eventTargets()
a89a34463b
introduced a predicate
parameter to eventTargets. The problem is that it is passed by
std::function copy. Since eventTargets is called recursively it can
easily, in a heavy scene, lead to hundreds of allocation + deallocations
for each single event handling.
Pass the predicate as a (qxp::)function_ref to fix this.
Since function_ref has reference semantics, we cannot inititalize it
with nullptr anymore. So define a noop predicate for the
contextMenuTargets() case.
Pick-to: 6.9
Change-Id: I6a3162b9b76b197bba07c1725ac7768c8883818b
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
parent
e5d916b00c
commit
a62ef0f62e
|
@ -2077,7 +2077,7 @@ void QQuickDeliveryAgentPrivate::deliverPointerEvent(QPointerEvent *event)
|
|||
*/
|
||||
// FIXME: should this be iterative instead of recursive?
|
||||
QVector<QQuickItem *> QQuickDeliveryAgentPrivate::eventTargets(QQuickItem *item, const QEvent *event, QPointF scenePos,
|
||||
std::function<std::optional<bool>(QQuickItem *item, const QEvent *event)> predicate) const
|
||||
qxp::function_ref<std::optional<bool> (QQuickItem *, const QEvent *)> predicate) const
|
||||
{
|
||||
QVector<QQuickItem *> targets;
|
||||
auto itemPrivate = QQuickItemPrivate::get(item);
|
||||
|
@ -2089,13 +2089,9 @@ QVector<QQuickItem *> QQuickDeliveryAgentPrivate::eventTargets(QQuickItem *item,
|
|||
return targets;
|
||||
}
|
||||
QList<QQuickItem *> children = itemPrivate->paintOrderChildItems();
|
||||
if (predicate) {
|
||||
const auto override = predicate(item, event);
|
||||
if (override == true)
|
||||
relevant = true;
|
||||
else if (override == false)
|
||||
relevant = false;
|
||||
}
|
||||
const std::optional<bool> override = predicate(item, event);
|
||||
if (override.has_value())
|
||||
relevant = override.value();
|
||||
if (relevant) {
|
||||
auto it = std::lower_bound(children.begin(), children.end(), 0,
|
||||
[](auto lhs, auto rhs) -> bool { return lhs->z() < rhs; });
|
||||
|
@ -2940,7 +2936,11 @@ bool QQuickDeliveryAgentPrivate::dragOverThreshold(QVector2D delta)
|
|||
*/
|
||||
QVector<QQuickItem *> QQuickDeliveryAgentPrivate::contextMenuTargets(QQuickItem *item, const QContextMenuEvent *event) const
|
||||
{
|
||||
return eventTargets(item, event, event->pos(), nullptr);
|
||||
auto predicate = [](QQuickItem *, const QEvent *) -> std::optional<bool> {
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
return eventTargets(item, event, event->pos(), predicate);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <QtQuick/private/qquickdeliveryagent_p.h>
|
||||
#include <QtGui/qevent.h>
|
||||
#include <QtCore/qstack.h>
|
||||
#include <QtCore/qxpfunctional.h>
|
||||
|
||||
#include <private/qevent_p.h>
|
||||
#include <private/qpointingdevice_p.h>
|
||||
|
@ -166,7 +167,7 @@ public:
|
|||
void deliverUpdatedPoints(QPointerEvent *event);
|
||||
void deliverMatchingPointsToItem(QQuickItem *item, bool isGrabber, QPointerEvent *pointerEvent, bool handlersOnly = false);
|
||||
|
||||
QVector<QQuickItem *> eventTargets(QQuickItem *, const QEvent *event, QPointF scenePos, std::function<std::optional<bool> (QQuickItem *, const QEvent *)> predicate) const;
|
||||
QVector<QQuickItem *> eventTargets(QQuickItem *, const QEvent *event, QPointF scenePos, qxp::function_ref<std::optional<bool> (QQuickItem *, const QEvent *)> predicate) const;
|
||||
QVector<QQuickItem *> pointerTargets(QQuickItem *, const QPointerEvent *event, const QEventPoint &point,
|
||||
bool checkMouseButtons, bool checkAcceptsTouch) const;
|
||||
QVector<QQuickItem *> mergePointerTargets(const QVector<QQuickItem *> &list1, const QVector<QQuickItem *> &list2) const;
|
||||
|
|
Loading…
Reference in New Issue