diff options
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem_p.h | 15 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 63 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene_p.h | 5 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview.cpp | 32 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsview_p.h | 4 |
5 files changed, 77 insertions, 42 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 9c1ee4f..ce74b4f 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -150,6 +150,8 @@ public: geometryChanged(0), inDestructor(0), isObject(0), + ignoreVisible(0), + ignoreOpacity(0), globalStackingOrder(-1), q_ptr(0) { @@ -327,6 +329,15 @@ public: return calcEffectiveOpacity(); } + inline qreal combineOpacityFromParent(qreal parentOpacity) const + { + if (parent && !(flags & QGraphicsItem::ItemIgnoresParentOpacity) + && !(parent->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { + return parentOpacity * opacity; + } + return opacity; + } + inline bool childrenCombineOpacity() const { if (!children.size()) @@ -407,7 +418,9 @@ public: quint32 geometryChanged : 1; quint32 inDestructor : 1; quint32 isObject : 1; - quint32 unused : 14; // feel free to use + quint32 ignoreVisible : 1; + quint32 ignoreOpacity : 1; + quint32 unused : 12; // feel free to use // Optional stacking order int globalStackingOrder; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 811e0d3..dd128ad 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5056,14 +5056,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * if (item) { if (!item->d_ptr->visible) return; - QGraphicsItem *p = item->d_ptr->parent; - bool itemIgnoresParentOpacity = item->d_ptr->flags & QGraphicsItem::ItemIgnoresParentOpacity; - bool parentDoesntPropagateOpacity = (p && (p->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)); - if (!itemIgnoresParentOpacity && !parentDoesntPropagateOpacity) { - opacity = parentOpacity * item->opacity(); - } else { - opacity = item->d_ptr->opacity; - } + opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); if (opacity == 0.0 && !(item->d_ptr->flags & QGraphicsItem::ItemDoesntPropagateOpacityToChildren)) { invisibleButChildIgnoresParentOpacity = !item->d_ptr->childrenCombineOpacity(); if (!invisibleButChildIgnoresParentOpacity) @@ -5297,6 +5290,11 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b item->d_ptr->dirtyChildren = 1; } + if (force) + item->d_ptr->ignoreVisible = 1; + if (ignoreOpacity) + item->d_ptr->ignoreOpacity = 1; + QGraphicsItem *p = item->d_ptr->parent; while (p && !p->d_ptr->dirtyChildren) { p->d_ptr->dirtyChildren = 1; @@ -5304,7 +5302,8 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b } } -void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren) +void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren, + qreal parentOpacity) { Q_Q(QGraphicsScene); @@ -5318,20 +5317,30 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool wasDirtyParentSceneTransform = true; } - // Process item. bool wasDirtyParentViewBoundingRects = false; + qreal opacity = parentOpacity; + if (item) { + wasDirtyParentViewBoundingRects = item->d_ptr->paintedViewBoundingRectsNeedRepaint; + opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); + if ((!item->d_ptr->ignoreVisible && !item->d_ptr->visible) + || (!item->d_ptr->ignoreOpacity && opacity == 0.0) + || (item->d_ptr->flags & QGraphicsItem::ItemHasNoContents)) { + // Make sure we don't process invisible items or items with no content. + item->d_ptr->dirty = 0; + item->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; + } + } + + // Process item. if (item && (item->d_ptr->dirty || item->d_ptr->paintedViewBoundingRectsNeedRepaint)) { const bool useCompatUpdate = views.isEmpty() || (connectedSignals & changedSignalMask); const bool untransformableItem = item->d_ptr->itemIsUntransformable(); - const QRectF itemBoundingRect = item->boundingRect(); + const QRectF itemBoundingRect = adjustedItemBoundingRect(item); if (item->d_ptr->geometryChanged) { // Update growingItemsBoundingRect. - if (!hasSceneRect) { - QRectF itemSceneBoundingRect = item->d_ptr->sceneTransform.mapRect(itemBoundingRect); - _q_adjustRect(&itemSceneBoundingRect); - growingItemsBoundingRect |= itemSceneBoundingRect; - } + if (!hasSceneRect) + growingItemsBoundingRect |= item->d_ptr->sceneTransform.mapRect(itemBoundingRect); item->d_ptr->geometryChanged = 0; } @@ -5360,11 +5369,12 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool break; } + QRect &paintedViewBoundingRect = item->d_ptr->paintedViewBoundingRects[viewPrivate->viewport]; if (item->d_ptr->paintedViewBoundingRectsNeedRepaint) { wasDirtyParentViewBoundingRects = true; - QRect rect = item->d_ptr->paintedViewBoundingRects.value(viewPrivate->viewport); - rect.translate(viewPrivate->dirtyScrollOffset); - viewPrivate->updateRect(rect); + paintedViewBoundingRect.translate(viewPrivate->dirtyScrollOffset); + if (!viewPrivate->updateRect(paintedViewBoundingRect)) + paintedViewBoundingRect = QRect(); } if (!item->d_ptr->dirty) @@ -5372,7 +5382,6 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool if (uninitializedDirtyRect) { dirtyRect = itemBoundingRect; - _q_adjustRect(&dirtyRect); if (!item->d_ptr->fullUpdatePending) { _q_adjustRect(&item->d_ptr->needsRepaint); dirtyRect &= item->d_ptr->needsRepaint; @@ -5390,10 +5399,14 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool else deviceTransform = item->deviceTransform(view->viewportTransform()); } - if (item->d_ptr->hasBoundingRegionGranularity) - viewPrivate->updateRegion(deviceTransform.map(QRegion(dirtyRect.toRect()))); - else - viewPrivate->updateRect(deviceTransform.mapRect(dirtyRect).toRect()); + + if (item->d_ptr->hasBoundingRegionGranularity) { + if (!viewPrivate->updateRegion(deviceTransform.map(QRegion(dirtyRect.toRect())))) + paintedViewBoundingRect = QRect(); + } else { + if (!viewPrivate->updateRect(deviceTransform.mapRect(dirtyRect).toRect())) + paintedViewBoundingRect = QRect(); + } } } } @@ -5434,7 +5447,7 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool child->d_ptr->paintedViewBoundingRectsNeedRepaint = 0; } - processDirtyItemsRecursive(child, dirtyAncestorContainsChildren); + processDirtyItemsRecursive(child, dirtyAncestorContainsChildren, opacity); } } else if (wasDirtyParentSceneTransform) { item->d_ptr->invalidateChildrenSceneTransform(); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index cd463ee..a8f6699 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -266,7 +266,8 @@ public: void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, bool maybeDirtyClipPath = false, bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); - void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false); + void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, + qreal parentOpacity = qreal(1.0)); inline void resetDirtyItem(QGraphicsItem *item) { @@ -278,6 +279,8 @@ public: item->d_ptr->needsRepaint = QRectF(); item->d_ptr->allChildrenDirty = 0; item->d_ptr->fullUpdatePending = 0; + item->d_ptr->ignoreVisible = 0; + item->d_ptr->ignoreOpacity = 0; } QStyle *style; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index e349992..715bf37 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -825,19 +825,22 @@ void QGraphicsViewPrivate::processPendingUpdates() dirtyRegion = QRegion(); } -void QGraphicsViewPrivate::updateRegion(const QRegion &r) +bool QGraphicsViewPrivate::updateRegion(const QRegion &r) { - if (r.isEmpty() || fullUpdatePending) - return; + if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty()) + return false; + + const QRect boundingRect = r.boundingRect(); + if (!boundingRect.intersects(viewport->rect())) + return false; // Update region outside viewport. - // Rect intersects viewport - update everything? switch (viewportUpdateMode) { case QGraphicsView::FullViewportUpdate: fullUpdatePending = true; viewport->update(); break; case QGraphicsView::BoundingRectViewportUpdate: - dirtyBoundingRect |= r.boundingRect(); + dirtyBoundingRect |= boundingRect; if (dirtyBoundingRect.contains(viewport->rect())) { fullUpdatePending = true; viewport->update(); @@ -855,18 +858,20 @@ void QGraphicsViewPrivate::updateRegion(const QRegion &r) } break; } - case QGraphicsView::NoViewportUpdate: - // Unreachable + default: break; } + + return true; } -void QGraphicsViewPrivate::updateRect(const QRect &r) +bool QGraphicsViewPrivate::updateRect(const QRect &r) { - if (r.isEmpty() || fullUpdatePending) - return; + if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate + || !r.intersects(viewport->rect())) { + return false; + } - // Rect intersects viewport - update everything? switch (viewportUpdateMode) { case QGraphicsView::FullViewportUpdate: fullUpdatePending = true; @@ -886,10 +891,11 @@ void QGraphicsViewPrivate::updateRect(const QRect &r) else dirtyRegion += r.adjusted(-2, -2, 2, 2); break; - case QGraphicsView::NoViewportUpdate: - // Unreachable + default: break; } + + return true; } QStyleOptionGraphicsItem *QGraphicsViewPrivate::allocStyleOptionsArray(int numItems) diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h index fac7bf9..9551ff6 100644 --- a/src/gui/graphicsview/qgraphicsview_p.h +++ b/src/gui/graphicsview/qgraphicsview_p.h @@ -171,8 +171,8 @@ public: dirtyBoundingRect = QRect(); dirtyRegion = QRegion(); } - void updateRect(const QRect &rect); - void updateRegion(const QRegion ®ion); + bool updateRect(const QRect &rect); + bool updateRegion(const QRegion ®ion); bool updateSceneSlotReimplementedChecked; QRegion exposedRegion; |