Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: Source/platform/graphics/paint/DisplayItemList.cpp

Issue 1315993004: Implement a paint offset cache for slimming paint v2 (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase more (world moved in the past hour) Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/TraceEvent.h" 9 #include "platform/TraceEvent.h"
10 #include "platform/graphics/paint/DrawingDisplayItem.h" 10 #include "platform/graphics/paint/DrawingDisplayItem.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 142 }
143 143
144 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const 144 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const
145 { 145 {
146 if (skippingCache()) 146 if (skippingCache())
147 return false; 147 return false;
148 updateValidlyCachedClientsIfNeeded(); 148 updateValidlyCachedClientsIfNeeded();
149 return m_validlyCachedClients.contains(client); 149 return m_validlyCachedClients.contains(client);
150 } 150 }
151 151
152 void DisplayItemList::invalidatePaintOffset(DisplayItemClient client)
153 {
154 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
155
156 updateValidlyCachedClientsIfNeeded();
157 m_validlyCachedClients.remove(client);
158
159 #if ENABLE(ASSERT)
160 m_clientsWithPaintOffsetInvalidations.add(client);
161
162 // Ensure no phases slipped in using the old paint offset which would indica te
163 // different phases used different paint offsets, which should not happen.
164 for (const auto& item : m_newDisplayItems)
165 ASSERT(!item.isCached() || item.client() != client);
166 #endif
167 }
168
169 #if ENABLE(ASSERT)
170 bool DisplayItemList::paintOffsetWasInvalidated(DisplayItemClient client) const
171 {
172 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
173 return m_clientsWithPaintOffsetInvalidations.contains(client);
174 }
175 #endif
176
177 void DisplayItemList::recordPaintOffset(DisplayItemClient client, const LayoutPo int& paintOffset)
178 {
179 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
180 m_previousPaintOffsets.set(client, paintOffset);
181 }
182
183 bool DisplayItemList::paintOffsetIsUnchanged(DisplayItemClient client, const Lay outPoint& paintOffset) const
184 {
185 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
186 PreviousPaintOffsets::const_iterator it = m_previousPaintOffsets.find(client );
187 if (it == m_previousPaintOffsets.end())
188 return false;
189 return paintOffset == it->value;
190 }
191
192 void DisplayItemList::removeUnneededPaintOffsetEntries()
193 {
194 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
195
196 // This function is only needed temporarily while paint offsets are stored
197 // in a map on the list itself. Because we don't always get notified when
198 // a display item client is removed, we need to infer it to prevent the
199 // paint offset map from growing indefinitely. This is achieved by just
200 // removing any paint offset clients that are no longer in the full list.
201
202 HashSet<DisplayItemClient> paintOffsetClientsToRemove;
203 for (auto& client : m_previousPaintOffsets.keys())
204 paintOffsetClientsToRemove.add(client);
205 for (auto& item : m_currentDisplayItems)
206 paintOffsetClientsToRemove.remove(item.client());
207
208 for (auto& client : paintOffsetClientsToRemove)
209 m_previousPaintOffsets.remove(client);
210 }
211
152 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems & list) 212 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, con st DisplayItemIndicesByClientMap& displayItemIndicesByClient, const DisplayItems & list)
153 { 213 {
154 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(id.client); 214 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(id.client);
155 if (it == displayItemIndicesByClient.end()) 215 if (it == displayItemIndicesByClient.end())
156 return kNotFound; 216 return kNotFound;
157 217
158 const Vector<size_t>& indices = it->value; 218 const Vector<size_t>& indices = it->value;
159 for (size_t index : indices) { 219 for (size_t index : indices) {
160 const DisplayItem& existingItem = list[index]; 220 const DisplayItem& existingItem = list[index];
161 ASSERT(!existingItem.isValid() || existingItem.client() == id.client); 221 ASSERT(!existingItem.isValid() || existingItem.client() == id.client);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 #endif 317 #endif
258 318
259 if (m_currentDisplayItems.isEmpty()) { 319 if (m_currentDisplayItems.isEmpty()) {
260 #if ENABLE(ASSERT) 320 #if ENABLE(ASSERT)
261 for (const auto& item : m_newDisplayItems) 321 for (const auto& item : m_newDisplayItems)
262 ASSERT(!item.isCached()); 322 ASSERT(!item.isCached());
263 #endif 323 #endif
264 m_currentDisplayItems.swap(m_newDisplayItems); 324 m_currentDisplayItems.swap(m_newDisplayItems);
265 m_validlyCachedClientsDirty = true; 325 m_validlyCachedClientsDirty = true;
266 m_numCachedItems = 0; 326 m_numCachedItems = 0;
327 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
328 removeUnneededPaintOffsetEntries();
267 return; 329 return;
268 } 330 }
269 331
270 updateValidlyCachedClientsIfNeeded(); 332 updateValidlyCachedClientsIfNeeded();
271 333
272 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched 334 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched
273 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched 335 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched
274 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when 336 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when
275 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems 337 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems
276 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. 338 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time.
(...skipping 19 matching lines...) Expand all
296 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) { 358 for (DisplayItems::iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) {
297 const DisplayItem& newDisplayItem = *newIt; 359 const DisplayItem& newDisplayItem = *newIt;
298 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId(); 360 const DisplayItem::Id newDisplayItemId = newDisplayItem.nonCachedId();
299 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type; 361 bool newDisplayItemHasCachedType = newDisplayItem.type() != newDisplayIt emId.type;
300 362
301 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt); 363 bool isSynchronized = currentIt != currentEnd && newDisplayItemId.matche s(*currentIt);
302 364
303 if (newDisplayItemHasCachedType) { 365 if (newDisplayItemHasCachedType) {
304 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled()); 366 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled());
305 ASSERT(newDisplayItem.isCached()); 367 ASSERT(newDisplayItem.isCached());
306 ASSERT(clientCacheIsValid(newDisplayItem.client())); 368 ASSERT(clientCacheIsValid(newDisplayItem.client()) || (RuntimeEnable dFeatures::slimmingPaintV2Enabled() && !paintOffsetWasInvalidated(newDisplayItem .client())));
307 if (!isSynchronized) { 369 if (!isSynchronized) {
308 currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId , outOfOrderIndexContext); 370 currentIt = findOutOfOrderCachedItem(currentIt, newDisplayItemId , outOfOrderIndexContext);
309 371
310 if (currentIt == currentEnd) { 372 if (currentIt == currentEnd) {
311 #ifndef NDEBUG 373 #ifndef NDEBUG
312 showDebugData(); 374 showDebugData();
313 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD isplayItem.asDebugString().utf8().data()); 375 WTFLogAlways("%s not found in m_currentDisplayItems\n", newD isplayItem.asDebugString().utf8().data());
314 #endif 376 #endif
315 ASSERT_NOT_REACHED(); 377 ASSERT_NOT_REACHED();
316 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug 378 // We did not find the cached display item. This should be i mpossible, but may occur if there is a bug
317 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids. 379 // in the system, such as under-invalidation, incorrect cach e checking or duplicate display ids.
318 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list. 380 // In this case, attempt to recover rather than crashing or bailing on display of the rest of the display list.
319 continue; 381 continue;
320 } 382 }
321 } 383 }
322 384
323 if (newDisplayItem.isCachedDrawing()) { 385 if (newDisplayItem.isCachedDrawing()) {
324 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()) ; 386 updatedList.appendByMoving(*currentIt, currentIt->derivedSize()) ;
325 ++currentIt; 387 ++currentIt;
326 } else { 388 } else {
327 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence); 389 ASSERT(newDisplayItem.type() == DisplayItem::CachedSubsequence);
328 copyCachedSubsequence(currentIt, updatedList); 390 copyCachedSubsequence(currentIt, updatedList);
329 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence) ; 391 ASSERT(updatedList.last().type() == DisplayItem::EndSubsequence) ;
330 } 392 }
331 } else { 393 } else {
332 #if ENABLE(ASSERT) 394 #if ENABLE(ASSERT)
333 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) 395 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) {
334 checkCachedDisplayItemIsUnchanged(newDisplayItem, outOfOrderInde xContext.displayItemIndicesByClient); 396 checkCachedDisplayItemIsUnchanged(newDisplayItem, outOfOrderInde xContext.displayItemIndicesByClient);
335 else 397 } else {
336 ASSERT(!newDisplayItem.isDrawing() || newDisplayItem.skippedCach e() || !clientCacheIsValid(newDisplayItem.client())); 398 ASSERT(!newDisplayItem.isDrawing()
337 #endif // ENABLE(ASSERT) 399 || newDisplayItem.skippedCache()
400 || !clientCacheIsValid(newDisplayItem.client())
401 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && pain tOffsetWasInvalidated(newDisplayItem.client())));
402 }
403 #endif
338 updatedList.appendByMoving(*newIt, newIt->derivedSize()); 404 updatedList.appendByMoving(*newIt, newIt->derivedSize());
339 405
340 if (isSynchronized) 406 if (isSynchronized)
341 ++currentIt; 407 ++currentIt;
342 } 408 }
343 } 409 }
344 410
345 #if ENABLE(ASSERT) 411 #if ENABLE(ASSERT)
346 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 412 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
347 checkNoRemainingCachedDisplayItems(); 413 checkNoRemainingCachedDisplayItems();
348 #endif // ENABLE(ASSERT) 414 #endif // ENABLE(ASSERT)
349 415
350 m_newDisplayItems.clear(); 416 m_newDisplayItems.clear();
351 m_validlyCachedClientsDirty = true; 417 m_validlyCachedClientsDirty = true;
352 m_currentDisplayItems.swap(updatedList); 418 m_currentDisplayItems.swap(updatedList);
353 m_numCachedItems = 0; 419 m_numCachedItems = 0;
420
421 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
422 removeUnneededPaintOffsetEntries();
423
424 #if ENABLE(ASSERT)
425 m_clientsWithPaintOffsetInvalidations.clear();
426 #endif
354 } 427 }
355 428
356 size_t DisplayItemList::approximateUnsharedMemoryUsage() const 429 size_t DisplayItemList::approximateUnsharedMemoryUsage() const
357 { 430 {
358 size_t memoryUsage = sizeof(*this); 431 size_t memoryUsage = sizeof(*this);
359 432
360 // Memory outside this class due to m_currentDisplayItems. 433 // Memory outside this class due to m_currentDisplayItems.
361 memoryUsage += m_currentDisplayItems.memoryUsageInBytes(); 434 memoryUsage += m_currentDisplayItems.memoryUsageInBytes();
362 435
363 // TODO(jbroman): If display items begin to have significant external memory 436 // TODO(jbroman): If display items begin to have significant external memory
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 624
552 void DisplayItemList::replay(GraphicsContext& context) 625 void DisplayItemList::replay(GraphicsContext& context)
553 { 626 {
554 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); 627 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay");
555 ASSERT(m_newDisplayItems.isEmpty()); 628 ASSERT(m_newDisplayItems.isEmpty());
556 for (DisplayItem& displayItem : m_currentDisplayItems) 629 for (DisplayItem& displayItem : m_currentDisplayItems)
557 displayItem.replay(context); 630 displayItem.replay(context);
558 } 631 }
559 632
560 } // namespace blink 633 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/paint/DisplayItemList.h ('k') | Source/platform/graphics/paint/DrawingRecorder.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698