Reduce size of QQuickItemPrivate
authorAaron Kennedy <aaron.kennedy@nokia.com>
Mon, 13 Feb 2012 14:42:34 +0000 (14:42 +0000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 21 Feb 2012 09:56:27 +0000 (10:56 +0100)
Change-Id: I02653536f68cfef3dfc06acaf30e2565a97dc194
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
src/quick/designer/designersupport.cpp
src/quick/items/qquickanchors_p_p.h
src/quick/items/qquickcanvas.cpp
src/quick/items/qquickitem.cpp
src/quick/items/qquickitem_p.h
src/quick/items/qquickmousearea.cpp
src/quick/items/qquickscreen.cpp

index eb371a1..d500e0a 100644 (file)
@@ -75,13 +75,13 @@ void DesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool hide)
     QQuickItemPrivate::get(referencedItem)->refFromEffectItem(hide);
     QQuickCanvasPrivate::get(referencedItem->canvas())->updateDirtyNode(referencedItem);
 
-    Q_ASSERT(QQuickItemPrivate::get(referencedItem)->rootNode);
+    Q_ASSERT(QQuickItemPrivate::get(referencedItem)->rootNode());
 
     if (!m_itemTextureHash.contains(referencedItem)) {
         QQuickShaderEffectTexture *texture = new QQuickShaderEffectTexture(referencedItem);
 
         texture->setLive(true);
-        texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode);
+        texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode());
         texture->setRect(referencedItem->boundingRect());
         texture->setSize(referencedItem->boundingRect().size().toSize());
         texture->setRecursive(true);
index 144e130..b2b5879 100644 (file)
@@ -62,8 +62,6 @@ QT_BEGIN_NAMESPACE
 class QQuickAnchorLine
 {
 public:
-    QQuickAnchorLine() : item(0), anchorLine(Invalid) {}
-
     enum AnchorLine {
         Invalid = 0x0,
         Left = 0x01,
@@ -77,6 +75,9 @@ public:
         Vertical_Mask = Top | Bottom | VCenter | Baseline
     };
 
+    QQuickAnchorLine() : item(0), anchorLine(Invalid) {}
+    QQuickAnchorLine(QQuickItem *i, AnchorLine l) : item(i), anchorLine(l) {}
+
     QQuickItem *item;
     AnchorLine anchorLine;
 };
index dcac822..a9df484 100644 (file)
@@ -893,7 +893,7 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
     Q_Q(QQuickCanvas);
 
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
+    if (itemPrivate->opacity() == 0.0)
         return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
@@ -911,7 +911,7 @@ bool QQuickCanvasPrivate::deliverInitialMousePressEvent(QQuickItem *item, QMouse
             return true;
     }
 
-    if (itemPrivate->acceptedMouseButtons & event->button()) {
+    if (itemPrivate->acceptedMouseButtons() & event->button()) {
         QPointF p = item->mapFromScene(event->windowPos());
         if (QRectF(0, 0, item->width(), item->height()).contains(p)) {
             QMouseEvent me(event->type(), p, event->windowPos(), event->screenPos(),
@@ -1063,7 +1063,7 @@ bool QQuickCanvasPrivate::deliverHoverEvent(QQuickItem *item, const QPointF &sce
                                          Qt::KeyboardModifiers modifiers, bool &accepted)
 {
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
+    if (itemPrivate->opacity() == 0.0)
         return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
@@ -1131,7 +1131,7 @@ bool QQuickCanvasPrivate::deliverWheelEvent(QQuickItem *item, QWheelEvent *event
 {
     Q_Q(QQuickCanvas);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
+    if (itemPrivate->opacity() == 0.0)
         return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
@@ -1266,7 +1266,7 @@ bool QQuickCanvasPrivate::deliverTouchPoints(QQuickItem *item, QTouchEvent *even
     Q_Q(QQuickCanvas);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
 
-    if (itemPrivate->opacity == 0.0)
+    if (itemPrivate->opacity() == 0.0)
         return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
@@ -1426,7 +1426,7 @@ bool QQuickCanvasPrivate::deliverDragEvent(QQuickDragGrabber *grabber, QQuickIte
     Q_Q(QQuickCanvas);
     bool accepted = false;
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0 || !item->isVisible() || !item->isEnabled())
+    if (itemPrivate->opacity() == 0.0 || !item->isVisible() || !item->isEnabled())
         return false;
 
     QPointF p = item->mapFromScene(event->pos());
@@ -1568,8 +1568,12 @@ void QQuickCanvasPrivate::cleanupNodesOnShutdown(QQuickItem *item)
     if (p->itemNodeInstance) {
         delete p->itemNodeInstance;
         p->itemNodeInstance = 0;
-        p->opacityNode = 0;
-        p->clipNode = 0;
+
+        if (p->extra.isAllocated()) {
+            p->extra->opacityNode = 0;
+            p->extra->clipNode = 0;
+        }
+
         p->groupNode = 0;
         p->paintNode = 0;
     }
@@ -1623,8 +1627,8 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
     itemPriv->dirtyAttributes = 0;
 
     if ((dirty & QQuickItemPrivate::TransformUpdateMask) ||
-        (dirty & QQuickItemPrivate::Size && itemPriv->origin != QQuickItem::TopLeft &&
-         (itemPriv->scale != 1. || itemPriv->rotation != 0.))) {
+        (dirty & QQuickItemPrivate::Size && itemPriv->origin() != QQuickItem::TopLeft &&
+         (itemPriv->scale() != 1. || itemPriv->rotation() != 0.))) {
 
         QMatrix4x4 matrix;
 
@@ -1634,13 +1638,13 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
         for (int ii = itemPriv->transforms.count() - 1; ii >= 0; --ii)
             itemPriv->transforms.at(ii)->applyTo(&matrix);
 
-        if (itemPriv->scale != 1. || itemPriv->rotation != 0.) {
+        if (itemPriv->scale() != 1. || itemPriv->rotation() != 0.) {
             QPointF origin = item->transformOriginPoint();
             matrix.translate(origin.x(), origin.y());
-            if (itemPriv->scale != 1.)
-                matrix.scale(itemPriv->scale, itemPriv->scale);
-            if (itemPriv->rotation != 0.)
-                matrix.rotate(itemPriv->rotation, 0, 0, 1);
+            if (itemPriv->scale() != 1.)
+                matrix.scale(itemPriv->scale(), itemPriv->scale());
+            if (itemPriv->rotation() != 0.)
+                matrix.rotate(itemPriv->rotation(), 0, 0, 1);
             matrix.translate(-origin.x(), -origin.y());
         }
 
@@ -1648,32 +1652,35 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
     }
 
     bool clipEffectivelyChanged = (dirty & (QQuickItemPrivate::Clip | QQuickItemPrivate::Canvas)) &&
-                                  ((item->clip() == false) != (itemPriv->clipNode == 0));
+                                  ((item->clip() == false) != (itemPriv->clipNode() == 0));
+    int effectRefCount = itemPriv->extra.isAllocated()?itemPriv->extra->effectRefCount:0;
     bool effectRefEffectivelyChanged = (dirty & (QQuickItemPrivate::EffectReference | QQuickItemPrivate::Canvas)) &&
-                                  ((itemPriv->effectRefCount == 0) != (itemPriv->rootNode == 0));
+                                  ((effectRefCount == 0) != (itemPriv->rootNode() == 0));
 
     if (clipEffectivelyChanged) {
-        QSGNode *parent = itemPriv->opacityNode ? (QSGNode *) itemPriv->opacityNode : (QSGNode *)itemPriv->itemNode();
-        QSGNode *child = itemPriv->rootNode ? (QSGNode *)itemPriv->rootNode : (QSGNode *)itemPriv->groupNode;
+        QSGNode *parent = itemPriv->opacityNode() ? (QSGNode *) itemPriv->opacityNode() :
+                                                    (QSGNode *)itemPriv->itemNode();
+        QSGNode *child = itemPriv->rootNode() ? (QSGNode *)itemPriv->rootNode() :
+                                                (QSGNode *)itemPriv->groupNode;
 
         if (item->clip()) {
-            Q_ASSERT(itemPriv->clipNode == 0);
-            itemPriv->clipNode = new QQuickDefaultClipNode(item->boundingRect());
-            itemPriv->clipNode->update();
+            Q_ASSERT(itemPriv->clipNode() == 0);
+            itemPriv->extra.value().clipNode = new QQuickDefaultClipNode(item->boundingRect());
+            itemPriv->clipNode()->update();
 
             if (child)
                 parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->clipNode);
+            parent->appendChildNode(itemPriv->clipNode());
             if (child)
-                itemPriv->clipNode->appendChildNode(child);
+                itemPriv->clipNode()->appendChildNode(child);
 
         } else {
-            Q_ASSERT(itemPriv->clipNode != 0);
-            parent->removeChildNode(itemPriv->clipNode);
+            Q_ASSERT(itemPriv->clipNode() != 0);
+            parent->removeChildNode(itemPriv->clipNode());
             if (child)
-                itemPriv->clipNode->removeChildNode(child);
-            delete itemPriv->clipNode;
-            itemPriv->clipNode = 0;
+                itemPriv->clipNode()->removeChildNode(child);
+            delete itemPriv->clipNode();
+            itemPriv->extra->clipNode = 0;
             if (child)
                 parent->appendChildNode(child);
         }
@@ -1683,29 +1690,29 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
         itemPriv->childContainerNode()->removeAllChildNodes();
 
     if (effectRefEffectivelyChanged) {
-        QSGNode *parent = itemPriv->clipNode;
+        QSGNode *parent = itemPriv->clipNode();
         if (!parent)
-            parent = itemPriv->opacityNode;
+            parent = itemPriv->opacityNode();
         if (!parent)
             parent = itemPriv->itemNode();
         QSGNode *child = itemPriv->groupNode;
 
-        if (itemPriv->effectRefCount) {
-            Q_ASSERT(itemPriv->rootNode == 0);
-            itemPriv->rootNode = new QSGRootNode;
+        if (itemPriv->extra.isAllocated() && itemPriv->extra->effectRefCount) {
+            Q_ASSERT(itemPriv->rootNode() == 0);
+            itemPriv->extra->rootNode = new QSGRootNode;
 
             if (child)
                 parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->rootNode);
+            parent->appendChildNode(itemPriv->rootNode());
             if (child)
-                itemPriv->rootNode->appendChildNode(child);
+                itemPriv->rootNode()->appendChildNode(child);
         } else {
-            Q_ASSERT(itemPriv->rootNode != 0);
-            parent->removeChildNode(itemPriv->rootNode);
+            Q_ASSERT(itemPriv->rootNode() != 0);
+            parent->removeChildNode(itemPriv->rootNode());
             if (child)
-                itemPriv->rootNode->removeChildNode(child);
-            delete itemPriv->rootNode;
-            itemPriv->rootNode = 0;
+                itemPriv->rootNode()->removeChildNode(child);
+            delete itemPriv->rootNode();
+            itemPriv->extra->rootNode = 0;
             if (child)
                 parent->appendChildNode(child);
         }
@@ -1721,21 +1728,26 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
 
         for (; ii < orderedChildren.count() && orderedChildren.at(ii)->z() < 0; ++ii) {
             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
-            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
+            if (!childPrivate->explicitVisible &&
+                (!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
                 continue;
             if (childPrivate->itemNode()->parent())
                 childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
 
             itemPriv->childContainerNode()->appendChildNode(childPrivate->itemNode());
         }
-        itemPriv->beforePaintNode = itemPriv->groupNode ? itemPriv->groupNode->lastChild() : 0;
+
+        QSGNode *beforePaintNode = itemPriv->groupNode ? itemPriv->groupNode->lastChild() : 0;
+        if (beforePaintNode || itemPriv->extra.isAllocated())
+            itemPriv->extra.value().beforePaintNode = beforePaintNode;
 
         if (itemPriv->paintNode)
             itemPriv->childContainerNode()->appendChildNode(itemPriv->paintNode);
 
         for (; ii < orderedChildren.count(); ++ii) {
             QQuickItemPrivate *childPrivate = QQuickItemPrivate::get(orderedChildren.at(ii));
-            if (!childPrivate->explicitVisible && !childPrivate->effectRefCount)
+            if (!childPrivate->explicitVisible &&
+                (!childPrivate->extra.isAllocated() || !childPrivate->extra->effectRefCount))
                 continue;
             if (childPrivate->itemNode()->parent())
                 childPrivate->itemNode()->parent()->removeChildNode(childPrivate->itemNode());
@@ -1744,35 +1756,35 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
         }
     }
 
-    if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode) {
-        itemPriv->clipNode->setRect(item->boundingRect());
-        itemPriv->clipNode->update();
+    if ((dirty & QQuickItemPrivate::Size) && itemPriv->clipNode()) {
+        itemPriv->clipNode()->setRect(item->boundingRect());
+        itemPriv->clipNode()->update();
     }
 
     if (dirty & (QQuickItemPrivate::OpacityValue | QQuickItemPrivate::Visible
                  | QQuickItemPrivate::HideReference | QQuickItemPrivate::Canvas))
     {
-        qreal opacity = itemPriv->explicitVisible && itemPriv->hideRefCount == 0
-                      ? itemPriv->opacity : qreal(0);
+        qreal opacity = itemPriv->explicitVisible && (!itemPriv->extra.isAllocated() || itemPriv->extra->hideRefCount == 0)
+                      ? itemPriv->opacity() : qreal(0);
 
-        if (opacity != 1 && !itemPriv->opacityNode) {
-            itemPriv->opacityNode = new QSGOpacityNode;
+        if (opacity != 1 && !itemPriv->opacityNode()) {
+            itemPriv->extra.value().opacityNode = new QSGOpacityNode;
 
             QSGNode *parent = itemPriv->itemNode();
-            QSGNode *child = itemPriv->clipNode;
+            QSGNode *child = itemPriv->clipNode();
             if (!child)
-                child = itemPriv->rootNode;
+                child = itemPriv->rootNode();
             if (!child)
                 child = itemPriv->groupNode;
 
             if (child)
                 parent->removeChildNode(child);
-            parent->appendChildNode(itemPriv->opacityNode);
+            parent->appendChildNode(itemPriv->opacityNode());
             if (child)
-                itemPriv->opacityNode->appendChildNode(child);
+                itemPriv->opacityNode()->appendChildNode(child);
         }
-        if (itemPriv->opacityNode)
-            itemPriv->opacityNode->setOpacity(opacity);
+        if (itemPriv->opacityNode())
+            itemPriv->opacityNode()->setOpacity(opacity);
     }
 
     if (dirty & QQuickItemPrivate::ContentUpdateMask) {
@@ -1786,8 +1798,8 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
                      itemPriv->paintNode->parent() == itemPriv->childContainerNode());
 
             if (itemPriv->paintNode && itemPriv->paintNode->parent() == 0) {
-                if (itemPriv->beforePaintNode)
-                    itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, itemPriv->beforePaintNode);
+                if (itemPriv->extra.isAllocated() && itemPriv->extra->beforePaintNode)
+                    itemPriv->childContainerNode()->insertChildNodeAfter(itemPriv->paintNode, itemPriv->extra->beforePaintNode);
                 else
                     itemPriv->childContainerNode()->prependChildNode(itemPriv->paintNode);
             }
@@ -1806,9 +1818,9 @@ void QQuickCanvasPrivate::updateDirtyNode(QQuickItem *item)
     // Check consistency.
     const QSGNode *nodeChain[] = {
         itemPriv->itemNodeInstance,
-        itemPriv->opacityNode,
-        itemPriv->clipNode,
-        itemPriv->rootNode,
+        itemPriv->opacityNode(),
+        itemPriv->clipNode(),
+        itemPriv->rootNode(),
         itemPriv->groupNode,
         itemPriv->paintNode,
     };
index 889f054..04f4c1f 100644 (file)
@@ -442,8 +442,8 @@ QQuickItemKeyFilter::QQuickItemKeyFilter(QQuickItem *item)
 {
     QQuickItemPrivate *p = item?QQuickItemPrivate::get(item):0;
     if (p) {
-        m_next = p->keyHandler;
-        p->keyHandler = this;
+        m_next = p->extra.value().keyHandler;
+        p->extra->keyHandler = this;
     }
 }
 
@@ -1505,7 +1505,7 @@ QQuickLayoutMirroringAttached::QQuickLayoutMirroringAttached(QObject *parent) :
 {
     if (QQuickItem *item = qobject_cast<QQuickItem*>(parent)) {
         itemPrivate = QQuickItemPrivate::get(item);
-        itemPrivate->attachedLayoutDirection = this;
+        itemPrivate->extra.value().layoutDirectionAttached = this;
     } else
         qmlInfo(parent) << tr("LayoutDirection attached property only works with Items");
 }
@@ -1598,8 +1598,8 @@ void QQuickItemPrivate::setLayoutMirror(bool mirror)
             emit _anchors->mirroredChanged();
         }
         mirrorChange();
-        if (attachedLayoutDirection) {
-            emit attachedLayoutDirection->enabledChanged();
+        if (extra.isAllocated() && extra->layoutDirectionAttached) {
+            emit extra->layoutDirectionAttached->enabledChanged();
         }
     }
 }
@@ -1824,11 +1824,14 @@ QQuickItem::~QQuickItem()
     }
 
     d->changeListeners.clear();
-    delete d->_anchorLines; d->_anchorLines = 0;
+
+    if (d->extra.isAllocated()) {
+        delete d->extra->contents; d->extra->contents = 0;
+        delete d->extra->layer; d->extra->layer = 0;
+    }
+
     delete d->_anchors; d->_anchors = 0;
     delete d->_stateGroup; d->_stateGroup = 0;
-    delete d->_contents; d->_contents = 0;
-    delete d->_layer;
 }
 
 /*!
@@ -2055,7 +2058,7 @@ QList<QQuickItem *> QQuickItemPrivate::paintOrderChildItems() const
     // the childItems list.  This is by far the most common case.
     bool haveZ = false;
     for (int i = 0; i < childItems.count(); ++i) {
-        if (QQuickItemPrivate::get(childItems.at(i))->z != 0.) {
+        if (QQuickItemPrivate::get(childItems.at(i))->z() != 0.) {
             haveZ = true;
             break;
         }
@@ -2150,12 +2153,16 @@ void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
         QQuickCanvasPrivate::get(canvas)->itemsToPolish.insert(q);
 
     itemNodeInstance = 0;
-    opacityNode = 0;
-    clipNode = 0;
-    rootNode = 0;
+
+    if (extra.isAllocated()) {
+        extra->opacityNode = 0;
+        extra->clipNode = 0;
+        extra->rootNode = 0;
+        extra->beforePaintNode = 0;
+    }
+
     groupNode = 0;
     paintNode = 0;
-    beforePaintNode = 0;
 
     InitializationState _dummy;
     InitializationState *childState = state;
@@ -2185,8 +2192,8 @@ void QQuickItemPrivate::initCanvas(InitializationState *state, QQuickCanvas *c)
 
     dirty(Canvas);
 
-    if (screenAttached)
-        screenAttached->canvasChanged(c);
+    if (extra.isAllocated() && extra->screenAttached)
+        extra->screenAttached->canvasChanged(c);
     itemChange(QQuickItem::ItemSceneChange, c);
 }
 
@@ -2225,11 +2232,11 @@ void QQuickItemPrivate::itemToParentTransform(QTransform &t) const
         t = m.toTransform();
     }
 
-    if (scale != 1. || rotation != 0.) {
+    if (scale() != 1. || rotation() != 0.) {
         QPointF tp = computeTransformOrigin();
         t.translate(tp.x(), tp.y());
-        t.scale(scale, scale);
-        t.rotate(rotation);
+        t.scale(scale(), scale());
+        t.rotate(rotation());
         t.translate(-tp.x(), -tp.y());
     }
 }
@@ -2290,9 +2297,8 @@ bool QQuickItem::isComponentComplete() const
 }
 
 QQuickItemPrivate::QQuickItemPrivate()
-: _anchors(0), _contents(0), baselineOffset(0), _anchorLines(0), _stateGroup(0), origin(QQuickItem::Center),
-
-  flags(0), widthValid(false), heightValid(false), componentComplete(true),
+: _anchors(0), _stateGroup(0),
+  flags(0), widthValid(false), heightValid(false), baselineOffsetValid(false), componentComplete(true),
   keepMouse(false), keepTouch(false), hoverEnabled(false), smooth(false), focus(false), activeFocus(false), notifiedFocus(false),
   notifiedActiveFocus(false), filtersChildMouseEvents(false), explicitVisible(true),
   effectiveVisible(true), explicitEnable(true), effectiveEnable(true), polishScheduled(false),
@@ -2301,22 +2307,17 @@ QQuickItemPrivate::QQuickItemPrivate()
   staticSubtreeGeometry(false),
   isAccessible(false),
 
+  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
+
   canvas(0), parentItem(0), sortedChildItems(&childItems),
 
   subFocusItem(0),
 
   x(0), y(0), width(0), height(0), implicitWidth(0), implicitHeight(0),
-  z(0), scale(1), rotation(0), opacity(1),
 
-  attachedLayoutDirection(0), acceptedMouseButtons(0),
-
-  keyHandler(0),
-
-  dirtyAttributes(0), nextDirtyItem(0), prevDirtyItem(0),
+  baselineOffset(0),
 
-  itemNodeInstance(0), opacityNode(0), clipNode(0), rootNode(0), groupNode(0), paintNode(0)
-  , beforePaintNode(0), effectRefCount(0), hideRefCount(0)
-  , screenAttached(0), _layer(0)
+  itemNodeInstance(0), groupNode(0), paintNode(0)
 {
 }
 
@@ -2341,7 +2342,7 @@ void QQuickItemPrivate::init(QQuickItem *parent)
 
     registerAccessorProperties();
 
-    baselineOffset.invalidate();
+    baselineOffsetValid = false;
 
     if (parent) {
         q->setParentItem(parent);
@@ -2529,7 +2530,9 @@ QQuickItem *QQuickItemPrivate::visibleChildren_at(QDeclarativeListProperty<QQuic
 int QQuickItemPrivate::transform_count(QDeclarativeListProperty<QQuickTransform> *prop)
 {
     QQuickItem *that = static_cast<QQuickItem *>(prop->object);
-    return QQuickItemPrivate::get(that)->transforms.count();
+    QQuickItemPrivate *p = QQuickItemPrivate::get(that);
+
+    return p->transforms.count();
 }
 
 void QQuickTransform::appendToItem(QQuickItem *item)
@@ -2838,14 +2841,6 @@ QQuickAnchors *QQuickItemPrivate::anchors() const
     return _anchors;
 }
 
-QQuickItemPrivate::AnchorLines *QQuickItemPrivate::anchorLines() const
-{
-    Q_Q(const QQuickItem);
-    if (!_anchorLines) _anchorLines =
-        new AnchorLines(const_cast<QQuickItem *>(q));
-    return _anchorLines;
-}
-
 void QQuickItemPrivate::siblingOrderChanged()
 {
     Q_Q(QQuickItem);
@@ -2868,12 +2863,12 @@ QDeclarativeListProperty<QObject> QQuickItemPrivate::data()
 QRectF QQuickItem::childrenRect()
 {
     Q_D(QQuickItem);
-    if (!d->_contents) {
-        d->_contents = new QQuickContents(this);
+    if (!d->extra.isAllocated() || !d->extra->contents) {
+        d->extra.value().contents = new QQuickContents(this);
         if (d->componentComplete)
-            d->_contents->complete();
+            d->extra->contents->complete();
     }
-    return d->_contents->rectF();
+    return d->extra->contents->rectF();
 }
 
 QList<QQuickItem *> QQuickItem::childItems() const
@@ -2971,6 +2966,11 @@ void QQuickItem::sendAccessibilityUpdate()
 {
 }
 
+void QQuickItemPrivate::addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
+{
+    changeListeners.append(ChangeListener(listener, types));
+}
+
 void QQuickItemPrivate::removeItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types)
 {
     ChangeListener change(listener, types);
@@ -2987,7 +2987,8 @@ void QQuickItemPrivate::updateOrAddGeometryChangeListener(QQuickItemChangeListen
         changeListeners.append(change);
 }
 
-void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types)
+void QQuickItemPrivate::updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener,
+                                                             GeometryChangeTypes types)
 {
     ChangeListener change(listener, types);
     if (types == NoChange) {
@@ -3130,8 +3131,8 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
     case Qt::ImMaximumTextLength:
     case Qt::ImAnchorPosition:
     case Qt::ImPreferredLanguage:
-        if (d->keyHandler)
-            v = d->keyHandler->inputMethodQuery(query);
+        if (d->extra.isAllocated() && d->extra->keyHandler)
+            v = d->extra->keyHandler->inputMethodQuery(query);
     default:
         break;
     }
@@ -3141,46 +3142,54 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
 
 QQuickAnchorLine QQuickItemPrivate::left() const
 {
-    return anchorLines()->left;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Left);
 }
 
 QQuickAnchorLine QQuickItemPrivate::right() const
 {
-    return anchorLines()->right;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Right);
 }
 
 QQuickAnchorLine QQuickItemPrivate::horizontalCenter() const
 {
-    return anchorLines()->hCenter;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::HCenter);
 }
 
 QQuickAnchorLine QQuickItemPrivate::top() const
 {
-    return anchorLines()->top;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Top);
 }
 
 QQuickAnchorLine QQuickItemPrivate::bottom() const
 {
-    return anchorLines()->bottom;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Bottom);
 }
 
 QQuickAnchorLine QQuickItemPrivate::verticalCenter() const
 {
-    return anchorLines()->vCenter;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::VCenter);
 }
 
 QQuickAnchorLine QQuickItemPrivate::baseline() const
 {
-    return anchorLines()->baseline;
+    Q_Q(const QQuickItem);
+    return QQuickAnchorLine(const_cast<QQuickItem *>(q), QQuickAnchorLine::Baseline);
 }
 
 qreal QQuickItem::baselineOffset() const
 {
     Q_D(const QQuickItem);
-    if (!d->baselineOffset.isValid()) {
-        return 0.0;
-    } else
+    if (d->baselineOffsetValid) {
         return d->baselineOffset;
+    } else {
+        return 0.0;
+    }
 }
 
 void QQuickItem::setBaselineOffset(qreal offset)
@@ -3190,6 +3199,7 @@ void QQuickItem::setBaselineOffset(qreal offset)
         return;
 
     d->baselineOffset = offset;
+    d->baselineOffsetValid = true;
 
     for (int ii = 0; ii < d->changeListeners.count(); ++ii) {
         const QQuickItemPrivate::ChangeListener &change = d->changeListeners.at(ii);
@@ -3404,8 +3414,8 @@ void QQuickItem::classBegin()
         d->_stateGroup->classBegin();
     if (d->_anchors)
         d->_anchors->classBegin();
-    if (d->_layer)
-        d->_layer->classBegin();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->classBegin();
 }
 
 void QQuickItem::componentComplete()
@@ -3419,13 +3429,14 @@ void QQuickItem::componentComplete()
         QQuickAnchorsPrivate::get(d->_anchors)->updateOnComplete();
     }
 
-    if (d->_layer)
-        d->_layer->componentComplete();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->componentComplete();
+
+    if (d->extra.isAllocated() && d->extra->keyHandler)
+        d->extra->keyHandler->componentComplete();
 
-    if (d->keyHandler)
-        d->keyHandler->componentComplete();
-    if (d->_contents)
-        d->_contents->complete();
+    if (d->extra.isAllocated() && d->extra->contents)
+        d->extra->contents->complete();
 }
 
 QDeclarativeStateGroup *QQuickItemPrivate::_states()
@@ -3442,27 +3453,9 @@ QDeclarativeStateGroup *QQuickItemPrivate::_states()
     return _stateGroup;
 }
 
-QQuickItemPrivate::AnchorLines::AnchorLines(QQuickItem *q)
-{
-    left.item = q;
-    left.anchorLine = QQuickAnchorLine::Left;
-    right.item = q;
-    right.anchorLine = QQuickAnchorLine::Right;
-    hCenter.item = q;
-    hCenter.anchorLine = QQuickAnchorLine::HCenter;
-    top.item = q;
-    top.anchorLine = QQuickAnchorLine::Top;
-    bottom.item = q;
-    bottom.anchorLine = QQuickAnchorLine::Bottom;
-    vCenter.item = q;
-    vCenter.anchorLine = QQuickAnchorLine::VCenter;
-    baseline.item = q;
-    baseline.anchorLine = QQuickAnchorLine::Baseline;
-}
-
 QPointF QQuickItemPrivate::computeTransformOrigin() const
 {
-    switch (origin) {
+    switch (origin()) {
     default:
     case QQuickItem::TopLeft:
         return QPointF(0, 0);
@@ -3487,8 +3480,8 @@ QPointF QQuickItemPrivate::computeTransformOrigin() const
 
 void QQuickItemPrivate::transformChanged()
 {
-    if (_layer)
-        _layer->updateMatrix();
+    if (extra.isAllocated() && extra->layer)
+        extra->layer->updateMatrix();
 }
 
 void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
@@ -3496,11 +3489,11 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
     Q_Q(QQuickItem);
 
     Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, false);
+            extra->keyHandler->keyPressed(e, false);
         else
-            keyHandler->keyReleased(e, false);
+            extra->keyHandler->keyReleased(e, false);
 
         if (e->isAccepted())
             return;
@@ -3516,13 +3509,13 @@ void QQuickItemPrivate::deliverKeyEvent(QKeyEvent *e)
     if (e->isAccepted())
         return;
 
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         e->accept();
 
         if (e->type() == QEvent::KeyPress)
-            keyHandler->keyPressed(e, true);
+            extra->keyHandler->keyPressed(e, true);
         else
-            keyHandler->keyReleased(e, true);
+            extra->keyHandler->keyReleased(e, true);
     }
 }
 
@@ -3531,8 +3524,8 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
     Q_Q(QQuickItem);
 
     Q_ASSERT(e->isAccepted());
-    if (keyHandler) {
-        keyHandler->inputMethodEvent(e, false);
+    if (extra.isAllocated() && extra->keyHandler) {
+        extra->keyHandler->inputMethodEvent(e, false);
 
         if (e->isAccepted())
             return;
@@ -3545,10 +3538,10 @@ void QQuickItemPrivate::deliverInputMethodEvent(QInputMethodEvent *e)
     if (e->isAccepted())
         return;
 
-    if (keyHandler) {
+    if (extra.isAllocated() && extra->keyHandler) {
         e->accept();
 
-        keyHandler->inputMethodEvent(e, true);
+        extra->keyHandler->inputMethodEvent(e, true);
     }
 }
 
@@ -3665,52 +3658,52 @@ QRectF QQuickItem::boundingRect() const
 QQuickItem::TransformOrigin QQuickItem::transformOrigin() const
 {
     Q_D(const QQuickItem);
-    return d->origin;
+    return d->origin();
 }
 
 void QQuickItem::setTransformOrigin(TransformOrigin origin)
 {
     Q_D(QQuickItem);
-    if (origin == d->origin)
+    if (origin == d->origin())
         return;
 
-    d->origin = origin;
+    d->extra.value().origin = origin;
     d->dirty(QQuickItemPrivate::TransformOrigin);
 
-    emit transformOriginChanged(d->origin);
+    emit transformOriginChanged(d->origin());
 }
 
 QPointF QQuickItem::transformOriginPoint() const
 {
     Q_D(const QQuickItem);
-    if (!d->transformOriginPoint.isNull())
-        return d->transformOriginPoint;
+    if (d->extra.isAllocated() && !d->extra->userTransformOriginPoint.isNull())
+        return d->extra->userTransformOriginPoint;
     return d->computeTransformOrigin();
 }
 
 void QQuickItem::setTransformOriginPoint(const QPointF &point)
 {
     Q_D(QQuickItem);
-    if (d->transformOriginPoint == point)
+    if (d->extra.value().userTransformOriginPoint == point)
         return;
 
-    d->transformOriginPoint = point;
+    d->extra->userTransformOriginPoint = point;
     d->dirty(QQuickItemPrivate::TransformOrigin);
 }
 
 qreal QQuickItem::z() const
 {
     Q_D(const QQuickItem);
-    return d->z;
+    return d->z();
 }
 
 void QQuickItem::setZ(qreal v)
 {
     Q_D(QQuickItem);
-    if (d->z == v)
+    if (d->z() == v)
         return;
 
-    d->z = v;
+    d->extra.value().z = v;
 
     d->dirty(QQuickItemPrivate::ZValue);
     if (d->parentItem) {
@@ -3720,8 +3713,8 @@ void QQuickItem::setZ(qreal v)
 
     emit zChanged();
 
-    if (d->_layer)
-        d->_layer->updateZ();
+    if (d->extra.isAllocated() && d->extra->layer)
+        d->extra->layer->updateZ();
 }
 
 
@@ -3854,16 +3847,16 @@ void QQuickItem::setZ(qreal v)
 qreal QQuickItem::rotation() const
 {
     Q_D(const QQuickItem);
-    return d->rotation;
+    return d->rotation();
 }
 
 void QQuickItem::setRotation(qreal r)
 {
     Q_D(QQuickItem);
-    if (d->rotation == r)
+    if (d->rotation() == r)
         return;
 
-    d->rotation = r;
+    d->extra.value().rotation = r;
 
     d->dirty(QQuickItemPrivate::BasicTransform);
 
@@ -3875,16 +3868,16 @@ void QQuickItem::setRotation(qreal r)
 qreal QQuickItem::scale() const
 {
     Q_D(const QQuickItem);
-    return d->scale;
+    return d->scale();
 }
 
 void QQuickItem::setScale(qreal s)
 {
     Q_D(QQuickItem);
-    if (d->scale == s)
+    if (d->scale() == s)
         return;
 
-    d->scale = s;
+    d->extra.value().scale = s;
 
     d->dirty(QQuickItemPrivate::BasicTransform);
 
@@ -3894,16 +3887,16 @@ void QQuickItem::setScale(qreal s)
 qreal QQuickItem::opacity() const
 {
     Q_D(const QQuickItem);
-    return d->opacity;
+    return d->opacity();
 }
 
 void QQuickItem::setOpacity(qreal o)
 {
     Q_D(QQuickItem);
-    if (d->opacity == o)
+    if (d->opacity() == o)
         return;
 
-    d->opacity = o;
+    d->extra.value().opacity = o;
 
     d->dirty(QQuickItemPrivate::OpacityValue);
 
@@ -4127,27 +4120,27 @@ void QQuickItemPrivate::removeFromDirtyList()
 
 void QQuickItemPrivate::refFromEffectItem(bool hide)
 {
-    ++effectRefCount;
-    if (1 == effectRefCount) {
+    ++extra.value().effectRefCount;
+    if (1 == extra->effectRefCount) {
         dirty(EffectReference);
         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
     }
     if (hide) {
-        if (++hideRefCount == 1)
+        if (++extra->hideRefCount == 1)
             dirty(HideReference);
     }
 }
 
 void QQuickItemPrivate::derefFromEffectItem(bool unhide)
 {
-    Q_ASSERT(effectRefCount);
-    --effectRefCount;
-    if (0 == effectRefCount) {
+    Q_ASSERT(extra->effectRefCount);
+    --extra->effectRefCount;
+    if (0 == extra->effectRefCount) {
         dirty(EffectReference);
         if (parentItem) QQuickItemPrivate::get(parentItem)->dirty(ChildrenStackingChanged);
     }
     if (unhide) {
-        if (--hideRefCount == 0)
+        if (--extra->hideRefCount == 0)
             dirty(HideReference);
     }
 }
@@ -4687,13 +4680,20 @@ QQuickItem *QQuickItem::scopedFocusItem() const
 Qt::MouseButtons QQuickItem::acceptedMouseButtons() const
 {
     Q_D(const QQuickItem);
-    return d->acceptedMouseButtons;
+    return d->acceptedMouseButtons();
 }
 
 void QQuickItem::setAcceptedMouseButtons(Qt::MouseButtons buttons)
 {
     Q_D(QQuickItem);
-    d->acceptedMouseButtons = buttons;
+    if (buttons & Qt::LeftButton)
+        d->extra.setFlag();
+    else
+        d->extra.clearFlag();
+
+    buttons &= ~Qt::LeftButton;
+    if (buttons || d->extra.isAllocated())
+        d->extra.value().acceptedMouseButtons = buttons;
 }
 
 bool QQuickItem::filtersChildMouseEvents() const
@@ -5379,7 +5379,8 @@ qint64 QQuickItemPrivate::restart(QElapsedTimer &t)
 bool QQuickItem::isTextureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->isTextureProvider() : false;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->isTextureProvider() : false;
 }
 
 /*!
@@ -5394,23 +5395,20 @@ bool QQuickItem::isTextureProvider() const
 QSGTextureProvider *QQuickItem::textureProvider() const
 {
     Q_D(const QQuickItem);
-    return d->_layer && d->_layer->effectSource() ? d->_layer->effectSource()->textureProvider() : 0;
+    return d->extra.isAllocated() && d->extra->layer && d->extra->layer->effectSource() ?
+           d->extra->layer->effectSource()->textureProvider() : 0;
 }
 
-
-
 QQuickItemLayer *QQuickItemPrivate::layer() const
 {
-    if (!_layer) {
-        _layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
+    if (!extra.isAllocated() || !extra->layer) {
+        extra.value().layer = new QQuickItemLayer(const_cast<QQuickItem *>(q_func()));
         if (!componentComplete)
-            _layer->classBegin();
+            extra->layer->classBegin();
     }
-    return _layer;
+    return extra->layer;
 }
 
-
-
 QQuickItemLayer::QQuickItemLayer(QQuickItem *item)
     : m_item(item)
     , m_enabled(false)
@@ -5852,10 +5850,20 @@ void QQuickItemLayer::updateMatrix()
     l->setScale(m_item->scale());
     l->setRotation(m_item->rotation());
     ld->transforms = QQuickItemPrivate::get(m_item)->transforms;
-    ld->origin = QQuickItemPrivate::get(m_item)->origin;
+    if (ld->origin() != QQuickItemPrivate::get(m_item)->origin())
+        ld->extra.value().origin = QQuickItemPrivate::get(m_item)->origin();
     ld->dirty(QQuickItemPrivate::Transform);
 }
 
+QQuickItemPrivate::ExtraData::ExtraData()
+: z(0), scale(1), rotation(0), opacity(1),
+  contents(0), screenAttached(0), layoutDirectionAttached(0),
+  keyHandler(0), layer(0), effectRefCount(0), hideRefCount(0),
+  opacityNode(0), clipNode(0), rootNode(0), beforePaintNode(0),
+  acceptedMouseButtons(0), origin(QQuickItem::Center)
+{
+}
+
 QT_END_NAMESPACE
 
 #include <moc_qquickitem.cpp>
index 5d1b284..c2cc7d0 100644 (file)
@@ -69,6 +69,7 @@
 #include <private/qdeclarativenullablevalue_p_p.h>
 #include <private/qdeclarativenotifier_p.h>
 #include <private/qdeclarativeglobal_p.h>
+#include <private/qlazilyallocated_p.h>
 
 #include <qdeclarative.h>
 #include <qdeclarativecontext.h>
@@ -292,25 +293,6 @@ public:
     static QQuickTransform *transform_at(QDeclarativeListProperty<QQuickTransform> *list, int);
     static void transform_clear(QDeclarativeListProperty<QQuickTransform> *list);
 
-    QQuickAnchors *anchors() const;
-    mutable QQuickAnchors *_anchors;
-    QQuickContents *_contents;
-
-    QDeclarativeNullableValue<qreal> baselineOffset;
-
-    struct AnchorLines {
-        AnchorLines(QQuickItem *);
-        QQuickAnchorLine left;
-        QQuickAnchorLine right;
-        QQuickAnchorLine hCenter;
-        QQuickAnchorLine top;
-        QQuickAnchorLine bottom;
-        QQuickAnchorLine vCenter;
-        QQuickAnchorLine baseline;
-    };
-    mutable AnchorLines *_anchorLines;
-    AnchorLines *anchorLines() const;
-
     enum ChangeType {
         Geometry = 0x01,
         SiblingOrder = 0x02,
@@ -345,21 +327,61 @@ public:
         bool operator==(const ChangeListener &other) const { return listener == other.listener && types == other.types; }
     };
 
-    void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types) {
-        changeListeners.append(ChangeListener(listener, types));
-    }
+    struct ExtraData {
+        ExtraData();
+
+        qreal z;
+        qreal scale;
+        qreal rotation;
+        qreal opacity;
+
+        QQuickContents *contents;
+        QQuickScreenAttached *screenAttached;
+        QQuickLayoutMirroringAttached* layoutDirectionAttached;
+        QQuickItemKeyFilter *keyHandler;
+        mutable QQuickItemLayer *layer;
+        QPointF userTransformOriginPoint;
+
+        int effectRefCount;
+        int hideRefCount;
+
+        QSGOpacityNode *opacityNode;
+        QQuickDefaultClipNode *clipNode;
+        QSGRootNode *rootNode;
+        QSGNode *beforePaintNode;
+
+        // 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
+        // rare to use any of the other buttons.
+        Qt::MouseButtons acceptedMouseButtons;
+
+        QQuickItem::TransformOrigin origin:5;
+    };
+    QLazilyAllocated<ExtraData> extra;
+
+    QQuickAnchors *anchors() const;
+    mutable QQuickAnchors *_anchors;
+
+    inline Qt::MouseButtons acceptedMouseButtons() const;
+
+    QPODVector<QQuickItemPrivate::ChangeListener,4> changeListeners;
+
+    void addItemChangeListener(QQuickItemChangeListener *listener, ChangeTypes types);
     void removeItemChangeListener(QQuickItemChangeListener *, ChangeTypes types);
     void updateOrAddGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types);
     void updateOrRemoveGeometryChangeListener(QQuickItemChangeListener *listener, GeometryChangeTypes types);
-    QPODVector<ChangeListener,4> changeListeners;
 
     QDeclarativeStateGroup *_states();
     QDeclarativeStateGroup *_stateGroup;
 
-    QQuickItem::TransformOrigin origin:5;
+    inline QQuickItem::TransformOrigin origin() const;
+
+    // Bit 0
     quint32 flags:5;
     bool widthValid:1;
     bool heightValid:1;
+    bool baselineOffsetValid:1;
     bool componentComplete:1;
     bool keepMouse:1;
     bool keepTouch:1;
@@ -368,6 +390,7 @@ public:
     bool focus:1;
     bool activeFocus:1;
     bool notifiedFocus:1;
+    // Bit 16
     bool notifiedActiveFocus:1;
     bool filtersChildMouseEvents:1;
     bool explicitVisible:1;
@@ -383,9 +406,51 @@ public:
     bool childrenDoNotOverlap:1;
     bool staticSubtreeGeometry:1;
     bool isAccessible:1;
+    // bool dummy:1
+    // Bit 32
+
+    enum DirtyType {
+        TransformOrigin         = 0x00000001,
+        Transform               = 0x00000002,
+        BasicTransform          = 0x00000004,
+        Position                = 0x00000008,
+        Size                    = 0x00000010,
+
+        ZValue                  = 0x00000020,
+        Content                 = 0x00000040,
+        Smooth                  = 0x00000080,
+        OpacityValue            = 0x00000100,
+        ChildrenChanged         = 0x00000200,
+        ChildrenStackingChanged = 0x00000400,
+        ParentChanged           = 0x00000800,
+
+        Clip                    = 0x00001000,
+        Canvas                  = 0x00002000,
+
+        EffectReference         = 0x00008000,
+        Visible                 = 0x00010000,
+        HideReference           = 0x00020000,
+        PerformanceHints        = 0x00040000,
+        // When you add an attribute here, don't forget to update
+        // dirtyToString()
+
+        TransformUpdateMask     = TransformOrigin | Transform | BasicTransform | Position |
+                                  Size | Canvas,
+        ComplexTransformUpdateMask     = Transform | Canvas,
+        ContentUpdateMask       = Size | Content | Smooth | Canvas,
+        ChildrenUpdateMask      = ChildrenChanged | ChildrenStackingChanged | EffectReference | Canvas
+    };
+
+    quint32 dirtyAttributes;
+    QString dirtyToString() const;
+    void dirty(DirtyType);
+    void addToDirtyList();
+    void removeFromDirtyList();
+    QQuickItem *nextDirtyItem;
+    QQuickItem**prevDirtyItem;
 
     QQuickCanvas *canvas;
-    QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context; }
+    inline QSGContext *sceneGraphContext() const;
 
     QQuickItem *parentItem;
     QDeclarativeNotifier parentNotifier;
@@ -397,15 +462,7 @@ public:
     void removeChild(QQuickItem *);
     void siblingOrderChanged();
 
-    inline void markSortedChildrenDirty(QQuickItem *child) {
-        // If sortedChildItems == &childItems then all in childItems have z == 0
-        // and we don't need to invalidate if the changed item also has z == 0.
-        if (child->z() != 0. || sortedChildItems != &childItems) {
-            if (sortedChildItems != &childItems)
-                delete sortedChildItems;
-            sortedChildItems = 0;
-        }
-    }
+    inline void markSortedChildrenDirty(QQuickItem *child);
 
     class InitializationState {
     public:
@@ -430,19 +487,17 @@ public:
     qreal implicitWidth;
     qreal implicitHeight;
 
-    qreal z;
-    qreal scale;
-    qreal rotation;
-    qreal opacity;
+    qreal baselineOffset;
 
-    QQuickLayoutMirroringAttached* attachedLayoutDirection;
+    QList<QQuickTransform *> transforms;
 
-    Qt::MouseButtons acceptedMouseButtons;
+    inline qreal z() const { return extra.isAllocated()?extra->z:0; }
+    inline qreal scale() const { return extra.isAllocated()?extra->scale:1; }
+    inline qreal rotation() const { return extra.isAllocated()?extra->rotation:0; }
+    inline qreal opacity() const { return extra.isAllocated()?extra->opacity:1; }
 
     void setAccessibleFlagAndListener();
 
-    QPointF transformOriginPoint;
-
     virtual qreal getImplicitWidth() const;
     virtual qreal getImplicitHeight() const;
     virtual void implicitWidthChanged();
@@ -461,10 +516,8 @@ public:
     }
 
     QPointF computeTransformOrigin() const;
-    QList<QQuickTransform *> transforms;
     virtual void transformChanged();
 
-    QQuickItemKeyFilter *keyHandler;
     void deliverKeyEvent(QKeyEvent *);
     void deliverInputMethodEvent(QInputMethodEvent *);
     void deliverFocusEvent(QFocusEvent *);
@@ -479,45 +532,6 @@ public:
     bool calcEffectiveEnable() const;
     void setEffectiveEnableRecur(QQuickItem *scope, bool);
 
-    // XXX todo
-    enum DirtyType {
-        TransformOrigin         = 0x00000001,
-        Transform               = 0x00000002,
-        BasicTransform          = 0x00000004,
-        Position                = 0x00000008,
-        Size                    = 0x00000010,
-
-        ZValue                  = 0x00000020,
-        Content                 = 0x00000040,
-        Smooth                  = 0x00000080,
-        OpacityValue            = 0x00000100,
-        ChildrenChanged         = 0x00000200,
-        ChildrenStackingChanged = 0x00000400,
-        ParentChanged           = 0x00000800,
-
-        Clip                    = 0x00001000,
-        Canvas                  = 0x00002000,
-
-        EffectReference         = 0x00008000,
-        Visible                 = 0x00010000,
-        HideReference           = 0x00020000,
-        PerformanceHints        = 0x00040000,
-        // When you add an attribute here, don't forget to update
-        // dirtyToString()
-
-        TransformUpdateMask     = TransformOrigin | Transform | BasicTransform | Position | Size | Canvas,
-        ComplexTransformUpdateMask     = Transform | Canvas,
-        ContentUpdateMask       = Size | Content | Smooth | Canvas,
-        ChildrenUpdateMask      = ChildrenChanged | ChildrenStackingChanged | EffectReference | Canvas
-
-    };
-    quint32 dirtyAttributes;
-    QString dirtyToString() const;
-    void dirty(DirtyType);
-    void addToDirtyList();
-    void removeFromDirtyList();
-    QQuickItem *nextDirtyItem;
-    QQuickItem**prevDirtyItem;
 
     inline QSGTransformNode *itemNode();
     inline QSGNode *childContainerNode();
@@ -531,13 +545,13 @@ public:
          - groupNode
      */
 
+    QSGOpacityNode *opacityNode() const { return extra.isAllocated()?extra->opacityNode:0; }
+    QQuickDefaultClipNode *clipNode() const { return extra.isAllocated()?extra->clipNode:0; }
+    QSGRootNode *rootNode() const { return extra.isAllocated()?extra->rootNode:0; }
+
     QSGTransformNode *itemNodeInstance;
-    QSGOpacityNode *opacityNode;
-    QQuickDefaultClipNode *clipNode;
-    QSGRootNode *rootNode;
     QSGNode *groupNode;
     QSGNode *paintNode;
-    QSGNode *beforePaintNode;
 
     virtual QSGTransformNode *createTransformNode();
 
@@ -545,17 +559,11 @@ public:
     // it should insert a root node.
     void refFromEffectItem(bool hide);
     void derefFromEffectItem(bool unhide);
-    int effectRefCount;
-    int hideRefCount;
 
     void itemChange(QQuickItem::ItemChange, const QQuickItem::ItemChangeData &);
 
     virtual void mirrorChange() {}
 
-    QQuickScreenAttached *screenAttached;
-
-    mutable QQuickItemLayer *_layer;
-
     static qint64 consistentTime;
     static void setConsistentTime(qint64 t);
     static void start(QElapsedTimer &);
@@ -820,6 +828,34 @@ private:
     static const SigMap sigMap[];
 };
 
+Qt::MouseButtons QQuickItemPrivate::acceptedMouseButtons() const
+{
+    return extra.flag()?Qt::LeftButton:Qt::MouseButton(0) |
+           (extra.isAllocated()?extra->acceptedMouseButtons:Qt::MouseButtons(0));
+}
+
+QSGContext *QQuickItemPrivate::sceneGraphContext() const
+{
+    Q_ASSERT(canvas);
+    return static_cast<QQuickCanvasPrivate *>(QObjectPrivate::get(canvas))->context;
+}
+
+void QQuickItemPrivate::markSortedChildrenDirty(QQuickItem *child)
+{
+    // If sortedChildItems == &childItems then all in childItems have z == 0
+    // and we don't need to invalidate if the changed item also has z == 0.
+    if (child->z() != 0. || sortedChildItems != &childItems) {
+        if (sortedChildItems != &childItems)
+            delete sortedChildItems;
+        sortedChildItems = 0;
+    }
+}
+
+QQuickItem::TransformOrigin QQuickItemPrivate::origin() const
+{
+    return extra.isAllocated()?extra->origin:QQuickItem::Center;
+}
+
 QSGTransformNode *QQuickItemPrivate::itemNode()
 {
     if (!itemNodeInstance) {
@@ -837,12 +873,12 @@ QSGNode *QQuickItemPrivate::childContainerNode()
 {
     if (!groupNode) {
         groupNode = new QSGNode();
-        if (rootNode)
-            rootNode->appendChildNode(groupNode);
-        else if (clipNode)
-            clipNode->appendChildNode(groupNode);
-        else if (opacityNode)
-            opacityNode->appendChildNode(groupNode);
+        if (rootNode())
+            rootNode()->appendChildNode(groupNode);
+        else if (clipNode())
+            clipNode()->appendChildNode(groupNode);
+        else if (opacityNode())
+            opacityNode()->appendChildNode(groupNode);
         else
             itemNode()->appendChildNode(groupNode);
         groupNode->setFlag(QSGNode::ChildrenDoNotOverlap, childrenDoNotOverlap);
index b870443..d0894e9 100644 (file)
@@ -251,7 +251,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
     //But specific to MouseArea, so doesn't belong in canvas
     Q_Q(const QQuickMouseArea);
     QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
-    if (itemPrivate->opacity == 0.0)
+    if (itemPrivate->opacity() == 0.0)
         return false;
 
     if (itemPrivate->flags & QQuickItem::ItemClipsChildrenToShape) {
@@ -270,7 +270,7 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
     }
 
     QQuickMouseArea* ma = qobject_cast<QQuickMouseArea*>(item);
-    if (ma && ma != q && itemPrivate->acceptedMouseButtons & ev->button()) {
+    if (ma && ma != q && itemPrivate->acceptedMouseButtons() & ev->button()) {
         switch (sig) {
         case Click:
             if (!ma->d_func()->isClickConnected())
index b6bd78b..3dfeb90 100644 (file)
@@ -95,7 +95,7 @@ QQuickScreenAttached::QQuickScreenAttached(QObject* attachee)
     m_attachee = qobject_cast<QQuickItem*>(attachee);
 
     if (m_attachee) {
-        QQuickItemPrivate::get(m_attachee)->screenAttached = this;
+        QQuickItemPrivate::get(m_attachee)->extra.value().screenAttached = this;
 
         if (m_attachee->canvas()) //It might not be assigned to a canvas yet
             canvasChanged(m_attachee->canvas());