diff options
author | Robin Burchell <robin.burchell@viroteck.net> | 2014-10-15 14:13:53 +0200 |
---|---|---|
committer | Robin Burchell <robin.burchell@viroteck.net> | 2014-10-29 22:25:48 +0100 |
commit | 4b73acd49cc4f08a5169efba8169f968094063e0 (patch) | |
tree | 38db09cd6bc7bc017d500c237e5d11ed7258bc00 /src/quick/items | |
parent | aed97ab52133a06f998bf481be2b0d08b2107185 (diff) |
Move from a count of cursors, to storing whether or not a subtree has a cursor.
Calculation of this is going to be slower (of course) as we have to recurse the
children, but this only happens when unsetting a cursor or removing a child item
from a tree that had a cursor.
On the other hand, wasting 4 bytes per ExtraData plus padding is quite a large
concern, and it was also forcing allocation of ExtraData for an entire tree that
had a cursor set.
This also reduces the size of ExtraData from 152 down to 144 bytes through
reordering of members on x86_64.
Change-Id: Iab14ee71c762285bf4448fc86399070263eb118d
Reviewed-by: Gunnar Sletta <gunnar@sletta.org>
Diffstat (limited to 'src/quick/items')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 39 | ||||
-rw-r--r-- | src/quick/items/qquickitem_p.h | 8 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 5 |
3 files changed, 33 insertions, 19 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index b68a9b5455..3aff1f0dfc 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2722,8 +2722,11 @@ void QQuickItemPrivate::addChild(QQuickItem *child) #ifndef QT_NO_CURSOR QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); - if (childPrivate->extra.isAllocated()) - incrementCursorCount(childPrivate->extra.value().numItemsWithCursor); + + // if the added child has a cursor and we do not currently have any children + // with cursors, bubble the notification up + if (childPrivate->hasCursorInChild && !hasCursorInChild) + setHasCursorInChild(true); #endif markSortedChildrenDirty(child); @@ -2745,8 +2748,10 @@ void QQuickItemPrivate::removeChild(QQuickItem *child) #ifndef QT_NO_CURSOR QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(child); - if (childPrivate->extra.isAllocated()) - incrementCursorCount(-childPrivate->extra.value().numItemsWithCursor); + + // turn it off, if nothing else is using it + if (childPrivate->hasCursorInChild && hasCursorInChild) + setHasCursorInChild(false); #endif markSortedChildrenDirty(child); @@ -2948,6 +2953,7 @@ QQuickItemPrivate::QQuickItemPrivate() , isAccessible(false) , culled(false) , hasCursor(false) + , hasCursorInChild(false) , activeFocusOnTab(false) , implicitAntialiasing(false) , antialiasingValid(false) @@ -6731,15 +6737,27 @@ void QQuickItem::setAcceptHoverEvents(bool enabled) d->hoverEnabled = enabled; } -void QQuickItemPrivate::incrementCursorCount(int delta) +void QQuickItemPrivate::setHasCursorInChild(bool hasCursor) { #ifndef QT_NO_CURSOR Q_Q(QQuickItem); - extra.value().numItemsWithCursor += delta; + + // if we're asked to turn it off (because of an unsetcursor call, or a node + // removal) then we should check our children and make sure it's really ok + // to turn it off. + if (!hasCursor && hasCursorInChild) { + foreach (QQuickItem *otherChild, childItems) { + QQuickItemPrivate *otherChildPrivate = QQuickItemPrivate::get(otherChild); + if (otherChildPrivate->hasCursorInChild) + return; // nope! sorry, something else wants it kept on. + } + } + + hasCursorInChild = hasCursor; QQuickItem *parent = q->parentItem(); if (parent) { QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent); - parentPrivate->incrementCursorCount(delta); + parentPrivate->setHasCursorInChild(hasCursor); } #endif } @@ -6802,7 +6820,7 @@ void QQuickItem::setCursor(const QCursor &cursor) } if (!d->hasCursor) { - d->incrementCursorCount(+1); + d->setHasCursorInChild(true); d->hasCursor = true; if (d->window) { QWindow *renderWindow = QQuickRenderControl::renderWindowFor(d->window); @@ -6825,7 +6843,7 @@ void QQuickItem::unsetCursor() Q_D(QQuickItem); if (!d->hasCursor) return; - d->incrementCursorCount(-1); + d->setHasCursorInChild(false); d->hasCursor = false; if (d->extra.isAllocated()) d->extra->cursor = QCursor(); @@ -7807,9 +7825,6 @@ QQuickItemPrivate::ExtraData::ExtraData() : z(0), scale(1), rotation(0), opacity(1), contents(0), screenAttached(0), layoutDirectionAttached(0), keyHandler(0), layer(0), -#ifndef QT_NO_CURSOR - numItemsWithCursor(0), -#endif effectRefCount(0), hideRefCount(0), opacityNode(0), clipNode(0), rootNode(0), acceptedMouseButtons(0), origin(QQuickItem::Center), diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 2ae67c4c23..461b2f3485 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -342,7 +342,6 @@ public: mutable QQuickItemLayer *layer; #ifndef QT_NO_CURSOR QCursor cursor; - int numItemsWithCursor; #endif QPointF userTransformOriginPoint; @@ -353,6 +352,8 @@ public: QQuickDefaultClipNode *clipNode; QSGRootNode *rootNode; + QObjectList resourcesList; + // Although acceptedMouseButtons is inside ExtraData, we actually store // the LeftButton flag in the extra.flag() bit. This is because it is // extremely common to set acceptedMouseButtons to LeftButton, but very @@ -362,7 +363,7 @@ public: QQuickItem::TransformOrigin origin:5; uint transparentForPositioner : 1; - QObjectList resourcesList; + // 26 bits padding }; QLazilyAllocated<ExtraData> extra; @@ -414,6 +415,7 @@ public: bool culled:1; bool hasCursor:1; // Bit 32 + bool hasCursorInChild:1; bool activeFocusOnTab:1; bool implicitAntialiasing:1; bool antialiasingValid:1; @@ -576,7 +578,7 @@ public: virtual void mirrorChange() {} - void incrementCursorCount(int delta); + void setHasCursorInChild(bool hasCursor); // recursive helper to let a visual parent mark its visual children void markObjects(QV4::ExecutionEngine *e); diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index c7dde6d4aa..8bd6adca94 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -2277,10 +2277,7 @@ QQuickItem *QQuickWindowPrivate::findCursorItem(QQuickItem *item, const QPointF return 0; } - const int numCursorsInHierarchy = itemPrivate->extra.isAllocated() ? itemPrivate->extra.value().numItemsWithCursor : 0; - const int numChildrenWithCursor = itemPrivate->hasCursor ? numCursorsInHierarchy-1 : numCursorsInHierarchy; - - if (numChildrenWithCursor > 0) { + if (itemPrivate->hasCursorInChild) { QList<QQuickItem *> children = itemPrivate->paintOrderChildItems(); for (int ii = children.count() - 1; ii >= 0; --ii) { QQuickItem *child = children.at(ii); |