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

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

Issue 1160223004: Avoid false-positives of under-invalidation checking (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Check bitmaps for HTML canvas drawings only 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 289
290 static void showUnderInvalidationError(const char* reason, const DisplayItem& di splayItem) 290 static void showUnderInvalidationError(const char* reason, const DisplayItem& di splayItem)
291 { 291 {
292 #ifndef NDEBUG 292 #ifndef NDEBUG
293 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data()); 293 WTFLogAlways("%s: %s\nSee http://crbug.com/450725.", reason, displayItem.asD ebugString().utf8().data());
294 #else 294 #else
295 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason); 295 WTFLogAlways("%s. Run debug build to get more details\nSee http://crbug.com/ 450725.", reason);
296 #endif // NDEBUG 296 #endif // NDEBUG
297 } 297 }
298 298
299 static bool bitmapIsAllZero(const SkBitmap& bitmap)
300 {
301 bitmap.lockPixels();
302 bool result = true;
303 for (int x = 0; result && x < bitmap.width(); ++x) {
304 for (int y = 0; result && y < bitmap.height(); ++y) {
305 if (SkColorSetA(bitmap.getColor(x, y), 0) != SK_ColorTRANSPARENT)
306 result = false;
307 }
308 }
309 bitmap.unlockPixels();
310 return result;
311 }
312
299 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient) 313 void DisplayItemList::checkCachedDisplayItemIsUnchanged(const DisplayItem& displ ayItem, DisplayItemIndicesByClientMap& displayItemIndicesByClient)
300 { 314 {
301 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ()); 315 ASSERT(RuntimeEnabledFeatures::slimmingPaintUnderInvalidationCheckingEnabled ());
302 316
303 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client())) 317 if (!displayItem.isDrawing() || !clientCacheIsValid(displayItem.client()))
304 return; 318 return;
305 319
306 if (static_cast<const DrawingDisplayItem&>(displayItem).skipUnderInvalidatio nChecking()) 320 DrawingDisplayItem::UnderInvalidationCheckingMode mode = static_cast<const D rawingDisplayItem&>(displayItem).underInvalidationCheckingMode();
321 if (mode == DrawingDisplayItem::DontCheck)
307 return; 322 return;
308 323
309 // If checking under-invalidation, we always generate new display item even if the client is not invalidated. 324 // If checking under-invalidation, we always generate new display item even if the client is not invalidated.
310 // Checks if the new picture is the same as the cached old picture. If the n ew picture is different but 325 // Checks if the new picture is the same as the cached old picture. If the n ew picture is different but
311 // the client is not invalidated, issue error about under-invalidation. 326 // the client is not invalidated, issue error about under-invalidation.
312 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di splayItemIndicesByClient, m_currentDisplayItems); 327 size_t index = findMatchingItemFromIndex(displayItem, displayItem.type(), di splayItemIndicesByClient, m_currentDisplayItems);
313 if (index == kNotFound) { 328 if (index == kNotFound) {
314 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem); 329 showUnderInvalidationError("ERROR: under-invalidation: no cached display item", displayItem);
315 ASSERT_NOT_REACHED(); 330 ASSERT_NOT_REACHED();
316 return; 331 return;
317 } 332 }
318 333
319 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>( displayItem).picture(); 334 RefPtr<const SkPicture> newPicture = static_cast<const DrawingDisplayItem&>( displayItem).picture();
320 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>( *m_currentDisplayItems[index]).picture(); 335 RefPtr<const SkPicture> oldPicture = static_cast<const DrawingDisplayItem&>( *m_currentDisplayItems[index]).picture();
321 // Remove the display item from cache so that we can check if there are any remaining cached display items after merging. 336 // Remove the display item from cache so that we can check if there are any remaining cached display items after merging.
322 m_currentDisplayItems[index] = nullptr; 337 m_currentDisplayItems[index] = nullptr;
323 338
324 if (!newPicture && !oldPicture) 339 if (!newPicture && !oldPicture)
325 return; 340 return;
326 if (newPicture && oldPicture && newPicture->approximateOpCount() == oldPictu re->approximateOpCount()) { 341 if (newPicture && oldPicture) {
327 SkDynamicMemoryWStream newPictureSerialized; 342 switch (mode) {
328 newPicture->serialize(&newPictureSerialized); 343 case DrawingDisplayItem::CheckPicture:
329 SkDynamicMemoryWStream oldPictureSerialized; 344 if (newPicture->approximateOpCount() == oldPicture->approximateOpCou nt()) {
330 oldPicture->serialize(&oldPictureSerialized); 345 SkDynamicMemoryWStream newPictureSerialized;
346 newPicture->serialize(&newPictureSerialized);
347 SkDynamicMemoryWStream oldPictureSerialized;
348 oldPicture->serialize(&oldPictureSerialized);
331 349
332 if (newPictureSerialized.bytesWritten() == oldPictureSerialized.bytesWri tten()) { 350 if (newPictureSerialized.bytesWritten() == oldPictureSerialized. bytesWritten()) {
333 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyToData()) ; 351 RefPtr<SkData> oldData = adoptRef(oldPictureSerialized.copyT oData());
334 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyToData()) ; 352 RefPtr<SkData> newData = adoptRef(newPictureSerialized.copyT oData());
335 if (oldData->equals(newData.get())) 353 if (oldData->equals(newData.get()))
336 return; 354 return;
355 }
356 }
357 break;
358 case DrawingDisplayItem::CheckBitmap:
Justin Novosad 2015/06/01 21:47:34 For now, this strategy will work. In the near futu
359 if (newPicture->cullRect() == oldPicture->cullRect()) {
360 SkBitmap bitmap;
361 SkRect rect = newPicture->cullRect();
362 bitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect .height()));
363 SkCanvas canvas(bitmap);
364 canvas.translate(-rect.x(), -rect.y());
365 canvas.drawPicture(oldPicture.get());
366 SkPaint diffPaint;
367 diffPaint.setXfermodeMode(SkXfermode::kDifference_Mode);
368 canvas.drawPicture(newPicture.get(), nullptr, &diffPaint);
369 if (bitmapIsAllZero(bitmap)) // Contents are the same.
370 return;
371 }
372 default:
373 ASSERT_NOT_REACHED();
337 } 374 }
338 } 375 }
339 376
340 showUnderInvalidationError("ERROR: under-invalidation: display item changed" , displayItem); 377 showUnderInvalidationError("ERROR: under-invalidation: display item changed" , displayItem);
341 #ifndef NDEBUG 378 #ifndef NDEBUG
342 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture. get()) : "None"; 379 String oldPictureDebugString = oldPicture ? pictureAsDebugString(oldPicture. get()) : "None";
343 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture. get()) : "None"; 380 String newPictureDebugString = newPicture ? pictureAsDebugString(newPicture. get()) : "None";
344 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data()); 381 WTFLogAlways("old picture:\n%s\n", oldPictureDebugString.utf8().data());
345 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data()); 382 WTFLogAlways("new picture:\n%s\n", newPictureDebugString.utf8().data());
346 #endif // NDEBUG 383 #endif // NDEBUG
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 430
394 void DisplayItemList::replay(GraphicsContext& context) const 431 void DisplayItemList::replay(GraphicsContext& context) const
395 { 432 {
396 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay"); 433 TRACE_EVENT0("blink,benchmark", "DisplayItemList::replay");
397 ASSERT(m_newDisplayItems.isEmpty()); 434 ASSERT(m_newDisplayItems.isEmpty());
398 for (auto& displayItem : m_currentDisplayItems) 435 for (auto& displayItem : m_currentDisplayItems)
399 displayItem->replay(context); 436 displayItem->replay(context);
400 } 437 }
401 438
402 } // namespace blink 439 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698