OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "platform/graphics/paint/DisplayItemList.h" | 6 #include "platform/graphics/paint/DisplayItemList.h" |
7 | 7 |
8 #include "platform/NotImplemented.h" | 8 #include "platform/NotImplemented.h" |
9 #include "platform/RuntimeEnabledFeatures.h" | 9 #include "platform/RuntimeEnabledFeatures.h" |
10 #include "platform/TraceEvent.h" | 10 #include "platform/TraceEvent.h" |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 m_scopeStack.append(m_nextScope++); | 105 m_scopeStack.append(m_nextScope++); |
106 beginSkippingCache(); | 106 beginSkippingCache(); |
107 } | 107 } |
108 | 108 |
109 void DisplayItemList::endScope() | 109 void DisplayItemList::endScope() |
110 { | 110 { |
111 m_scopeStack.removeLast(); | 111 m_scopeStack.removeLast(); |
112 endSkippingCache(); | 112 endSkippingCache(); |
113 } | 113 } |
114 | 114 |
115 void DisplayItemList::invalidate(DisplayItemClient client) | 115 void DisplayItemList::invalidate(DisplayItemClient client) |
chrishtr
2015/08/28 17:10:47
Don't you also want to invalidate the paint offset
| |
116 { | 116 { |
117 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 117 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
118 // Can only be called during layout/paintInvalidation, not during painting. | 118 // Can only be called during layout/paintInvalidation, not during painting. |
119 ASSERT(m_newDisplayItems.isEmpty()); | 119 ASSERT(m_newDisplayItems.isEmpty()); |
120 updateValidlyCachedClientsIfNeeded(); | 120 updateValidlyCachedClientsIfNeeded(); |
121 m_validlyCachedClients.remove(client); | 121 m_validlyCachedClients.remove(client); |
122 } | 122 } |
123 | 123 |
124 void DisplayItemList::invalidateAll() | 124 void DisplayItemList::invalidateAll() |
125 { | 125 { |
126 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); | 126 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); |
127 // Can only be called during layout/paintInvalidation, not during painting. | 127 // Can only be called during layout/paintInvalidation, not during painting. |
128 ASSERT(m_newDisplayItems.isEmpty()); | 128 ASSERT(m_newDisplayItems.isEmpty()); |
129 m_currentDisplayItems.clear(); | 129 m_currentDisplayItems.clear(); |
130 m_validlyCachedClients.clear(); | 130 m_validlyCachedClients.clear(); |
131 m_validlyCachedClientsDirty = false; | 131 m_validlyCachedClientsDirty = false; |
132 } | 132 } |
133 | 133 |
134 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const | 134 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const |
135 { | 135 { |
136 if (skippingCache()) | 136 if (skippingCache()) |
137 return false; | 137 return false; |
138 updateValidlyCachedClientsIfNeeded(); | 138 updateValidlyCachedClientsIfNeeded(); |
139 return m_validlyCachedClients.contains(client); | 139 return m_validlyCachedClients.contains(client); |
140 } | 140 } |
141 | 141 |
142 void DisplayItemList::invalidatePaintOffset(DisplayItemClient client) | |
143 { | |
144 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
145 | |
146 updateValidlyCachedClientsIfNeeded(); | |
147 m_validlyCachedClients.remove(client); | |
148 | |
149 #if ENABLE(ASSERT) | |
150 m_clientsWithPaintOffsetInvalidations.add(client); | |
151 | |
152 // Ensure no phases slipped in using the old paint offset which would indica te | |
153 // different phases used different paint offsets, which should not happen. | |
154 for (const auto& item : m_newDisplayItems) | |
155 ASSERT(!item.isCached() || item.client() != client); | |
156 #endif | |
157 } | |
158 | |
159 #if ENABLE(ASSERT) | |
160 bool DisplayItemList::paintOffsetWasInvalidated(DisplayItemClient client) const | |
161 { | |
162 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
163 return m_clientsWithPaintOffsetInvalidations.contains(client); | |
164 } | |
165 #endif | |
166 | |
167 void DisplayItemList::recordPaintOffset(DisplayItemClient client, const LayoutPo int& paintOffset) | |
168 { | |
169 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
170 m_previousPaintOffsets.set(client, paintOffset); | |
171 } | |
172 | |
173 bool DisplayItemList::paintOffsetWasRecorded(DisplayItemClient client, const Lay outPoint& paintOffset) const | |
chrishtr
2015/08/28 17:10:47
This name doesn't seem quite right. Shouldn't it b
| |
174 { | |
175 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
176 PreviousPaintOffsets::const_iterator it = m_previousPaintOffsets.find(client ); | |
177 if (it == m_previousPaintOffsets.end()) | |
178 return false; | |
179 return paintOffset == it->value; | |
180 } | |
181 | |
182 void DisplayItemList::removeUnneededPaintOffsetEntries() | |
183 { | |
184 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
185 | |
186 // This function is only needed temporarily while paint offsets are stored | |
187 // in a map on the list itself. Because we don't always get notified when | |
188 // a display item client is removed, we need to infer it to prevent the | |
189 // paint offset map from growing indefinitely. This is achieved by just | |
190 // removing any paint offset clients that are no longer in the full list. | |
191 | |
192 HashSet<DisplayItemClient> paintOffsetClientsToRemove; | |
193 for (auto& client : m_previousPaintOffsets.keys()) | |
194 paintOffsetClientsToRemove.add(client); | |
195 for (auto& item : m_currentDisplayItems) | |
196 paintOffsetClientsToRemove.remove(item.client()); | |
197 | |
198 for (auto& client : paintOffsetClientsToRemove) | |
199 m_previousPaintOffsets.remove(client); | |
200 } | |
201 | |
142 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems & list) | 202 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems & list) |
143 { | 203 { |
144 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(id.client); | 204 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(id.client); |
145 if (it == displayItemIndicesByClient.end()) | 205 if (it == displayItemIndicesByClient.end()) |
146 return kNotFound; | 206 return kNotFound; |
147 | 207 |
148 const Vector<size_t>& indices = it->value; | 208 const Vector<size_t>& indices = it->value; |
149 for (size_t index : indices) { | 209 for (size_t index : indices) { |
150 const DisplayItem& existingItem = list[index]; | 210 const DisplayItem& existingItem = list[index]; |
151 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); | 211 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 #endif | 307 #endif |
248 | 308 |
249 if (m_currentDisplayItems.isEmpty()) { | 309 if (m_currentDisplayItems.isEmpty()) { |
250 #if ENABLE(ASSERT) | 310 #if ENABLE(ASSERT) |
251 for (const auto& item : m_newDisplayItems) | 311 for (const auto& item : m_newDisplayItems) |
252 ASSERT(!item.isCached()); | 312 ASSERT(!item.isCached()); |
253 #endif | 313 #endif |
254 m_currentDisplayItems.swap(m_newDisplayItems); | 314 m_currentDisplayItems.swap(m_newDisplayItems); |
255 m_validlyCachedClientsDirty = true; | 315 m_validlyCachedClientsDirty = true; |
256 m_numCachedItems = 0; | 316 m_numCachedItems = 0; |
317 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
318 removeUnneededPaintOffsetEntries(); | |
257 return; | 319 return; |
258 } | 320 } |
259 | 321 |
260 updateValidlyCachedClientsIfNeeded(); | 322 updateValidlyCachedClientsIfNeeded(); |
261 | 323 |
262 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched | 324 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched |
263 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched | 325 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched |
264 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when | 326 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when |
265 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems | 327 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems |
266 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. | 328 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. |
(...skipping 19 matching lines...) Expand all Loading... | |
286 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) { | 348 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) { |
287 const DisplayItem& newDisplayItem = *newIt; | 349 const DisplayItem& newDisplayItem = *newIt; |
288 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); | 350 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); |
289 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type; | 351 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type; |
290 | 352 |
291 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); | 353 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); |
292 | 354 |
293 if (newDisplayItemHasCachedType) { | 355 if (newDisplayItemHasCachedType) { |
294 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled()); | 356 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled()); |
295 ASSERT(newDisplayItem.isCached()); | 357 ASSERT(newDisplayItem.isCached()); |
296 ASSERT(clientCacheIsValid(newDisplayItem.client())); | 358 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintV2Enabled() && !paintOffsetWasInvalidated(newDisplayItem .client()))); |
297 if (!isSynchronized) { | 359 if (!isSynchronized) { |
298 currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId , outOfOrderIndexContext); | 360 currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId , outOfOrderIndexContext); |
299 | 361 |
300 if (currentIt == currentEnd) { | 362 if (currentIt == currentEnd) { |
301 #ifndef NDEBUG | 363 #ifndef NDEBUG |
302 showDebugData(); | 364 showDebugData(); |
303 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD isplayItem.asDebugString().utf8().data()); | 365 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD isplayItem.asDebugString().utf8().data()); |
304 #endif | 366 #endif |
305 ASSERT_NOT_REACHED(); | 367 ASSERT_NOT_REACHED(); |
306 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug | 368 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug |
307 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids. | 369 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids. |
308 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list. | 370 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list. |
309 continue; | 371 continue; |
310 } | 372 } |
311 } | 373 } |
312 | 374 |
313 if (newDisplayItem.isCachedDrawing()) { | 375 if (newDisplayItem.isCachedDrawing()) { |
314 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()) ; | 376 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()) ; |
315 ++currentIt; | 377 ++currentIt; |
316 } else { | 378 } else { |
317 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); | 379 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); |
318 copyCachedSubsequence(currentIt, updatedList); | 380 copyCachedSubsequence(currentIt, updatedList); |
319 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence) ; | 381 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence) ; |
320 } | 382 } |
321 } else { | 383 } else { |
322 #if ENABLE(ASSERT) | 384 #if ENABLE(ASSERT) |
323 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) | 385 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) { |
324 checkCachedDisplayItemIsUnchanged(newDisplayItem, outOfOrderInde xContext.displayItemIndicesByClient); | 386 checkCachedDisplayItemIsUnchanged(newDisplayItem, outOfOrderInde xContext.displayItemIndicesByClient); |
325 else | 387 } else { |
326 ASSERT(!newDisplayItem.isDrawing() || newDisplayItem.skippedCach e() || !clientCacheIsValid(newDisplayItem.client())); | 388 ASSERT(!newDisplayItem.isDrawing() |
327 #endif // ENABLE(ASSERT) | 389 || newDisplayItem.skippedCache() |
390 || !clientCacheIsValid(newDisplayItem.client()) | |
391 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && pain tOffsetWasInvalidated(newDisplayItem.client()))); | |
392 } | |
393 #endif | |
328 updatedList.appendByMoving(*newIt, newIt->derivedSize()); | 394 updatedList.appendByMoving(*newIt, newIt->derivedSize()); |
329 | 395 |
330 if (isSynchronized) | 396 if (isSynchronized) |
331 ++currentIt; | 397 ++currentIt; |
332 } | 398 } |
333 } | 399 } |
334 | 400 |
335 #if ENABLE(ASSERT) | 401 #if ENABLE(ASSERT) |
336 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) | 402 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) |
337 checkNoRemainingCachedDisplayItems(); | 403 checkNoRemainingCachedDisplayItems(); |
338 #endif // ENABLE(ASSERT) | 404 #endif // ENABLE(ASSERT) |
339 | 405 |
340 m_newDisplayItems.clear(); | 406 m_newDisplayItems.clear(); |
341 m_validlyCachedClientsDirty = true; | 407 m_validlyCachedClientsDirty = true; |
342 m_currentDisplayItems.swap(updatedList); | 408 m_currentDisplayItems.swap(updatedList); |
343 m_numCachedItems = 0; | 409 m_numCachedItems = 0; |
410 | |
411 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | |
412 removeUnneededPaintOffsetEntries(); | |
413 | |
414 #if ENABLE(ASSERT) | |
415 m_clientsWithPaintOffsetInvalidations.clear(); | |
416 #endif | |
344 } | 417 } |
345 | 418 |
346 size_t DisplayItemList::approximateUnsharedMemoryUsage() const | 419 size_t DisplayItemList::approximateUnsharedMemoryUsage() const |
347 { | 420 { |
348 size_t memoryUsage = sizeof(*this); | 421 size_t memoryUsage = sizeof(*this); |
349 | 422 |
350 // Memory outside this class due to m_currentDisplayItems. | 423 // Memory outside this class due to m_currentDisplayItems. |
351 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); | 424 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); |
352 | 425 |
353 // TODO(jbroman): If display items begin to have significant external memory | 426 // TODO(jbroman): If display items begin to have significant external memory |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
541 | 614 |
542 void DisplayItemList::replay(GraphicsContext& context) | 615 void DisplayItemList::replay(GraphicsContext& context) |
543 { | 616 { |
544 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); | 617 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); |
545 ASSERT(m_newDisplayItems.isEmpty()); | 618 ASSERT(m_newDisplayItems.isEmpty()); |
546 for (DisplayItem& displayItem : m_currentDisplayItems) | 619 for (DisplayItem& displayItem : m_currentDisplayItems) |
547 displayItem.replay(context); | 620 displayItem.replay(context); |
548 } | 621 } |
549 | 622 |
550 } // namespace blink | 623 } // namespace blink |
OLD | NEW |