Line | Source Code | Coverage |
---|
1 | /**************************************************************************** | - |
2 | ** | - |
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). | - |
4 | ** Contact: http://www.qt-project.org/legal | - |
5 | ** | - |
6 | ** This file is part of the QtGui module of the Qt Toolkit. | - |
7 | ** | - |
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - |
9 | ** Commercial License Usage | - |
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - |
11 | ** accordance with the commercial license agreement provided with the | - |
12 | ** Software or, alternatively, in accordance with the terms contained in | - |
13 | ** a written agreement between you and Digia. For licensing terms and | - |
14 | ** conditions see http://qt.digia.com/licensing. For further information | - |
15 | ** use the contact form at http://qt.digia.com/contact-us. | - |
16 | ** | - |
17 | ** GNU Lesser General Public License Usage | - |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - |
19 | ** General Public License version 2.1 as published by the Free Software | - |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the | - |
21 | ** packaging of this file. Please review the following information to | - |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements | - |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - |
24 | ** | - |
25 | ** In addition, as a special exception, Digia gives you certain additional | - |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception | - |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - |
28 | ** | - |
29 | ** GNU General Public License Usage | - |
30 | ** Alternatively, this file may be used under the terms of the GNU | - |
31 | ** General Public License version 3.0 as published by the Free Software | - |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the | - |
33 | ** packaging of this file. Please review the following information to | - |
34 | ** ensure the GNU General Public License version 3.0 requirements will be | - |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. | - |
36 | ** | - |
37 | ** | - |
38 | ** $QT_END_LICENSE$ | - |
39 | ** | - |
40 | ****************************************************************************/ | - |
41 | | - |
42 | /*! | - |
43 | \class QGraphicsSceneBspTreeIndex | - |
44 | \brief The QGraphicsSceneBspTreeIndex class provides an implementation of | - |
45 | a BSP indexing algorithm for discovering items in QGraphicsScene. | - |
46 | \since 4.6 | - |
47 | \ingroup graphicsview-api | - |
48 | | - |
49 | \internal | - |
50 | | - |
51 | QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) | - |
52 | implementation to discover items quickly. This implementation is | - |
53 | very efficient for static scenes. It has a depth that you can set. | - |
54 | The depth directly affects performance and memory usage; the latter | - |
55 | growing exponentially with the depth of the tree. With an optimal tree | - |
56 | depth, the index can instantly determine the locality of items, even | - |
57 | for scenes with thousands or millions of items. This also greatly improves | - |
58 | rendering performance. | - |
59 | | - |
60 | By default, the depth value is 0, in which case Qt will guess a reasonable | - |
61 | default depth based on the size, location and number of items in the | - |
62 | scene. If these parameters change frequently, however, you may experience | - |
63 | slowdowns as the index retunes the depth internally. You can avoid | - |
64 | potential slowdowns by fixating the tree depth through setting this | - |
65 | property. | - |
66 | | - |
67 | The depth of the tree and the size of the scene rectangle decide the | - |
68 | granularity of the scene's partitioning. The size of each scene segment is | - |
69 | determined by the following algorithm: | - |
70 | | - |
71 | The BSP tree has an optimal size when each segment contains between 0 and | - |
72 | 10 items. | - |
73 | | - |
74 | \sa QGraphicsScene, QGraphicsView, QGraphicsSceneIndex | - |
75 | */ | - |
76 | | - |
77 | #include <QtCore/qglobal.h> | - |
78 | | - |
79 | #ifndef QT_NO_GRAPHICSVIEW | - |
80 | | - |
81 | #include <private/qgraphicsscene_p.h> | - |
82 | #include <private/qgraphicsscenebsptreeindex_p.h> | - |
83 | #include <private/qgraphicssceneindex_p.h> | - |
84 | | - |
85 | #include <QtCore/qmath.h> | - |
86 | #include <QtCore/qdebug.h> | - |
87 | | - |
88 | QT_BEGIN_NAMESPACE | - |
89 | | - |
90 | static inline int intmaxlog(int n) | - |
91 | { | - |
92 | return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); executed: return (n > 0 ? qMax(qCeil(qLn(qreal(n)) / qLn(qreal(2))), 5) : 0); Execution Count:356 | 356 |
93 | } | - |
94 | | - |
95 | /*! | - |
96 | Constructs a private scene bsp index. | - |
97 | */ | - |
98 | QGraphicsSceneBspTreeIndexPrivate::QGraphicsSceneBspTreeIndexPrivate(QGraphicsScene *scene) | - |
99 | : QGraphicsSceneIndexPrivate(scene), | - |
100 | bspTreeDepth(0), | - |
101 | indexTimerId(0), | - |
102 | restartIndexTimer(false), | - |
103 | regenerateIndex(true), | - |
104 | lastItemCount(0), | - |
105 | purgePending(false), | - |
106 | sortCacheEnabled(false), | - |
107 | updatingSortCache(false) | - |
108 | { | - |
109 | } executed: } Execution Count:798 | 798 |
110 | | - |
111 | | - |
112 | /*! | - |
113 | This method will update the BSP index by removing the items from the temporary | - |
114 | unindexed list and add them in the indexedItems list. This will also | - |
115 | update the growingItemsBoundingRect if needed. This will update the BSP | - |
116 | implementation as well. | - |
117 | | - |
118 | \internal | - |
119 | */ | - |
120 | void QGraphicsSceneBspTreeIndexPrivate::_q_updateIndex() | - |
121 | { | - |
122 | Q_Q(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndex * const q = q_func(); | - |
123 | if (!indexTimerId) evaluated: !indexTimerId yes Evaluation Count:2165 | yes Evaluation Count:372 |
| 372-2165 |
124 | return; executed: return; Execution Count:2165 | 2165 |
125 | | - |
126 | q->killTimer(indexTimerId); executed (the execution status of this line is deduced): q->killTimer(indexTimerId); | - |
127 | indexTimerId = 0; executed (the execution status of this line is deduced): indexTimerId = 0; | - |
128 | | - |
129 | purgeRemovedItems(); executed (the execution status of this line is deduced): purgeRemovedItems(); | - |
130 | | - |
131 | // Add unindexedItems to indexedItems | - |
132 | for (int i = 0; i < unindexedItems.size(); ++i) { evaluated: i < unindexedItems.size() yes Evaluation Count:808 | yes Evaluation Count:372 |
| 372-808 |
133 | if (QGraphicsItem *item = unindexedItems.at(i)) { partially evaluated: QGraphicsItem *item = unindexedItems.at(i) yes Evaluation Count:808 | no Evaluation Count:0 |
| 0-808 |
134 | Q_ASSERT(!item->d_ptr->itemDiscovered); executed (the execution status of this line is deduced): qt_noop(); | - |
135 | if (!freeItemIndexes.isEmpty()) { evaluated: !freeItemIndexes.isEmpty() yes Evaluation Count:227 | yes Evaluation Count:581 |
| 227-581 |
136 | int freeIndex = freeItemIndexes.takeFirst(); executed (the execution status of this line is deduced): int freeIndex = freeItemIndexes.takeFirst(); | - |
137 | item->d_func()->index = freeIndex; executed (the execution status of this line is deduced): item->d_func()->index = freeIndex; | - |
138 | indexedItems[freeIndex] = item; executed (the execution status of this line is deduced): indexedItems[freeIndex] = item; | - |
139 | } else { executed: } Execution Count:227 | 227 |
140 | item->d_func()->index = indexedItems.size(); executed (the execution status of this line is deduced): item->d_func()->index = indexedItems.size(); | - |
141 | indexedItems << item; executed (the execution status of this line is deduced): indexedItems << item; | - |
142 | } executed: } Execution Count:581 | 581 |
143 | } | - |
144 | } executed: } Execution Count:808 | 808 |
145 | | - |
146 | // Determine whether we should regenerate the BSP tree. | - |
147 | if (bspTreeDepth == 0) { evaluated: bspTreeDepth == 0 yes Evaluation Count:178 | yes Evaluation Count:194 |
| 178-194 |
148 | int oldDepth = intmaxlog(lastItemCount); executed (the execution status of this line is deduced): int oldDepth = intmaxlog(lastItemCount); | - |
149 | bspTreeDepth = intmaxlog(indexedItems.size()); executed (the execution status of this line is deduced): bspTreeDepth = intmaxlog(indexedItems.size()); | - |
150 | static const int slack = 100; | - |
151 | if (bsp.leafCount() == 0 || (oldDepth != bspTreeDepth && qAbs(lastItemCount - indexedItems.size()) > slack)) { evaluated: bsp.leafCount() == 0 yes Evaluation Count:177 | yes Evaluation Count:1 |
partially evaluated: oldDepth != bspTreeDepth yes Evaluation Count:1 | no Evaluation Count:0 |
partially evaluated: qAbs(lastItemCount - indexedItems.size()) > slack no Evaluation Count:0 | yes Evaluation Count:1 |
| 0-177 |
152 | // ### Crude algorithm. | - |
153 | regenerateIndex = true; executed (the execution status of this line is deduced): regenerateIndex = true; | - |
154 | } executed: } Execution Count:177 | 177 |
155 | } executed: } Execution Count:178 | 178 |
156 | | - |
157 | // Regenerate the tree. | - |
158 | if (regenerateIndex) { evaluated: regenerateIndex yes Evaluation Count:197 | yes Evaluation Count:175 |
| 175-197 |
159 | regenerateIndex = false; executed (the execution status of this line is deduced): regenerateIndex = false; | - |
160 | bsp.initialize(sceneRect, bspTreeDepth); executed (the execution status of this line is deduced): bsp.initialize(sceneRect, bspTreeDepth); | - |
161 | unindexedItems = indexedItems; executed (the execution status of this line is deduced): unindexedItems = indexedItems; | - |
162 | lastItemCount = indexedItems.size(); executed (the execution status of this line is deduced): lastItemCount = indexedItems.size(); | - |
163 | } executed: } Execution Count:197 | 197 |
164 | | - |
165 | // Insert all unindexed items into the tree. | - |
166 | for (int i = 0; i < unindexedItems.size(); ++i) { evaluated: i < unindexedItems.size() yes Evaluation Count:808 | yes Evaluation Count:372 |
| 372-808 |
167 | if (QGraphicsItem *item = unindexedItems.at(i)) { partially evaluated: QGraphicsItem *item = unindexedItems.at(i) yes Evaluation Count:808 | no Evaluation Count:0 |
| 0-808 |
168 | if (item->d_ptr->itemIsUntransformable()) { evaluated: item->d_ptr->itemIsUntransformable() yes Evaluation Count:5 | yes Evaluation Count:803 |
| 5-803 |
169 | untransformableItems << item; executed (the execution status of this line is deduced): untransformableItems << item; | - |
170 | continue; executed: continue; Execution Count:5 | 5 |
171 | } | - |
172 | if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) evaluated: item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren yes Evaluation Count:7 | yes Evaluation Count:796 |
| 7-796 |
173 | continue; executed: continue; Execution Count:7 | 7 |
174 | | - |
175 | bsp.insertItem(item, item->d_ptr->sceneEffectiveBoundingRect()); executed (the execution status of this line is deduced): bsp.insertItem(item, item->d_ptr->sceneEffectiveBoundingRect()); | - |
176 | } executed: } Execution Count:796 | 796 |
177 | } executed: } Execution Count:796 | 796 |
178 | unindexedItems.clear(); executed (the execution status of this line is deduced): unindexedItems.clear(); | - |
179 | } executed: } Execution Count:372 | 372 |
180 | | - |
181 | | - |
182 | /*! | - |
183 | \internal | - |
184 | | - |
185 | Removes stale pointers from all data structures. | - |
186 | */ | - |
187 | void QGraphicsSceneBspTreeIndexPrivate::purgeRemovedItems() | - |
188 | { | - |
189 | if (!purgePending && removedItems.isEmpty()) evaluated: !purgePending yes Evaluation Count:7322 | yes Evaluation Count:2 |
partially evaluated: removedItems.isEmpty() yes Evaluation Count:7322 | no Evaluation Count:0 |
| 0-7322 |
190 | return; executed: return; Execution Count:7322 | 7322 |
191 | | - |
192 | // Remove stale items from the BSP tree. | - |
193 | bsp.removeItems(removedItems); executed (the execution status of this line is deduced): bsp.removeItems(removedItems); | - |
194 | // Purge this list. | - |
195 | removedItems.clear(); executed (the execution status of this line is deduced): removedItems.clear(); | - |
196 | freeItemIndexes.clear(); executed (the execution status of this line is deduced): freeItemIndexes.clear(); | - |
197 | for (int i = 0; i < indexedItems.size(); ++i) { evaluated: i < indexedItems.size() yes Evaluation Count:4 | yes Evaluation Count:2 |
| 2-4 |
198 | if (!indexedItems.at(i)) partially evaluated: !indexedItems.at(i) yes Evaluation Count:4 | no Evaluation Count:0 |
| 0-4 |
199 | freeItemIndexes << i; executed: freeItemIndexes << i; Execution Count:4 | 4 |
200 | } executed: } Execution Count:4 | 4 |
201 | purgePending = false; executed (the execution status of this line is deduced): purgePending = false; | - |
202 | } executed: } Execution Count:2 | 2 |
203 | | - |
204 | /*! | - |
205 | \internal | - |
206 | | - |
207 | Starts or restarts the timer used for reindexing unindexed items. | - |
208 | */ | - |
209 | void QGraphicsSceneBspTreeIndexPrivate::startIndexTimer(int interval) | - |
210 | { | - |
211 | Q_Q(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndex * const q = q_func(); | - |
212 | if (indexTimerId) { evaluated: indexTimerId yes Evaluation Count:1872 | yes Evaluation Count:959 |
| 959-1872 |
213 | restartIndexTimer = true; executed (the execution status of this line is deduced): restartIndexTimer = true; | - |
214 | } else { executed: } Execution Count:1872 | 1872 |
215 | indexTimerId = q->startTimer(interval); executed (the execution status of this line is deduced): indexTimerId = q->startTimer(interval); | - |
216 | } executed: } Execution Count:959 | 959 |
217 | } | - |
218 | | - |
219 | /*! | - |
220 | \internal | - |
221 | */ | - |
222 | void QGraphicsSceneBspTreeIndexPrivate::resetIndex() | - |
223 | { | - |
224 | purgeRemovedItems(); executed (the execution status of this line is deduced): purgeRemovedItems(); | - |
225 | for (int i = 0; i < indexedItems.size(); ++i) { evaluated: i < indexedItems.size() yes Evaluation Count:176 | yes Evaluation Count:833 |
| 176-833 |
226 | if (QGraphicsItem *item = indexedItems.at(i)) { evaluated: QGraphicsItem *item = indexedItems.at(i) yes Evaluation Count:148 | yes Evaluation Count:28 |
| 28-148 |
227 | item->d_ptr->index = -1; executed (the execution status of this line is deduced): item->d_ptr->index = -1; | - |
228 | Q_ASSERT(!item->d_ptr->itemDiscovered); executed (the execution status of this line is deduced): qt_noop(); | - |
229 | unindexedItems << item; executed (the execution status of this line is deduced): unindexedItems << item; | - |
230 | } executed: } Execution Count:148 | 148 |
231 | } executed: } Execution Count:176 | 176 |
232 | indexedItems.clear(); executed (the execution status of this line is deduced): indexedItems.clear(); | - |
233 | freeItemIndexes.clear(); executed (the execution status of this line is deduced): freeItemIndexes.clear(); | - |
234 | untransformableItems.clear(); executed (the execution status of this line is deduced): untransformableItems.clear(); | - |
235 | regenerateIndex = true; executed (the execution status of this line is deduced): regenerateIndex = true; | - |
236 | startIndexTimer(); executed (the execution status of this line is deduced): startIndexTimer(); | - |
237 | } executed: } Execution Count:833 | 833 |
238 | | - |
239 | /*! | - |
240 | \internal | - |
241 | */ | - |
242 | void QGraphicsSceneBspTreeIndexPrivate::climbTree(QGraphicsItem *item, int *stackingOrder) | - |
243 | { | - |
244 | if (!item->d_ptr->children.isEmpty()) { never evaluated: !item->d_ptr->children.isEmpty() | 0 |
245 | QList<QGraphicsItem *> childList = item->d_ptr->children; never executed (the execution status of this line is deduced): QList<QGraphicsItem *> childList = item->d_ptr->children; | - |
246 | std::sort(childList.begin(), childList.end(), qt_closestLeaf); never executed (the execution status of this line is deduced): std::sort(childList.begin(), childList.end(), qt_closestLeaf); | - |
247 | for (int i = 0; i < childList.size(); ++i) { never evaluated: i < childList.size() | 0 |
248 | QGraphicsItem *item = childList.at(i); never executed (the execution status of this line is deduced): QGraphicsItem *item = childList.at(i); | - |
249 | if (!(item->flags() & QGraphicsItem::ItemStacksBehindParent)) never evaluated: !(item->flags() & QGraphicsItem::ItemStacksBehindParent) | 0 |
250 | climbTree(childList.at(i), stackingOrder); never executed: climbTree(childList.at(i), stackingOrder); | 0 |
251 | } | 0 |
252 | item->d_ptr->globalStackingOrder = (*stackingOrder)++; never executed (the execution status of this line is deduced): item->d_ptr->globalStackingOrder = (*stackingOrder)++; | - |
253 | for (int i = 0; i < childList.size(); ++i) { never evaluated: i < childList.size() | 0 |
254 | QGraphicsItem *item = childList.at(i); never executed (the execution status of this line is deduced): QGraphicsItem *item = childList.at(i); | - |
255 | if (item->flags() & QGraphicsItem::ItemStacksBehindParent) never evaluated: item->flags() & QGraphicsItem::ItemStacksBehindParent | 0 |
256 | climbTree(childList.at(i), stackingOrder); never executed: climbTree(childList.at(i), stackingOrder); | 0 |
257 | } | 0 |
258 | } else { | 0 |
259 | item->d_ptr->globalStackingOrder = (*stackingOrder)++; never executed (the execution status of this line is deduced): item->d_ptr->globalStackingOrder = (*stackingOrder)++; | - |
260 | } | 0 |
261 | } | - |
262 | | - |
263 | /*! | - |
264 | \internal | - |
265 | */ | - |
266 | void QGraphicsSceneBspTreeIndexPrivate::_q_updateSortCache() | - |
267 | { | - |
268 | Q_Q(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndex * const q = q_func(); | - |
269 | _q_updateIndex(); executed (the execution status of this line is deduced): _q_updateIndex(); | - |
270 | | - |
271 | if (!sortCacheEnabled || !updatingSortCache) partially evaluated: !sortCacheEnabled yes Evaluation Count:2442 | no Evaluation Count:0 |
never evaluated: !updatingSortCache | 0-2442 |
272 | return; executed: return; Execution Count:2442 | 2442 |
273 | | - |
274 | updatingSortCache = false; never executed (the execution status of this line is deduced): updatingSortCache = false; | - |
275 | int stackingOrder = 0; never executed (the execution status of this line is deduced): int stackingOrder = 0; | - |
276 | | - |
277 | QList<QGraphicsItem *> topLevels; never executed (the execution status of this line is deduced): QList<QGraphicsItem *> topLevels; | - |
278 | const QList<QGraphicsItem *> items = q->items(); never executed (the execution status of this line is deduced): const QList<QGraphicsItem *> items = q->items(); | - |
279 | for (int i = 0; i < items.size(); ++i) { never evaluated: i < items.size() | 0 |
280 | QGraphicsItem *item = items.at(i); never executed (the execution status of this line is deduced): QGraphicsItem *item = items.at(i); | - |
281 | if (item && !item->d_ptr->parent) never evaluated: item never evaluated: !item->d_ptr->parent | 0 |
282 | topLevels << item; never executed: topLevels << item; | 0 |
283 | } | 0 |
284 | | - |
285 | std::sort(topLevels.begin(), topLevels.end(), qt_closestLeaf); never executed (the execution status of this line is deduced): std::sort(topLevels.begin(), topLevels.end(), qt_closestLeaf); | - |
286 | for (int i = 0; i < topLevels.size(); ++i) never evaluated: i < topLevels.size() | 0 |
287 | climbTree(topLevels.at(i), &stackingOrder); never executed: climbTree(topLevels.at(i), &stackingOrder); | 0 |
288 | } | 0 |
289 | | - |
290 | /*! | - |
291 | \internal | - |
292 | */ | - |
293 | void QGraphicsSceneBspTreeIndexPrivate::invalidateSortCache() | - |
294 | { | - |
295 | Q_Q(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndex * const q = q_func(); | - |
296 | if (!sortCacheEnabled || updatingSortCache) partially evaluated: !sortCacheEnabled yes Evaluation Count:4040 | no Evaluation Count:0 |
never evaluated: updatingSortCache | 0-4040 |
297 | return; executed: return; Execution Count:4040 | 4040 |
298 | | - |
299 | updatingSortCache = true; never executed (the execution status of this line is deduced): updatingSortCache = true; | - |
300 | QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); never executed (the execution status of this line is deduced): QMetaObject::invokeMethod(q, "_q_updateSortCache", Qt::QueuedConnection); | - |
301 | } | 0 |
302 | | - |
303 | void QGraphicsSceneBspTreeIndexPrivate::addItem(QGraphicsItem *item, bool recursive) | - |
304 | { | - |
305 | if (!item) partially evaluated: !item no Evaluation Count:0 | yes Evaluation Count:1998 |
| 0-1998 |
306 | return; | 0 |
307 | | - |
308 | // Prevent reusing a recently deleted pointer: purge all removed item from our lists. | - |
309 | purgeRemovedItems(); executed (the execution status of this line is deduced): purgeRemovedItems(); | - |
310 | | - |
311 | // Invalidate any sort caching; arrival of a new item means we need to resort. | - |
312 | // Update the scene's sort cache settings. | - |
313 | item->d_ptr->globalStackingOrder = -1; executed (the execution status of this line is deduced): item->d_ptr->globalStackingOrder = -1; | - |
314 | invalidateSortCache(); executed (the execution status of this line is deduced): invalidateSortCache(); | - |
315 | | - |
316 | // Indexing requires sceneBoundingRect(), but because \a item might | - |
317 | // not be completely constructed at this point, we need to store it in | - |
318 | // a temporary list and schedule an indexing for later. | - |
319 | if (item->d_ptr->index == -1) { partially evaluated: item->d_ptr->index == -1 yes Evaluation Count:1998 | no Evaluation Count:0 |
| 0-1998 |
320 | Q_ASSERT(!unindexedItems.contains(item)); executed (the execution status of this line is deduced): qt_noop(); | - |
321 | unindexedItems << item; executed (the execution status of this line is deduced): unindexedItems << item; | - |
322 | startIndexTimer(0); executed (the execution status of this line is deduced): startIndexTimer(0); | - |
323 | } else { executed: } Execution Count:1998 | 1998 |
324 | Q_ASSERT(indexedItems.contains(item)); never executed (the execution status of this line is deduced): qt_noop(); | - |
325 | qWarning("QGraphicsSceneBspTreeIndex::addItem: item has already been added to this BSP"); never executed (the execution status of this line is deduced): QMessageLogger("graphicsview/qgraphicsscenebsptreeindex.cpp", 325, __PRETTY_FUNCTION__).warning("QGraphicsSceneBspTreeIndex::addItem: item has already been added to this BSP"); | - |
326 | } | 0 |
327 | | - |
328 | if (recursive) { partially evaluated: recursive no Evaluation Count:0 | yes Evaluation Count:1998 |
| 0-1998 |
329 | for (int i = 0; i < item->d_ptr->children.size(); ++i) never evaluated: i < item->d_ptr->children.size() | 0 |
330 | addItem(item->d_ptr->children.at(i), recursive); never executed: addItem(item->d_ptr->children.at(i), recursive); | 0 |
331 | } | 0 |
332 | } executed: } Execution Count:1998 | 1998 |
333 | | - |
334 | void QGraphicsSceneBspTreeIndexPrivate::removeItem(QGraphicsItem *item, bool recursive, | - |
335 | bool moveToUnindexedItems) | - |
336 | { | - |
337 | if (!item) partially evaluated: !item no Evaluation Count:0 | yes Evaluation Count:1972 |
| 0-1972 |
338 | return; | 0 |
339 | | - |
340 | if (item->d_ptr->index != -1) { evaluated: item->d_ptr->index != -1 yes Evaluation Count:317 | yes Evaluation Count:1655 |
| 317-1655 |
341 | Q_ASSERT(item->d_ptr->index < indexedItems.size()); executed (the execution status of this line is deduced): qt_noop(); | - |
342 | Q_ASSERT(indexedItems.at(item->d_ptr->index) == item); executed (the execution status of this line is deduced): qt_noop(); | - |
343 | Q_ASSERT(!item->d_ptr->itemDiscovered); executed (the execution status of this line is deduced): qt_noop(); | - |
344 | freeItemIndexes << item->d_ptr->index; executed (the execution status of this line is deduced): freeItemIndexes << item->d_ptr->index; | - |
345 | indexedItems[item->d_ptr->index] = 0; executed (the execution status of this line is deduced): indexedItems[item->d_ptr->index] = 0; | - |
346 | item->d_ptr->index = -1; executed (the execution status of this line is deduced): item->d_ptr->index = -1; | - |
347 | | - |
348 | if (item->d_ptr->itemIsUntransformable()) { evaluated: item->d_ptr->itemIsUntransformable() yes Evaluation Count:2 | yes Evaluation Count:315 |
| 2-315 |
349 | untransformableItems.removeOne(item); executed (the execution status of this line is deduced): untransformableItems.removeOne(item); | - |
350 | } else if (item->d_ptr->inDestructor) { executed: } Execution Count:2 evaluated: item->d_ptr->inDestructor yes Evaluation Count:55 | yes Evaluation Count:260 |
| 2-260 |
351 | // Avoid virtual function calls from the destructor. | - |
352 | purgePending = true; executed (the execution status of this line is deduced): purgePending = true; | - |
353 | removedItems << item; executed (the execution status of this line is deduced): removedItems << item; | - |
354 | } else if (!(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { executed: } Execution Count:55 partially evaluated: !(item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) yes Evaluation Count:260 | no Evaluation Count:0 |
| 0-260 |
355 | bsp.removeItem(item, item->d_ptr->sceneEffectiveBoundingRect()); executed (the execution status of this line is deduced): bsp.removeItem(item, item->d_ptr->sceneEffectiveBoundingRect()); | - |
356 | } executed: } Execution Count:260 | 260 |
357 | } else { | - |
358 | unindexedItems.removeOne(item); executed (the execution status of this line is deduced): unindexedItems.removeOne(item); | - |
359 | } executed: } Execution Count:1655 | 1655 |
360 | invalidateSortCache(); // ### Only do this when removing from BSP? executed (the execution status of this line is deduced): invalidateSortCache(); | - |
361 | | - |
362 | Q_ASSERT(item->d_ptr->index == -1); executed (the execution status of this line is deduced): qt_noop(); | - |
363 | Q_ASSERT(!indexedItems.contains(item)); executed (the execution status of this line is deduced): qt_noop(); | - |
364 | Q_ASSERT(!unindexedItems.contains(item)); executed (the execution status of this line is deduced): qt_noop(); | - |
365 | Q_ASSERT(!untransformableItems.contains(item)); executed (the execution status of this line is deduced): qt_noop(); | - |
366 | | - |
367 | if (moveToUnindexedItems) evaluated: moveToUnindexedItems yes Evaluation Count:272 | yes Evaluation Count:1700 |
| 272-1700 |
368 | addItem(item); executed: addItem(item); Execution Count:272 | 272 |
369 | | - |
370 | if (recursive) { evaluated: recursive yes Evaluation Count:19 | yes Evaluation Count:1953 |
| 19-1953 |
371 | for (int i = 0; i < item->d_ptr->children.size(); ++i) evaluated: i < item->d_ptr->children.size() yes Evaluation Count:6 | yes Evaluation Count:19 |
| 6-19 |
372 | removeItem(item->d_ptr->children.at(i), recursive, moveToUnindexedItems); executed: removeItem(item->d_ptr->children.at(i), recursive, moveToUnindexedItems); Execution Count:6 | 6 |
373 | } executed: } Execution Count:19 | 19 |
374 | } executed: } Execution Count:1972 | 1972 |
375 | | - |
376 | QList<QGraphicsItem *> QGraphicsSceneBspTreeIndexPrivate::estimateItems(const QRectF &rect, Qt::SortOrder order, | - |
377 | bool onlyTopLevelItems) | - |
378 | { | - |
379 | Q_Q(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndex * const q = q_func(); | - |
380 | if (onlyTopLevelItems && rect.isNull()) partially evaluated: onlyTopLevelItems yes Evaluation Count:2442 | no Evaluation Count:0 |
partially evaluated: rect.isNull() no Evaluation Count:0 | yes Evaluation Count:2442 |
| 0-2442 |
381 | return q->QGraphicsSceneIndex::estimateTopLevelItems(rect, order); never executed: return q->QGraphicsSceneIndex::estimateTopLevelItems(rect, order); | 0 |
382 | | - |
383 | purgeRemovedItems(); executed (the execution status of this line is deduced): purgeRemovedItems(); | - |
384 | _q_updateSortCache(); executed (the execution status of this line is deduced): _q_updateSortCache(); | - |
385 | Q_ASSERT(unindexedItems.isEmpty()); executed (the execution status of this line is deduced): qt_noop(); | - |
386 | | - |
387 | QList<QGraphicsItem *> rectItems = bsp.items(rect, onlyTopLevelItems); executed (the execution status of this line is deduced): QList<QGraphicsItem *> rectItems = bsp.items(rect, onlyTopLevelItems); | - |
388 | if (onlyTopLevelItems) { partially evaluated: onlyTopLevelItems yes Evaluation Count:2442 | no Evaluation Count:0 |
| 0-2442 |
389 | for (int i = 0; i < untransformableItems.size(); ++i) { evaluated: i < untransformableItems.size() yes Evaluation Count:8 | yes Evaluation Count:2442 |
| 8-2442 |
390 | QGraphicsItem *item = untransformableItems.at(i); executed (the execution status of this line is deduced): QGraphicsItem *item = untransformableItems.at(i); | - |
391 | if (!item->d_ptr->parent) { evaluated: !item->d_ptr->parent yes Evaluation Count:6 | yes Evaluation Count:2 |
| 2-6 |
392 | rectItems << item; executed (the execution status of this line is deduced): rectItems << item; | - |
393 | } else { executed: } Execution Count:6 | 6 |
394 | item = item->topLevelItem(); executed (the execution status of this line is deduced): item = item->topLevelItem(); | - |
395 | if (!rectItems.contains(item)) partially evaluated: !rectItems.contains(item) no Evaluation Count:0 | yes Evaluation Count:2 |
| 0-2 |
396 | rectItems << item; never executed: rectItems << item; | 0 |
397 | } executed: } Execution Count:2 | 2 |
398 | } | - |
399 | } else { executed: } Execution Count:2442 | 2442 |
400 | rectItems += untransformableItems; never executed (the execution status of this line is deduced): rectItems += untransformableItems; | - |
401 | } | 0 |
402 | | - |
403 | sortItems(&rectItems, order, sortCacheEnabled, onlyTopLevelItems); executed (the execution status of this line is deduced): sortItems(&rectItems, order, sortCacheEnabled, onlyTopLevelItems); | - |
404 | return rectItems; executed: return rectItems; Execution Count:2442 | 2442 |
405 | } | - |
406 | | - |
407 | /*! | - |
408 | Sort a list of \a itemList in a specific \a order and use the cache if requested. | - |
409 | | - |
410 | \internal | - |
411 | */ | - |
412 | void QGraphicsSceneBspTreeIndexPrivate::sortItems(QList<QGraphicsItem *> *itemList, Qt::SortOrder order, | - |
413 | bool sortCacheEnabled, bool onlyTopLevelItems) | - |
414 | { | - |
415 | if (order == Qt::SortOrder(-1)) partially evaluated: order == Qt::SortOrder(-1) no Evaluation Count:0 | yes Evaluation Count:4121 |
| 0-4121 |
416 | return; | 0 |
417 | | - |
418 | if (onlyTopLevelItems) { evaluated: onlyTopLevelItems yes Evaluation Count:2442 | yes Evaluation Count:1679 |
| 1679-2442 |
419 | if (order == Qt::DescendingOrder) partially evaluated: order == Qt::DescendingOrder no Evaluation Count:0 | yes Evaluation Count:2442 |
| 0-2442 |
420 | std::sort(itemList->begin(), itemList->end(), qt_closestLeaf); never executed: std::sort(itemList->begin(), itemList->end(), qt_closestLeaf); | 0 |
421 | else if (order == Qt::AscendingOrder) partially evaluated: order == Qt::AscendingOrder yes Evaluation Count:2442 | no Evaluation Count:0 |
| 0-2442 |
422 | std::sort(itemList->begin(), itemList->end(), qt_notclosestLeaf); executed: std::sort(itemList->begin(), itemList->end(), qt_notclosestLeaf); Execution Count:2442 | 2442 |
423 | return; executed: return; Execution Count:2442 | 2442 |
424 | } | - |
425 | | - |
426 | if (sortCacheEnabled) { partially evaluated: sortCacheEnabled no Evaluation Count:0 | yes Evaluation Count:1679 |
| 0-1679 |
427 | if (order == Qt::DescendingOrder) { never evaluated: order == Qt::DescendingOrder | 0 |
428 | std::sort(itemList->begin(), itemList->end(), closestItemFirst_withCache); never executed (the execution status of this line is deduced): std::sort(itemList->begin(), itemList->end(), closestItemFirst_withCache); | - |
429 | } else if (order == Qt::AscendingOrder) { never executed: } never evaluated: order == Qt::AscendingOrder | 0 |
430 | std::sort(itemList->begin(), itemList->end(), closestItemLast_withCache); never executed (the execution status of this line is deduced): std::sort(itemList->begin(), itemList->end(), closestItemLast_withCache); | - |
431 | } | 0 |
432 | } else { | - |
433 | if (order == Qt::DescendingOrder) { evaluated: order == Qt::DescendingOrder yes Evaluation Count:1673 | yes Evaluation Count:6 |
| 6-1673 |
434 | std::sort(itemList->begin(), itemList->end(), qt_closestItemFirst); executed (the execution status of this line is deduced): std::sort(itemList->begin(), itemList->end(), qt_closestItemFirst); | - |
435 | } else if (order == Qt::AscendingOrder) { executed: } Execution Count:1673 partially evaluated: order == Qt::AscendingOrder yes Evaluation Count:6 | no Evaluation Count:0 |
| 0-1673 |
436 | std::sort(itemList->begin(), itemList->end(), qt_closestItemLast); executed (the execution status of this line is deduced): std::sort(itemList->begin(), itemList->end(), qt_closestItemLast); | - |
437 | } executed: } Execution Count:6 | 6 |
438 | } | - |
439 | } | - |
440 | | - |
441 | /*! | - |
442 | Constructs a BSP scene index for the given \a scene. | - |
443 | */ | - |
444 | QGraphicsSceneBspTreeIndex::QGraphicsSceneBspTreeIndex(QGraphicsScene *scene) | - |
445 | : QGraphicsSceneIndex(*new QGraphicsSceneBspTreeIndexPrivate(scene), scene) | - |
446 | { | - |
447 | | - |
448 | } executed: } Execution Count:798 | 798 |
449 | | - |
450 | QGraphicsSceneBspTreeIndex::~QGraphicsSceneBspTreeIndex() | - |
451 | { | - |
452 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
453 | for (int i = 0; i < d->indexedItems.size(); ++i) { partially evaluated: i < d->indexedItems.size() no Evaluation Count:0 | yes Evaluation Count:779 |
| 0-779 |
454 | // Ensure item bits are reset properly. | - |
455 | if (QGraphicsItem *item = d->indexedItems.at(i)) { never evaluated: QGraphicsItem *item = d->indexedItems.at(i) | 0 |
456 | Q_ASSERT(!item->d_ptr->itemDiscovered); never executed (the execution status of this line is deduced): qt_noop(); | - |
457 | item->d_ptr->index = -1; never executed (the execution status of this line is deduced): item->d_ptr->index = -1; | - |
458 | } | 0 |
459 | } | 0 |
460 | } executed: } Execution Count:779 | 779 |
461 | | - |
462 | /*! | - |
463 | \internal | - |
464 | Clear the all the BSP index. | - |
465 | */ | - |
466 | void QGraphicsSceneBspTreeIndex::clear() | - |
467 | { | - |
468 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
469 | d->bsp.clear(); executed (the execution status of this line is deduced): d->bsp.clear(); | - |
470 | d->lastItemCount = 0; executed (the execution status of this line is deduced): d->lastItemCount = 0; | - |
471 | d->freeItemIndexes.clear(); executed (the execution status of this line is deduced): d->freeItemIndexes.clear(); | - |
472 | for (int i = 0; i < d->indexedItems.size(); ++i) { evaluated: i < d->indexedItems.size() yes Evaluation Count:387 | yes Evaluation Count:779 |
| 387-779 |
473 | // Ensure item bits are reset properly. | - |
474 | if (QGraphicsItem *item = d->indexedItems.at(i)) { evaluated: QGraphicsItem *item = d->indexedItems.at(i) yes Evaluation Count:325 | yes Evaluation Count:62 |
| 62-325 |
475 | Q_ASSERT(!item->d_ptr->itemDiscovered); executed (the execution status of this line is deduced): qt_noop(); | - |
476 | item->d_ptr->index = -1; executed (the execution status of this line is deduced): item->d_ptr->index = -1; | - |
477 | } executed: } Execution Count:325 | 325 |
478 | } executed: } Execution Count:387 | 387 |
479 | d->indexedItems.clear(); executed (the execution status of this line is deduced): d->indexedItems.clear(); | - |
480 | d->unindexedItems.clear(); executed (the execution status of this line is deduced): d->unindexedItems.clear(); | - |
481 | d->untransformableItems.clear(); executed (the execution status of this line is deduced): d->untransformableItems.clear(); | - |
482 | d->regenerateIndex = true; executed (the execution status of this line is deduced): d->regenerateIndex = true; | - |
483 | } executed: } Execution Count:779 | 779 |
484 | | - |
485 | /*! | - |
486 | Add the \a item into the BSP index. | - |
487 | */ | - |
488 | void QGraphicsSceneBspTreeIndex::addItem(QGraphicsItem *item) | - |
489 | { | - |
490 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
491 | d->addItem(item); executed (the execution status of this line is deduced): d->addItem(item); | - |
492 | } executed: } Execution Count:1726 | 1726 |
493 | | - |
494 | /*! | - |
495 | Remove the \a item from the BSP index. | - |
496 | */ | - |
497 | void QGraphicsSceneBspTreeIndex::removeItem(QGraphicsItem *item) | - |
498 | { | - |
499 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
500 | d->removeItem(item); executed (the execution status of this line is deduced): d->removeItem(item); | - |
501 | } executed: } Execution Count:1700 | 1700 |
502 | | - |
503 | /*! | - |
504 | \internal | - |
505 | Update the BSP when the \a item 's bounding rect has changed. | - |
506 | */ | - |
507 | void QGraphicsSceneBspTreeIndex::prepareBoundingRectChange(const QGraphicsItem *item) | - |
508 | { | - |
509 | if (!item) partially evaluated: !item no Evaluation Count:0 | yes Evaluation Count:1774 |
| 0-1774 |
510 | return; | 0 |
511 | | - |
512 | if (item->d_ptr->index == -1 || item->d_ptr->itemIsUntransformable() evaluated: item->d_ptr->index == -1 yes Evaluation Count:1520 | yes Evaluation Count:254 |
partially evaluated: item->d_ptr->itemIsUntransformable() no Evaluation Count:0 | yes Evaluation Count:254 |
| 0-1520 |
513 | || (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) { evaluated: (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) yes Evaluation Count:1 | yes Evaluation Count:253 |
| 1-253 |
514 | return; // Item is not in BSP tree; nothing to do. executed: return; Execution Count:1521 | 1521 |
515 | } | - |
516 | | - |
517 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
518 | QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); executed (the execution status of this line is deduced): QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); | - |
519 | d->removeItem(thatItem, /*recursive=*/false, /*moveToUnindexedItems=*/true); executed (the execution status of this line is deduced): d->removeItem(thatItem, false, true); | - |
520 | for (int i = 0; i < item->d_ptr->children.size(); ++i) // ### Do we really need this? evaluated: i < item->d_ptr->children.size() yes Evaluation Count:16 | yes Evaluation Count:253 |
| 16-253 |
521 | prepareBoundingRectChange(item->d_ptr->children.at(i)); executed: prepareBoundingRectChange(item->d_ptr->children.at(i)); Execution Count:16 | 16 |
522 | } executed: } Execution Count:253 | 253 |
523 | | - |
524 | /*! | - |
525 | Returns an estimation visible items that are either inside or | - |
526 | intersect with the specified \a rect and return a list sorted using \a order. | - |
527 | | - |
528 | \a deviceTransform is the transformation apply to the view. | - |
529 | | - |
530 | */ | - |
531 | QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::estimateItems(const QRectF &rect, Qt::SortOrder order) const | - |
532 | { | - |
533 | Q_D(const QGraphicsSceneBspTreeIndex); never executed (the execution status of this line is deduced): const QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
534 | return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order); never executed: return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order); | 0 |
535 | } | - |
536 | | - |
537 | QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::estimateTopLevelItems(const QRectF &rect, Qt::SortOrder order) const | - |
538 | { | - |
539 | Q_D(const QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): const QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
540 | return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order, /*onlyTopLevels=*/true); executed: return const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->estimateItems(rect, order, true); Execution Count:2442 | 2442 |
541 | } | - |
542 | | - |
543 | /*! | - |
544 | \fn QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const; | - |
545 | | - |
546 | Return all items in the BSP index and sort them using \a order. | - |
547 | */ | - |
548 | QList<QGraphicsItem *> QGraphicsSceneBspTreeIndex::items(Qt::SortOrder order) const | - |
549 | { | - |
550 | Q_D(const QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): const QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
551 | const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->purgeRemovedItems(); executed (the execution status of this line is deduced): const_cast<QGraphicsSceneBspTreeIndexPrivate*>(d)->purgeRemovedItems(); | - |
552 | QList<QGraphicsItem *> itemList; executed (the execution status of this line is deduced): QList<QGraphicsItem *> itemList; | - |
553 | | - |
554 | // If freeItemIndexes is empty, we know there are no holes in indexedItems and | - |
555 | // unindexedItems. | - |
556 | if (d->freeItemIndexes.isEmpty()) { evaluated: d->freeItemIndexes.isEmpty() yes Evaluation Count:1676 | yes Evaluation Count:3 |
| 3-1676 |
557 | if (d->unindexedItems.isEmpty()) { evaluated: d->unindexedItems.isEmpty() yes Evaluation Count:1181 | yes Evaluation Count:495 |
| 495-1181 |
558 | itemList = d->indexedItems; executed (the execution status of this line is deduced): itemList = d->indexedItems; | - |
559 | } else { executed: } Execution Count:1181 | 1181 |
560 | itemList = d->indexedItems + d->unindexedItems; executed (the execution status of this line is deduced): itemList = d->indexedItems + d->unindexedItems; | - |
561 | } executed: } Execution Count:495 | 495 |
562 | } else { | - |
563 | // Rebuild the list of items to avoid holes. ### We could also just | - |
564 | // compress the item lists at this point. | - |
565 | foreach (QGraphicsItem *item, d->indexedItems + d->unindexedItems) { executed (the execution status of this line is deduced): for (QForeachContainer<__typeof__(d->indexedItems + d->unindexedItems)> _container_(d->indexedItems + d->unindexedItems); !_container_.brk && _container_.i != _container_.e; __extension__ ({ ++_container_.brk; ++_container_.i; })) for (QGraphicsItem *item = *_container_.i;; __extension__ ({--_container_.brk; break;})) { | - |
566 | if (item) evaluated: item yes Evaluation Count:4 | yes Evaluation Count:5 |
| 4-5 |
567 | itemList << item; executed: itemList << item; Execution Count:4 | 4 |
568 | } executed: } Execution Count:9 | 9 |
569 | } executed: } Execution Count:3 | 3 |
570 | if (order != -1) { partially evaluated: order != -1 yes Evaluation Count:1679 | no Evaluation Count:0 |
| 0-1679 |
571 | //We sort descending order | - |
572 | d->sortItems(&itemList, order, d->sortCacheEnabled); executed (the execution status of this line is deduced): d->sortItems(&itemList, order, d->sortCacheEnabled); | - |
573 | } executed: } Execution Count:1679 | 1679 |
574 | return itemList; executed: return itemList; Execution Count:1679 | 1679 |
575 | } | - |
576 | | - |
577 | /*! | - |
578 | \property QGraphicsSceneBspTreeIndex::bspTreeDepth | - |
579 | \brief the depth of the BSP index tree | - |
580 | \since 4.6 | - |
581 | | - |
582 | This value determines the depth of BSP tree. The depth | - |
583 | directly affects performance and memory usage; the latter | - |
584 | growing exponentially with the depth of the tree. With an optimal tree | - |
585 | depth, the index can instantly determine the locality of items, even | - |
586 | for scenes with thousands or millions of items. This also greatly improves | - |
587 | rendering performance. | - |
588 | | - |
589 | By default, the value is 0, in which case Qt will guess a reasonable | - |
590 | default depth based on the size, location and number of items in the | - |
591 | scene. If these parameters change frequently, however, you may experience | - |
592 | slowdowns as the index retunes the depth internally. You can avoid | - |
593 | potential slowdowns by fixating the tree depth through setting this | - |
594 | property. | - |
595 | | - |
596 | The depth of the tree and the size of the scene rectangle decide the | - |
597 | granularity of the scene's partitioning. The size of each scene segment is | - |
598 | determined by the following algorithm: | - |
599 | | - |
600 | The BSP tree has an optimal size when each segment contains between 0 and | - |
601 | 10 items. | - |
602 | | - |
603 | */ | - |
604 | int QGraphicsSceneBspTreeIndex::bspTreeDepth() const | - |
605 | { | - |
606 | Q_D(const QGraphicsSceneBspTreeIndex); never executed (the execution status of this line is deduced): const QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
607 | return d->bspTreeDepth; never executed: return d->bspTreeDepth; | 0 |
608 | } | - |
609 | | - |
610 | void QGraphicsSceneBspTreeIndex::setBspTreeDepth(int depth) | - |
611 | { | - |
612 | Q_D(QGraphicsSceneBspTreeIndex); never executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
613 | if (d->bspTreeDepth == depth) never evaluated: d->bspTreeDepth == depth | 0 |
614 | return; | 0 |
615 | d->bspTreeDepth = depth; never executed (the execution status of this line is deduced): d->bspTreeDepth = depth; | - |
616 | d->resetIndex(); never executed (the execution status of this line is deduced): d->resetIndex(); | - |
617 | } | 0 |
618 | | - |
619 | /*! | - |
620 | \internal | - |
621 | | - |
622 | This method react to the \a rect change of the scene and | - |
623 | reset the BSP tree index. | - |
624 | */ | - |
625 | void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) | - |
626 | { | - |
627 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
628 | d->sceneRect = rect; executed (the execution status of this line is deduced): d->sceneRect = rect; | - |
629 | d->resetIndex(); executed (the execution status of this line is deduced): d->resetIndex(); | - |
630 | } executed: } Execution Count:833 | 833 |
631 | | - |
632 | /*! | - |
633 | \internal | - |
634 | | - |
635 | This method react to the \a change of the \a item and use the \a value to | - |
636 | update the BSP tree if necessary. | - |
637 | */ | - |
638 | void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) | - |
639 | { | - |
640 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
641 | switch (change) { | - |
642 | case QGraphicsItem::ItemFlagsChange: { | - |
643 | // Handle ItemIgnoresTransformations | - |
644 | QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value); executed (the execution status of this line is deduced): QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value); | - |
645 | bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; executed (the execution status of this line is deduced): bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; | - |
646 | bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations; executed (the execution status of this line is deduced): bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations; | - |
647 | bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; executed (the execution status of this line is deduced): bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; | - |
648 | bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape; executed (the execution status of this line is deduced): bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape; | - |
649 | if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { evaluated: (ignoredTransform != willIgnoreTransform) yes Evaluation Count:1 | yes Evaluation Count:25 |
evaluated: (clipsChildren != willClipChildren) yes Evaluation Count:9 | yes Evaluation Count:16 |
| 1-25 |
650 | QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); executed (the execution status of this line is deduced): QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); | - |
651 | // Remove item and its descendants from the index and append | - |
652 | // them to the list of unindexed items. Then, when the index | - |
653 | // is updated, they will be put into the bsp-tree or the list | - |
654 | // of untransformable items. | - |
655 | d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); executed (the execution status of this line is deduced): d->removeItem(thatItem, true, true); | - |
656 | } executed: } Execution Count:10 | 10 |
657 | break; executed: break; Execution Count:26 | 26 |
658 | } | - |
659 | case QGraphicsItem::ItemZValueChange: | - |
660 | d->invalidateSortCache(); executed (the execution status of this line is deduced): d->invalidateSortCache(); | - |
661 | break; executed: break; Execution Count:55 | 55 |
662 | case QGraphicsItem::ItemParentChange: { | - |
663 | d->invalidateSortCache(); executed (the execution status of this line is deduced): d->invalidateSortCache(); | - |
664 | // Handle ItemIgnoresTransformations | - |
665 | const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value); executed (the execution status of this line is deduced): const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value); | - |
666 | bool ignoredTransform = item->d_ptr->itemIsUntransformable(); executed (the execution status of this line is deduced): bool ignoredTransform = item->d_ptr->itemIsUntransformable(); | - |
667 | bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) partially evaluated: (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) no Evaluation Count:0 | yes Evaluation Count:15 |
| 0-15 |
668 | || (newParent && newParent->d_ptr->itemIsUntransformable()); partially evaluated: newParent yes Evaluation Count:15 | no Evaluation Count:0 |
partially evaluated: newParent->d_ptr->itemIsUntransformable() no Evaluation Count:0 | yes Evaluation Count:15 |
| 0-15 |
669 | bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren; executed (the execution status of this line is deduced): bool ancestorClippedChildren = item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren; | - |
670 | bool ancestorWillClipChildren = newParent partially evaluated: newParent yes Evaluation Count:15 | no Evaluation Count:0 |
| 0-15 |
671 | && ((newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) evaluated: (newParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape) yes Evaluation Count:3 | yes Evaluation Count:12 |
| 3-12 |
672 | || (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)); partially evaluated: (newParent->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren) no Evaluation Count:0 | yes Evaluation Count:12 |
| 0-12 |
673 | if ((ignoredTransform != willIgnoreTransform) || (ancestorClippedChildren != ancestorWillClipChildren)) { partially evaluated: (ignoredTransform != willIgnoreTransform) no Evaluation Count:0 | yes Evaluation Count:15 |
evaluated: (ancestorClippedChildren != ancestorWillClipChildren) yes Evaluation Count:3 | yes Evaluation Count:12 |
| 0-15 |
674 | QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); executed (the execution status of this line is deduced): QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); | - |
675 | // Remove item and its descendants from the index and append | - |
676 | // them to the list of unindexed items. Then, when the index | - |
677 | // is updated, they will be put into the bsp-tree or the list | - |
678 | // of untransformable items. | - |
679 | d->removeItem(thatItem, /*recursive=*/true, /*moveToUnidexedItems=*/true); executed (the execution status of this line is deduced): d->removeItem(thatItem, true, true); | - |
680 | } executed: } Execution Count:3 | 3 |
681 | break; executed: break; Execution Count:15 | 15 |
682 | } | - |
683 | default: | - |
684 | break; | 0 |
685 | } | - |
686 | } executed: } Execution Count:96 | 96 |
687 | /*! | - |
688 | \reimp | - |
689 | | - |
690 | Used to catch the timer event. | - |
691 | | - |
692 | \internal | - |
693 | */ | - |
694 | bool QGraphicsSceneBspTreeIndex::event(QEvent *event) | - |
695 | { | - |
696 | Q_D(QGraphicsSceneBspTreeIndex); executed (the execution status of this line is deduced): QGraphicsSceneBspTreeIndexPrivate * const d = d_func(); | - |
697 | switch (event->type()) { | - |
698 | case QEvent::Timer: | - |
699 | if (d->indexTimerId && static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId) { partially evaluated: d->indexTimerId yes Evaluation Count:316 | no Evaluation Count:0 |
partially evaluated: static_cast<QTimerEvent *>(event)->timerId() == d->indexTimerId yes Evaluation Count:316 | no Evaluation Count:0 |
| 0-316 |
700 | if (d->restartIndexTimer) { evaluated: d->restartIndexTimer yes Evaluation Count:221 | yes Evaluation Count:95 |
| 95-221 |
701 | d->restartIndexTimer = false; executed (the execution status of this line is deduced): d->restartIndexTimer = false; | - |
702 | } else { executed: } Execution Count:221 | 221 |
703 | // this call will kill the timer | - |
704 | d->_q_updateIndex(); executed (the execution status of this line is deduced): d->_q_updateIndex(); | - |
705 | } executed: } Execution Count:95 | 95 |
706 | } | - |
707 | // Fallthrough intended - support timers in subclasses. | - |
708 | default: | - |
709 | return QObject::event(event); executed: return QObject::event(event); Execution Count:316 | 316 |
710 | } | - |
711 | return true; never executed: return true; | 0 |
712 | } | - |
713 | | - |
714 | QT_END_NAMESPACE | - |
715 | | - |
716 | #include "moc_qgraphicsscenebsptreeindex_p.cpp" | - |
717 | | - |
718 | #endif // QT_NO_GRAPHICSVIEW | - |
719 | | - |
720 | | - |
| | |