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

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

Issue 1157653005: Move use of DisplayItemList's vector behind an explicit DisplayItems interface. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: DisplayItems must be noncopyable (Windows build fix) Created 5 years, 6 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 | Annotate | Revision Log
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/RuntimeEnabledFeatures.h" 9 #include "platform/RuntimeEnabledFeatures.h"
10 #include "platform/TraceEvent.h" 10 #include "platform/TraceEvent.h"
(...skipping 22 matching lines...) Expand all
33 } 33 }
34 34
35 void DisplayItemList::add(WTF::PassOwnPtr<DisplayItem> displayItem) 35 void DisplayItemList::add(WTF::PassOwnPtr<DisplayItem> displayItem)
36 { 36 {
37 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled()); 37 ASSERT(RuntimeEnabledFeatures::slimmingPaintEnabled());
38 ASSERT(!m_constructionDisabled); 38 ASSERT(!m_constructionDisabled);
39 ASSERT(!skippingCache() || !displayItem->isCached()); 39 ASSERT(!skippingCache() || !displayItem->isCached());
40 40
41 if (displayItem->isEnd()) { 41 if (displayItem->isEnd()) {
42 ASSERT(!m_newDisplayItems.isEmpty()); 42 ASSERT(!m_newDisplayItems.isEmpty());
43 if (m_newDisplayItems.last()->isBegin() && !m_newDisplayItems.last()->dr awsContent()) { 43 if (m_newDisplayItems.last().isBegin() && !m_newDisplayItems.last().draw sContent()) {
44 ASSERT(displayItem->isEndAndPairedWith(*m_newDisplayItems.last())); 44 ASSERT(displayItem->isEndAndPairedWith(m_newDisplayItems.last().type ()));
45 // Remove the beginning display item of this empty pair. 45 // Remove the beginning display item of this empty pair.
46 m_newDisplayItems.removeLast(); 46 m_newDisplayItems.removeLast();
47 #if ENABLE(ASSERT) 47 #if ENABLE(ASSERT)
48 // Also remove the index pointing to the removed display item. 48 // Also remove the index pointing to the removed display item.
49 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndices ByClient.find(displayItem->client()); 49 DisplayItemIndicesByClientMap::iterator it = m_newDisplayItemIndices ByClient.find(displayItem->client());
50 if (it != m_newDisplayItemIndicesByClient.end()) { 50 if (it != m_newDisplayItemIndicesByClient.end()) {
51 Vector<size_t>& indices = it->value; 51 Vector<size_t>& indices = it->value;
52 if (!indices.isEmpty() && indices.last() == m_newDisplayItems.si ze()) 52 if (!indices.isEmpty() && indices.last() == m_newDisplayItems.si ze())
53 indices.removeLast(); 53 indices.removeLast();
54 } 54 }
55 #endif 55 #endif
56 return; 56 return;
57 } 57 }
58 } 58 }
59 59
60 if (!m_scopeStack.isEmpty()) 60 if (!m_scopeStack.isEmpty())
61 displayItem->setScope(m_scopeStack.last().id, m_scopeStack.last().client ); 61 displayItem->setScope(m_scopeStack.last().id, m_scopeStack.last().client );
62 62
63 #if ENABLE(ASSERT) 63 #if ENABLE(ASSERT)
64 size_t index = findMatchingItemFromIndex(*displayItem, displayItem->type(), m_newDisplayItemIndicesByClient, m_newDisplayItems); 64 size_t index = findMatchingItemFromIndex(displayItem->id(), displayItem->typ e(), m_newDisplayItemIndicesByClient, m_newDisplayItems);
65 if (index != kNotFound) { 65 if (index != kNotFound) {
66 #ifndef NDEBUG 66 #ifndef NDEBUG
67 showDebugData(); 67 showDebugData();
68 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n", 68 WTFLogAlways("DisplayItem %s has duplicated id with previous %s (index=% d)\n",
69 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index] ->asDebugString().utf8().data(), static_cast<int>(index)); 69 displayItem->asDebugString().utf8().data(), m_newDisplayItems[index] .asDebugString().utf8().data(), static_cast<int>(index));
70 #endif 70 #endif
71 ASSERT_NOT_REACHED(); 71 ASSERT_NOT_REACHED();
72 } 72 }
73 addItemToIndex(*displayItem, m_newDisplayItems.size(), m_newDisplayItemIndic esByClient); 73 addItemToIndex(displayItem->client(), displayItem->type(), m_newDisplayItems .size(), m_newDisplayItemIndicesByClient);
74 #endif // ENABLE(ASSERT) 74 #endif // ENABLE(ASSERT)
75 75
76 ASSERT(!displayItem->skippedCache()); // Only DisplayItemList can set the fl ag. 76 ASSERT(!displayItem->skippedCache()); // Only DisplayItemList can set the fl ag.
77 if (skippingCache()) 77 if (skippingCache())
78 displayItem->setSkippedCache(); 78 displayItem->setSkippedCache();
79 79
80 m_newDisplayItems.append(displayItem); 80 m_newDisplayItems.append(displayItem);
81 } 81 }
82 82
83 void DisplayItemList::beginScope(DisplayItemClient client) 83 void DisplayItemList::beginScope(DisplayItemClient client)
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 } 118 }
119 119
120 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const 120 bool DisplayItemList::clientCacheIsValid(DisplayItemClient client) const
121 { 121 {
122 if (skippingCache()) 122 if (skippingCache())
123 return false; 123 return false;
124 updateValidlyCachedClientsIfNeeded(); 124 updateValidlyCachedClientsIfNeeded();
125 return m_validlyCachedClients.contains(client); 125 return m_validlyCachedClients.contains(client);
126 } 126 }
127 127
128 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem& displayItem , DisplayItem::Type matchingType, const DisplayItemIndicesByClientMap& displayIt emIndicesByClient, const DisplayItems& list) 128 size_t DisplayItemList::findMatchingItemFromIndex(const DisplayItem::Id& id, Dis playItem::Type matchingType, const DisplayItemIndicesByClientMap& displayItemInd icesByClient, const DisplayItems& list)
129 { 129 {
130 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(displayItem.client()); 130 DisplayItemIndicesByClientMap::const_iterator it = displayItemIndicesByClien t.find(id.client);
131 if (it == displayItemIndicesByClient.end()) 131 if (it == displayItemIndicesByClient.end())
132 return kNotFound; 132 return kNotFound;
133 133
134 const Vector<size_t>& indices = it->value; 134 const Vector<size_t>& indices = it->value;
135 for (size_t index : indices) { 135 for (size_t index : indices) {
136 const OwnPtr<DisplayItem>& existingItem = list[index]; 136 DisplayItems::ItemHandle existingItem = list[index];
137 ASSERT(!existingItem || existingItem->client() == displayItem.client()); 137 ASSERT(existingItem.isGone() || existingItem.client() == id.client);
138 if (existingItem && existingItem->idsEqual(displayItem, matchingType)) 138 if (!existingItem.isGone() && existingItem.id().equalToExceptForType(id, matchingType))
139 return index; 139 return index;
140 } 140 }
141 141
142 return kNotFound; 142 return kNotFound;
143 } 143 }
144 144
145 void DisplayItemList::addItemToIndex(const DisplayItem& displayItem, size_t inde x, DisplayItemIndicesByClientMap& displayItemIndicesByClient) 145 void DisplayItemList::addItemToIndex(DisplayItemClient client, DisplayItem::Type type, size_t index, DisplayItemIndicesByClientMap& displayItemIndicesByClient)
146 { 146 {
147 // Only need to index DrawingDisplayItems and FIXME: BeginSubtreeDisplayItem s. 147 // Only need to index DrawingDisplayItems and FIXME: BeginSubtreeDisplayItem s.
148 if (!displayItem.isDrawing()) 148 if (!DisplayItem::isDrawingType(type))
149 return; 149 return;
150 150
151 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (displayItem.client()); 151 DisplayItemIndicesByClientMap::iterator it = displayItemIndicesByClient.find (client);
152 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ? 152 Vector<size_t>& indices = it == displayItemIndicesByClient.end() ?
153 displayItemIndicesByClient.add(displayItem.client(), Vector<size_t>()).s toredValue->value : it->value; 153 displayItemIndicesByClient.add(client, Vector<size_t>()).storedValue->va lue : it->value;
154 indices.append(index); 154 indices.append(index);
155 } 155 }
156 156
157 size_t DisplayItemList::findOutOfOrderCachedItem(size_t& currentDisplayItemsInde x, const DisplayItem& displayItem, DisplayItem::Type matchingType, DisplayItemIn dicesByClientMap& displayItemIndicesByClient) 157 DisplayItems::Iterator DisplayItemList::findOutOfOrderCachedItem(DisplayItems::I terator& currentIt, const DisplayItem::Id& id, DisplayItem::Type matchingType, D isplayItemIndicesByClientMap& displayItemIndicesByClient)
158 { 158 {
159 ASSERT(displayItem.isCached()); 159 ASSERT(DisplayItem::isCachedType(id.type));
160 ASSERT(clientCacheIsValid(displayItem.client())); 160 ASSERT(clientCacheIsValid(id.client));
161 161
162 size_t foundIndex = findMatchingItemFromIndex(displayItem, matchingType, dis playItemIndicesByClient, m_currentDisplayItems); 162 size_t foundIndex = findMatchingItemFromIndex(id, matchingType, displayItemI ndicesByClient, m_currentDisplayItems);
163 if (foundIndex != kNotFound) 163 if (foundIndex != kNotFound)
164 return foundIndex; 164 return m_currentDisplayItems.iteratorAt(foundIndex);
165 165
166 return findOutOfOrderCachedItemForward(currentDisplayItemsIndex, displayItem , matchingType, displayItemIndicesByClient); 166 return findOutOfOrderCachedItemForward(currentIt, id, matchingType, displayI temIndicesByClient);
167 } 167 }
168 168
169 // Find forward for the item and index all skipped indexable items. 169 // Find forward for the item and index all skipped indexable items.
170 size_t DisplayItemList::findOutOfOrderCachedItemForward(size_t& currentDisplayIt emsIndex, const DisplayItem& displayItem, DisplayItem::Type matchingType, Displa yItemIndicesByClientMap& displayItemIndicesByClient) 170 DisplayItems::Iterator DisplayItemList::findOutOfOrderCachedItemForward(DisplayI tems::Iterator& currentIt, const DisplayItem::Id& id, DisplayItem::Type matching Type, DisplayItemIndicesByClientMap& displayItemIndicesByClient)
171 { 171 {
172 size_t currentDisplayItemsSize = m_currentDisplayItems.size(); 172 DisplayItems::Iterator currentEnd = m_currentDisplayItems.end();
173 for (; currentDisplayItemsIndex < currentDisplayItemsSize; ++currentDisplayI temsIndex) { 173 for (; currentIt != currentEnd; ++currentIt) {
174 const DisplayItem* item = m_currentDisplayItems[currentDisplayItemsIndex ].get(); 174 DisplayItems::ItemHandle item = *currentIt;
175 if (item && item->isDrawing() && m_validlyCachedClients.contains(item->c lient())) { 175 if (!item.isGone()
176 if (item->idsEqual(displayItem, matchingType)) 176 && DisplayItem::isDrawingType(item.type())
177 return currentDisplayItemsIndex; 177 && m_validlyCachedClients.contains(item.client())) {
178 if (item.id().equalToExceptForType(id, matchingType))
179 return currentIt;
178 180
179 addItemToIndex(*item, currentDisplayItemsIndex, displayItemIndicesBy Client); 181 size_t currentDisplayItemsIndex = m_currentDisplayItems.indexForIter ator(currentIt);
182 addItemToIndex(item.client(), item.type(), currentDisplayItemsIndex, displayItemIndicesByClient);
180 } 183 }
181 } 184 }
182 return kNotFound; 185 return currentEnd;
183 } 186 }
184 187
185 // Update the existing display items by removing invalidated entries, updating 188 // Update the existing display items by removing invalidated entries, updating
186 // repainted ones, and appending new items. 189 // repainted ones, and appending new items.
187 // - For CachedDisplayItem, copy the corresponding cached DrawingDisplayItem; 190 // - For CachedDisplayItem, copy the corresponding cached DrawingDisplayItem;
188 // - FIXME: Re-enable SubtreeCachedDisplayItem: 191 // - FIXME: Re-enable SubtreeCachedDisplayItem:
189 // For SubtreeCachedDisplayItem, copy the cached display items between the 192 // For SubtreeCachedDisplayItem, copy the cached display items between the
190 // corresponding BeginSubtreeDisplayItem and EndSubtreeDisplayItem (incl.); 193 // corresponding BeginSubtreeDisplayItem and EndSubtreeDisplayItem (incl.);
191 // - Otherwise, copy the new display item. 194 // - Otherwise, copy the new display item.
192 // 195 //
193 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|). 196 // The algorithm is O(|m_currentDisplayItems| + |m_newDisplayItems|).
194 // Coefficients are related to the ratio of out-of-order [Subtree]CachedDisplayI tems 197 // Coefficients are related to the ratio of out-of-order [Subtree]CachedDisplayI tems
195 // and the average number of (Drawing|BeginSubtree)DisplayItems per client. 198 // and the average number of (Drawing|BeginSubtree)DisplayItems per client.
196 void DisplayItemList::commitNewDisplayItems() 199 void DisplayItemList::commitNewDisplayItems()
197 { 200 {
198 TRACE_EVENT0("blink,benchmark", "DisplayItemList::commitNewDisplayItems"); 201 TRACE_EVENT0("blink,benchmark", "DisplayItemList::commitNewDisplayItems");
199 202
200 // These data structures are used during painting only. 203 // These data structures are used during painting only.
201 m_clientScopeIdMap.clear(); 204 m_clientScopeIdMap.clear();
202 ASSERT(m_scopeStack.isEmpty()); 205 ASSERT(m_scopeStack.isEmpty());
203 m_scopeStack.clear(); 206 m_scopeStack.clear();
204 ASSERT(!skippingCache()); 207 ASSERT(!skippingCache());
205 #if ENABLE(ASSERT) 208 #if ENABLE(ASSERT)
206 m_newDisplayItemIndicesByClient.clear(); 209 m_newDisplayItemIndicesByClient.clear();
207 #endif 210 #endif
208 211
209 if (m_currentDisplayItems.isEmpty()) { 212 if (m_currentDisplayItems.isEmpty()) {
210 #if ENABLE(ASSERT) 213 #if ENABLE(ASSERT)
211 for (auto& item : m_newDisplayItems) 214 for (auto& item : m_newDisplayItems) {
212 ASSERT(!item->isCached() && !item->isSubtreeCached()); 215 ASSERT(!DisplayItem::isCachedType(item.type())
216 && !DisplayItem::isSubtreeCachedType(item.type()));
217 }
213 #endif 218 #endif
214 m_currentDisplayItems.swap(m_newDisplayItems); 219 m_currentDisplayItems.swap(m_newDisplayItems);
215 m_validlyCachedClientsDirty = true; 220 m_validlyCachedClientsDirty = true;
216 return; 221 return;
217 } 222 }
218 223
219 updateValidlyCachedClientsIfNeeded(); 224 updateValidlyCachedClientsIfNeeded();
220 225
221 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched 226 // Stores indices to valid DrawingDisplayItems in m_currentDisplayItems that have not been matched
222 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched 227 // by CachedDisplayItems during synchronized matching. The indexed items wil l be matched
223 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when 228 // by later out-of-order CachedDisplayItems in m_newDisplayItems. This ensur es that when
224 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems 229 // out-of-order CachedDisplayItems occur, we only traverse at most once over m_currentDisplayItems
225 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time. 230 // looking for potential matches. Thus we can ensure that the algorithm runs in linear time.
226 DisplayItemIndicesByClientMap displayItemIndicesByClient; 231 DisplayItemIndicesByClientMap displayItemIndicesByClient;
227 232
228 #if ENABLE(ASSERT) 233 #if ENABLE(ASSERT)
229 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) { 234 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) {
230 // Under-invalidation checking requires a full index of m_currentDisplay Items. 235 // Under-invalidation checking requires a full index of m_currentDisplay Items.
231 for (size_t i = 0; i < m_currentDisplayItems.size(); ++i) 236 size_t i = 0;
232 addItemToIndex(*m_currentDisplayItems[i], i, displayItemIndicesByCli ent); 237 for (const auto& item : m_currentDisplayItems) {
238 addItemToIndex(item.client(), item.type(), i, displayItemIndicesByCl ient);
239 ++i;
240 }
233 } 241 }
234 #endif // ENABLE(ASSERT) 242 #endif // ENABLE(ASSERT)
235 243
236 DisplayItems updatedList; 244 DisplayItems updatedList;
237 size_t currentDisplayItemsIndex = 0; 245 DisplayItems::Iterator currentIt = m_currentDisplayItems.begin();
238 for (auto& newDisplayItem : m_newDisplayItems) { 246 DisplayItems::Iterator currentEnd = m_currentDisplayItems.end();
239 DisplayItem::Type matchingType = newDisplayItem->type(); 247 for (DisplayItems::Iterator newIt = m_newDisplayItems.begin(); newIt != m_ne wDisplayItems.end(); ++newIt) {
240 if (newDisplayItem->isCached()) 248 DisplayItems::ItemHandle newDisplayItem = *newIt;
249 DisplayItem::Type matchingType = newDisplayItem.type();
250 if (DisplayItem::isCachedType(newDisplayItem.type()))
241 matchingType = DisplayItem::cachedTypeToDrawingType(matchingType); 251 matchingType = DisplayItem::cachedTypeToDrawingType(matchingType);
242 bool isSynchronized = currentDisplayItemsIndex < m_currentDisplayItems.s ize() 252 bool isSynchronized = currentIt != currentEnd
243 && m_currentDisplayItems[currentDisplayItemsIndex] 253 && !currentIt->isGone()
244 && m_currentDisplayItems[currentDisplayItemsIndex]->idsEqual(*newDis playItem, matchingType); 254 && currentIt->id().equalToExceptForType(newDisplayItem.id(), matchin gType);
245 255
246 if (newDisplayItem->isCached()) { 256 if (DisplayItem::isCachedType(newDisplayItem.type())) {
247 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled()); 257 ASSERT(!RuntimeEnabledFeatures::slimmingPaintUnderInvalidationChecki ngEnabled());
248 ASSERT(clientCacheIsValid(newDisplayItem->client())); 258 ASSERT(clientCacheIsValid(newDisplayItem.client()));
249 if (isSynchronized) { 259 if (isSynchronized) {
250 updatedList.append(m_currentDisplayItems[currentDisplayItemsInde x].release()); 260 updatedList.appendByMoving(currentIt);
251 } else { 261 } else {
252 size_t foundIndex = findOutOfOrderCachedItem(currentDisplayItems Index, *newDisplayItem, matchingType, displayItemIndicesByClient); 262 DisplayItems::Iterator foundIt = findOutOfOrderCachedItem(curren tIt, newDisplayItem.id(), matchingType, displayItemIndicesByClient);
253 ASSERT(foundIndex != kNotFound); 263 ASSERT(foundIt != currentEnd);
254 isSynchronized = (foundIndex == currentDisplayItemsIndex); 264 isSynchronized = (foundIt == currentIt);
255 updatedList.append(m_currentDisplayItems[foundIndex].release()); 265 updatedList.appendByMoving(foundIt);
256 } 266 }
257 } else { 267 } else {
258 #if ENABLE(ASSERT) 268 #if ENABLE(ASSERT)
259 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled()) 269 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEn abled())
260 checkCachedDisplayItemIsUnchanged(*newDisplayItem, displayItemIn dicesByClient); 270 checkCachedDisplayItemIsUnchanged(newDisplayItem, displayItemInd icesByClient);
261 else 271 else
262 ASSERT(!newDisplayItem->isDrawing() || newDisplayItem->skippedCa che() || !clientCacheIsValid(newDisplayItem->client())); 272 ASSERT(!DisplayItem::isDrawingType(newDisplayItem.type()) || new DisplayItem.skippedCache() || !clientCacheIsValid(newDisplayItem.client()));
263 #endif // ENABLE(ASSERT) 273 #endif // ENABLE(ASSERT)
264 updatedList.append(newDisplayItem.release()); 274 updatedList.appendByMoving(newIt);
265 } 275 }
266 276
267 if (isSynchronized) 277 if (isSynchronized)
268 ++currentDisplayItemsIndex; 278 ++currentIt;
269 } 279 }
270 280
271 #if ENABLE(ASSERT) 281 #if ENABLE(ASSERT)
272 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled()) 282 if (RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled())
273 checkNoRemainingCachedDisplayItems(); 283 checkNoRemainingCachedDisplayItems();
274 #endif // ENABLE(ASSERT) 284 #endif // ENABLE(ASSERT)
275 285
276 m_newDisplayItems.clear(); 286 m_newDisplayItems.clear();
277 m_validlyCachedClientsDirty = true; 287 m_validlyCachedClientsDirty = true;
278 m_currentDisplayItems.clear(); 288 m_currentDisplayItems.clear();
279 m_currentDisplayItems.swap(updatedList); 289 m_currentDisplayItems.swap(updatedList);
280 } 290 }
281 291
282 void DisplayItemList::updateValidlyCachedClientsIfNeeded() const 292 void DisplayItemList::updateValidlyCachedClientsIfNeeded() const
283 { 293 {
284 if (!m_validlyCachedClientsDirty) 294 if (!m_validlyCachedClientsDirty)
285 return; 295 return;
286 296
287 m_validlyCachedClients.clear(); 297 m_validlyCachedClients.clear();
288 m_validlyCachedClientsDirty = false; 298 m_validlyCachedClientsDirty = false;
289 299
290 DisplayItemClient lastClient = nullptr; 300 DisplayItemClient lastClient = nullptr;
291 for (const auto& displayItem : m_currentDisplayItems) { 301 for (const auto& displayItem : m_currentDisplayItems) {
292 if (displayItem->client() == lastClient) 302 if (displayItem.client() == lastClient)
293 continue; 303 continue;
294 lastClient = displayItem->client(); 304 lastClient = displayItem.client();
295 if (!displayItem->skippedCache()) 305 if (!displayItem.skippedCache())
296 m_validlyCachedClients.add(lastClient); 306 m_validlyCachedClients.add(lastClient);
297 } 307 }
298 } 308 }
299 309
310 void DisplayItemList::commitNewDisplayItemsAndAppendToWebDisplayItemList(WebDisp layItemList* list)
311 {
312 commitNewDisplayItems();
313 for (auto& item : m_currentDisplayItems)
314 item.appendToWebDisplayItemList(list);
315 }
316
300 #if ENABLE(ASSERT) 317 #if ENABLE(ASSERT)
301 318
302 static void showUnderInvalidationError(const char* reason, const DisplayItem& di splayItem) 319 static void showUnderInvalidationError(const char* reason, const DisplayItems::I temHandle& displayItem)
303 { 320 {
304 #ifndef NDEBUG 321 #ifndef NDEBUG
305 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data()); 322 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data());
306 #else 323 #else
307 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason); 324 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason);
308 #endif // NDEBUG 325 #endif // NDEBUG
309 } 326 }
310 327
311 static bool bitmapIsAllZero(const SkBitmap& bitmap) 328 static bool bitmapIsAllZero(const SkBitmap& bitmap)
312 { 329 {
313 bitmap.lockPixels(); 330 bitmap.lockPixels();
314 bool result = true; 331 bool result = true;
315 for (int x = 0; result && x < bitmap.width(); ++x) { 332 for (int x = 0; result && x < bitmap.width(); ++x) {
316 for (int y = 0; result && y < bitmap.height(); ++y) { 333 for (int y = 0; result && y < bitmap.height(); ++y) {
317 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT) 334 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT)
318 result = false; 335 result = false;
319 } 336 }
320 } 337 }
321 bitmap.unlockPixels(); 338 bitmap.unlockPixels();
322 return result; 339 return result;
323 } 340 }
324 341
325 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) 342 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItems::Item Handle& displayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient)
326 { 343 {
327 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 344 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
328 345
329 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) 346 if (!DisplayItem::isDrawingType(displayItem.type()) || !clientCacheIsValid(d isplayItem.client()))
330 return; 347 return;
331 348
332 const DrawingDisplayItem& drawingDisplayItem = static_cast<const DrawingDisp layItem&>(displayItem); 349 DrawingDisplayItem::UnderInvalidationCheckingMode mode = displayItem.underIn validationCheckingMode();
333 if (drawingDisplayItem.skippedCache())
334 return;
335
336 DrawingDisplayItem::UnderInvalidationCheckingMode mode = drawingDisplayItem. underInvalidationCheckingMode();
337 if (mode == DrawingDisplayItem::DontCheck) 350 if (mode == DrawingDisplayItem::DontCheck)
338 return; 351 return;
339 352
340 // If checking under-invalidation, we always generate new display item even if the client is not invalidated. 353 // If checking under-invalidation, we always generate new display item even if the client is not invalidated.
341 // Checks if the new picture is the same as the cached old picture. If the n ew picture is different but 354 // Checks if the new picture is the same as the cached old picture. If the n ew picture is different but
342 // the client is not invalidated, issue error about under-invalidation. 355 // the client is not invalidated, issue error about under-invalidation.
343 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di splayItemIndicesByClient, m_currentDisplayItems); 356 size_t index = findMatchingItemFromIndex(displayItem.id(), displayItem.type( ), displayItemIndicesByClient, m_currentDisplayItems);
344 if (index == kNotFound) { 357 if (index == kNotFound) {
345 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem); 358 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem);
346 ASSERT_NOT_REACHED(); 359 ASSERT_NOT_REACHED();
347 return; 360 return;
348 } 361 }
349 362
350 RefPtr<const SkPicture> newPicture = drawingDisplayItem.picture(); 363 DisplayItems::Iterator foundItem = m_currentDisplayItems.iteratorAt(index);
351 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>( *m_currentDisplayItems[index]).picture(); 364 RefPtr<const SkPicture> newPicture = displayItem.picture();
365 RefPtr<const SkPicture> oldPicture = foundItem->picture();
352 // Remove the display item from cache so that we can check if there are any remaining cached display items after merging. 366 // Remove the display item from cache so that we can check if there are any remaining cached display items after merging.
353 m_currentDisplayItems[index] = nullptr; 367 m_currentDisplayItems.setGone(foundItem);
354 368
355 if (!newPicture && !oldPicture) 369 if (!newPicture && !oldPicture)
356 return; 370 return;
357 if (newPicture && oldPicture) { 371 if (newPicture && oldPicture) {
358 switch (mode) { 372 switch (mode) {
359 case DrawingDisplayItem::CheckPicture: 373 case DrawingDisplayItem::CheckPicture:
360 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou nt()) { 374 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou nt()) {
361 SkDynamicMemoryWStream newPictureSerialized; 375 SkDynamicMemoryWStream newPictureSerialized;
362 newPicture->serialize(&newPictureSerialized); 376 newPicture->serialize(&newPictureSerialized);
363 SkDynamicMemoryWStream oldPictureSerialized; 377 SkDynamicMemoryWStream oldPictureSerialized;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); 412 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data());
399 #endif // NDEBUG 413 #endif // NDEBUG
400 414
401 ASSERT_NOT_REACHED(); 415 ASSERT_NOT_REACHED();
402 } 416 }
403 417
404 void DisplayItemList::checkNoRemainingCachedDisplayItems() 418 void DisplayItemList::checkNoRemainingCachedDisplayItems()
405 { 419 {
406 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 420 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
407 421
408 for (OwnPtr<DisplayItem>& displayItem : m_currentDisplayItems) { 422 for (const auto& displayItem : m_currentDisplayItems) {
409 if (!displayItem || !displayItem->isDrawing() || !clientCacheIsValid(dis playItem->client())) 423 if (displayItem.isGone() || !DisplayItem::isDrawingType(displayItem.type ()) || !clientCacheIsValid(displayItem.client()))
410 continue; 424 continue;
411 showUnderInvalidationError("May be under-invalidation: no new display it em", *displayItem); 425 showUnderInvalidationError("May be under-invalidation: no new display it em", displayItem);
412 } 426 }
413 } 427 }
414 428
415 #endif // ENABLE(ASSERT) 429 #endif // ENABLE(ASSERT)
416 430
417 #ifndef NDEBUG 431 #ifndef NDEBUG
418 432
419 WTF::String DisplayItemList::displayItemsAsDebugString(const DisplayItems& list) const 433 WTF::String DisplayItemList::displayItemsAsDebugString(const DisplayItems& list) const
420 { 434 {
421 StringBuilder stringBuilder; 435 StringBuilder stringBuilder;
422 for (size_t i = 0; i < list.size(); ++i) { 436 size_t i = 0;
423 const OwnPtr<DisplayItem>& displayItem = list[i]; 437 for (auto it = list.begin(); it != list.end(); ++it, ++i) {
438 DisplayItems::ItemHandle displayItem = list[i];
424 if (i) 439 if (i)
425 stringBuilder.append(",\n"); 440 stringBuilder.append(",\n");
426 if (!displayItem) { 441 if (displayItem.isGone()) {
427 stringBuilder.append("null"); 442 stringBuilder.append("null");
428 continue; 443 continue;
429 } 444 }
430 stringBuilder.append(String::format("{index: %d, ", (int)i)); 445 stringBuilder.append(String::format("{index: %d, ", (int)i));
431 displayItem->dumpPropertiesAsDebugString(stringBuilder); 446 displayItem.dumpPropertiesAsDebugString(stringBuilder);
432 stringBuilder.append(", cacheIsValid: "); 447 stringBuilder.append(", cacheIsValid: ");
433 stringBuilder.append(clientCacheIsValid(displayItem->client()) ? "true" : "false"); 448 stringBuilder.append(clientCacheIsValid(displayItem.client()) ? "true" : "false");
434 stringBuilder.append('}'); 449 stringBuilder.append('}');
435 } 450 }
436 return stringBuilder.toString(); 451 return stringBuilder.toString();
437 } 452 }
438 453
439 void DisplayItemList::showDebugData() const 454 void DisplayItemList::showDebugData() const
440 { 455 {
441 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu rrentDisplayItems).utf8().data()); 456 WTFLogAlways("current display items: [%s]\n", displayItemsAsDebugString(m_cu rrentDisplayItems).utf8().data());
442 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis playItems).utf8().data()); 457 WTFLogAlways("new display items: [%s]\n", displayItemsAsDebugString(m_newDis playItems).utf8().data());
443 } 458 }
444 459
445 #endif // ifndef NDEBUG 460 #endif // ifndef NDEBUG
446 461
447 void DisplayItemList::replay(GraphicsContext& context) const 462 void DisplayItemList::replay(GraphicsContext& context) const
448 { 463 {
449 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); 464 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay");
450 ASSERT(m_newDisplayItems.isEmpty()); 465 ASSERT(m_newDisplayItems.isEmpty());
451 for (auto& displayItem : m_currentDisplayItems) 466 for (auto& displayItem : m_currentDisplayItems)
452 displayItem->replay(context); 467 displayItem.replay(context);
453 } 468 }
454 469
455 } // namespace blink 470 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698