From 6887a89b0e0ee7a0eaff2adc34ae71ab01e2ba2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Tue, 2 Jun 2009 13:53:01 +0200 Subject: Generalize QGrahicsScenePrivate::processDirtyItemsRecursive. Add back compatibility support and make it independent of the views. Also store the sceneTransform instead of the deviceTransform. This will later be the item's cached scene transform (coming in another commit). --- src/gui/graphicsview/qgraphicsitem_p.h | 6 +- src/gui/graphicsview/qgraphicsscene.cpp | 99 ++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 47 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index d007f03..0e0a121 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -146,7 +146,7 @@ public: flags(0), dirtyChildrenBoundingRect(1), paintedViewBoundingRectsNeedRepaint(0), - hasValidDeviceTransform(0), + hasValidSceneTransform(0), globalStackingOrder(-1), q_ptr(0) { @@ -353,7 +353,7 @@ public: QGraphicsItem *parent; QList children; QTransform *transform; - QTransform deviceTransform; + QTransform sceneTransform; int index; int depth; @@ -388,7 +388,7 @@ public: quint32 flags : 11; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; - quint32 hasValidDeviceTransform : 1; + quint32 hasValidSceneTransform : 1; quint32 padding : 18; // feel free to use // Optional stacking order diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 25ac279..34c7dc1 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -680,7 +680,7 @@ void QGraphicsScenePrivate::_q_processDirtyItems() if (updateAll) return; - processDirtyItemsRecursive(0, views.at(0)->viewportTransform()); + processDirtyItemsRecursive(0, QTransform()); for (int i = 0; i < views.size(); ++i) views.at(i)->d_func()->processPendingUpdates(); } @@ -5113,12 +5113,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * QTransform transform = parentTransform; QRect viewBoundingRect; if (item) { - if (!item->d_ptr->hasValidDeviceTransform) { - item->d_ptr->combineTransformFromParent(&transform, &viewTransform); - } else { - transform = item->d_ptr->deviceTransform; - item->d_ptr->hasValidDeviceTransform = 0; - } + item->d_ptr->combineTransformFromParent(&transform, &viewTransform); QRectF brect = item->boundingRect(); if (!brect.size().isNull()) { // ### This does not take the clip into account. @@ -5244,51 +5239,67 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, const QTransform &parentTransform) { Q_ASSERT(!item || item->d_ptr->dirty || item->d_ptr->dirtyChildren); + Q_Q(QGraphicsScene); - // Calculate the full transform for this item. + // Calculate the full scene transform for this item. QTransform transform = parentTransform; - if (item) { - if (item->d_ptr->itemIsUntransformable()) { - QTransform x = views.at(0)->viewportTransform(); - item->d_ptr->combineTransformFromParent(&transform, &x); - } else { - item->d_ptr->combineTransformFromParent(&transform); - } + if (item && !item->d_ptr->itemIsUntransformable()) { + item->d_ptr->combineTransformFromParent(&transform); + item->d_ptr->sceneTransform = transform; + item->d_ptr->hasValidSceneTransform = 1; } // Process item. if (item && item->d_ptr->dirty) { - QRectF dirtyRect = adjustedItemBoundingRect(item); - if (!item->d_ptr->fullUpdatePending) { - _q_adjustRect(&item->d_ptr->needsRepaint); - dirtyRect &= item->d_ptr->needsRepaint; - } + const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask); + if (useCompatUpdate && !item->d_ptr->itemIsUntransformable() + && qFuzzyIsNull(item->boundingRegionGranularity())) { + // This block of code is kept for compatibility. Since 4.5, by default + // QGraphicsView does not connect the signal and we use the below + // method of delivering updates. + q->update(item->sceneBoundingRect()); + } else { + QRectF dirtyRect; + bool uninitializedDirtyRect = true; + + for (int j = 0; j < views.size(); ++j) { + QGraphicsView *view = views.at(j); + QGraphicsViewPrivate *viewPrivate = view->d_func(); + if (viewPrivate->fullUpdatePending) + continue; + switch (viewPrivate->viewportUpdateMode) { + case QGraphicsView::NoViewportUpdate: + continue; + case QGraphicsView::FullViewportUpdate: + view->viewport()->update(); + viewPrivate->fullUpdatePending = 1; + continue; + default: + break; + } - QGraphicsViewPrivate *viewPrivate = views.at(0)->d_func(); - if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) - viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport)); + if (uninitializedDirtyRect) { + dirtyRect = adjustedItemBoundingRect(item); + if (!item->d_ptr->fullUpdatePending) { + _q_adjustRect(&item->d_ptr->needsRepaint); + dirtyRect &= item->d_ptr->needsRepaint; + uninitializedDirtyRect = false; + } + } - bool dirtyRectOutsideViewport = false; - if (item->d_ptr->hasBoundingRegionGranularity) { - const QRegion dirtyViewRegion = transform.map(QRegion(dirtyRect.toRect())) - & viewPrivate->viewport->rect(); - if (!dirtyViewRegion.isEmpty()) - viewPrivate->updateRegion(dirtyViewRegion); - else - dirtyRectOutsideViewport = true; - } else { - const QRect dirtyViewRect = transform.mapRect(dirtyRect).toRect() - & viewPrivate->viewport->rect(); - if (!dirtyViewRect.isEmpty()) - viewPrivate->updateRect(dirtyViewRect); - else - dirtyRectOutsideViewport = true; - } - if (!dirtyRectOutsideViewport) { - // We know for sure this item will be process in the paint event, hence - // store its device transform and re-use it when drawing. - item->d_ptr->hasValidDeviceTransform = 1; - item->d_ptr->deviceTransform = transform; + if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) + viewPrivate->updateRect(item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport)); + + if (item->d_ptr->hasBoundingRegionGranularity) { + const QRegion dirtyViewRegion = item->deviceTransform(view->viewportTransform()) + .map(QRegion(dirtyRect.toRect())); + viewPrivate->updateRegion(dirtyViewRegion); + } else { + const QRect dirtyViewRect = item->deviceTransform(view->viewportTransform()) + .mapRect(dirtyRect).toRect(); + viewPrivate->updateRect(dirtyViewRect); + } + } } } -- cgit v0.12