| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 int x; | 85 int x; |
| 86 int y; | 86 int y; |
| 87 SkColor oldPixel; | 87 SkColor oldPixel; |
| 88 SkColor newPixel; | 88 SkColor newPixel; |
| 89 }; | 89 }; |
| 90 | 90 |
| 91 struct PaintInvalidationTracking { | 91 struct PaintInvalidationTracking { |
| 92 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | 92 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
| 93 Vector<PaintInvalidationInfo> trackedPaintInvalidations; | 93 Vector<PaintInvalidationInfo> trackedPaintInvalidations; |
| 94 sk_sp<SkPicture> lastPaintedPicture; | 94 sk_sp<SkPicture> lastPaintedPicture; |
| 95 IntRect lastInterestRect; |
| 95 Region paintInvalidationRegionSinceLastPaint; | 96 Region paintInvalidationRegionSinceLastPaint; |
| 96 Vector<UnderPaintInvalidation> underPaintInvalidations; | 97 Vector<UnderPaintInvalidation> underPaintInvalidations; |
| 97 }; | 98 }; |
| 98 | 99 |
| 99 typedef HashMap<const GraphicsLayer*, PaintInvalidationTracking> PaintInvalidati
onTrackingMap; | 100 typedef HashMap<const GraphicsLayer*, PaintInvalidationTracking> PaintInvalidati
onTrackingMap; |
| 100 static PaintInvalidationTrackingMap& paintInvalidationTrackingMap() | 101 static PaintInvalidationTrackingMap& paintInvalidationTrackingMap() |
| 101 { | 102 { |
| 102 DEFINE_STATIC_LOCAL(PaintInvalidationTrackingMap, map, ()); | 103 DEFINE_STATIC_LOCAL(PaintInvalidationTrackingMap, map, ()); |
| 103 return map; | 104 return map; |
| 104 } | 105 } |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 | 331 |
| 331 void GraphicsLayer::paint(const IntRect* interestRect, GraphicsContext::Disabled
Mode disabledMode) | 332 void GraphicsLayer::paint(const IntRect* interestRect, GraphicsContext::Disabled
Mode disabledMode) |
| 332 { | 333 { |
| 333 if (paintWithoutCommit(interestRect, disabledMode)) { | 334 if (paintWithoutCommit(interestRect, disabledMode)) { |
| 334 getPaintController().commitNewDisplayItems(offsetFromLayoutObjectWithSub
pixelAccumulation()); | 335 getPaintController().commitNewDisplayItems(offsetFromLayoutObjectWithSub
pixelAccumulation()); |
| 335 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { | 336 if (RuntimeEnabledFeatures::paintUnderInvalidationCheckingEnabled()) { |
| 336 sk_sp<SkPicture> newPicture = capturePicture(); | 337 sk_sp<SkPicture> newPicture = capturePicture(); |
| 337 checkPaintUnderInvalidations(*newPicture); | 338 checkPaintUnderInvalidations(*newPicture); |
| 338 PaintInvalidationTracking& tracking = paintInvalidationTrackingMap()
.add(this, PaintInvalidationTracking()).storedValue->value; | 339 PaintInvalidationTracking& tracking = paintInvalidationTrackingMap()
.add(this, PaintInvalidationTracking()).storedValue->value; |
| 339 tracking.lastPaintedPicture = std::move(newPicture); | 340 tracking.lastPaintedPicture = std::move(newPicture); |
| 341 tracking.lastInterestRect = m_previousInterestRect; |
| 340 tracking.paintInvalidationRegionSinceLastPaint = Region(); | 342 tracking.paintInvalidationRegionSinceLastPaint = Region(); |
| 341 } | 343 } |
| 342 } | 344 } |
| 343 } | 345 } |
| 344 | 346 |
| 345 bool GraphicsLayer::paintWithoutCommit(const IntRect* interestRect, GraphicsCont
ext::DisabledMode disabledMode) | 347 bool GraphicsLayer::paintWithoutCommit(const IntRect* interestRect, GraphicsCont
ext::DisabledMode disabledMode) |
| 346 { | 348 { |
| 347 ASSERT(drawsContent()); | 349 ASSERT(drawsContent()); |
| 348 | 350 |
| 349 if (!m_client) | 351 if (!m_client) |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 if (!drawsContent()) | 1280 if (!drawsContent()) |
| 1279 return; | 1281 return; |
| 1280 | 1282 |
| 1281 auto it = paintInvalidationTrackingMap().find(this); | 1283 auto it = paintInvalidationTrackingMap().find(this); |
| 1282 if (it == paintInvalidationTrackingMap().end()) | 1284 if (it == paintInvalidationTrackingMap().end()) |
| 1283 return; | 1285 return; |
| 1284 PaintInvalidationTracking& tracking = it->value; | 1286 PaintInvalidationTracking& tracking = it->value; |
| 1285 if (!tracking.lastPaintedPicture) | 1287 if (!tracking.lastPaintedPicture) |
| 1286 return; | 1288 return; |
| 1287 | 1289 |
| 1290 IntRect rect = intersection(tracking.lastInterestRect, interestRect()); |
| 1291 if (rect.isEmpty()) |
| 1292 return; |
| 1293 |
| 1288 SkBitmap oldBitmap; | 1294 SkBitmap oldBitmap; |
| 1289 int width = static_cast<int>(ceilf(std::min(tracking.lastPaintedPicture->cul
lRect().width(), newPicture.cullRect().width()))); | 1295 oldBitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height()
)); |
| 1290 int height = static_cast<int>(ceilf(std::min(tracking.lastPaintedPicture->cu
llRect().height(), newPicture.cullRect().height()))); | |
| 1291 oldBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); | |
| 1292 { | 1296 { |
| 1293 SkCanvas canvas(oldBitmap); | 1297 SkCanvas canvas(oldBitmap); |
| 1294 canvas.clear(SK_ColorTRANSPARENT); | 1298 canvas.clear(SK_ColorTRANSPARENT); |
| 1299 canvas.translate(-rect.x(), -rect.y()); |
| 1295 canvas.drawPicture(tracking.lastPaintedPicture.get()); | 1300 canvas.drawPicture(tracking.lastPaintedPicture.get()); |
| 1296 } | 1301 } |
| 1297 | 1302 |
| 1298 SkBitmap newBitmap; | 1303 SkBitmap newBitmap; |
| 1299 newBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height)); | 1304 newBitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height()
)); |
| 1300 { | 1305 { |
| 1301 SkCanvas canvas(newBitmap); | 1306 SkCanvas canvas(newBitmap); |
| 1302 canvas.clear(SK_ColorTRANSPARENT); | 1307 canvas.clear(SK_ColorTRANSPARENT); |
| 1308 canvas.translate(-rect.x(), -rect.y()); |
| 1303 canvas.drawPicture(&newPicture); | 1309 canvas.drawPicture(&newPicture); |
| 1304 } | 1310 } |
| 1305 | 1311 |
| 1306 oldBitmap.lockPixels(); | 1312 oldBitmap.lockPixels(); |
| 1307 newBitmap.lockPixels(); | 1313 newBitmap.lockPixels(); |
| 1308 int mismatchingPixels = 0; | 1314 int mismatchingPixels = 0; |
| 1309 static const int maxMismatchesToReport = 50; | 1315 static const int maxMismatchesToReport = 50; |
| 1310 for (int y = 0; y < height; ++y) { | 1316 for (int bitmapY = 0; bitmapY < rect.height(); ++bitmapY) { |
| 1311 for (int x = 0; x < width; ++x) { | 1317 int layerY = bitmapY + rect.y(); |
| 1312 SkColor oldPixel = oldBitmap.getColor(x, y); | 1318 for (int bitmapX = 0; bitmapX < rect.width(); ++bitmapX) { |
| 1313 SkColor newPixel = newBitmap.getColor(x, y); | 1319 int layerX = bitmapX + rect.x(); |
| 1314 if (pixelsDiffer(oldPixel, newPixel) && !tracking.paintInvalidationR
egionSinceLastPaint.contains(IntPoint(x, y))) { | 1320 SkColor oldPixel = oldBitmap.getColor(bitmapX, bitmapY); |
| 1321 SkColor newPixel = newBitmap.getColor(bitmapX, bitmapY); |
| 1322 if (pixelsDiffer(oldPixel, newPixel) && !tracking.paintInvalidationR
egionSinceLastPaint.contains(IntPoint(layerX, layerY))) { |
| 1315 if (mismatchingPixels < maxMismatchesToReport) { | 1323 if (mismatchingPixels < maxMismatchesToReport) { |
| 1316 UnderPaintInvalidation underPaintInvalidation = { x, y, oldP
ixel, newPixel }; | 1324 UnderPaintInvalidation underPaintInvalidation = { layerX, la
yerY, oldPixel, newPixel }; |
| 1317 tracking.underPaintInvalidations.append(underPaintInvalidati
on); | 1325 tracking.underPaintInvalidations.append(underPaintInvalidati
on); |
| 1318 LOG(ERROR) << debugName() << " Uninvalidated old/new pixels
mismatch at " << x << "," << y << " old:" << std::hex << oldPixel << " new:" <<
newPixel; | 1326 LOG(ERROR) << debugName() << " Uninvalidated old/new pixels
mismatch at " << layerX << "," << layerY << " old:" << std::hex << oldPixel << "
new:" << newPixel; |
| 1319 } else if (mismatchingPixels == maxMismatchesToReport) { | 1327 } else if (mismatchingPixels == maxMismatchesToReport) { |
| 1320 LOG(ERROR) << "and more..."; | 1328 LOG(ERROR) << "and more..."; |
| 1321 } | 1329 } |
| 1322 ++mismatchingPixels; | 1330 ++mismatchingPixels; |
| 1323 *newBitmap.getAddr32(x, y) = SkColorSetARGB(0xFF, 0xA0, 0, 0); /
/ Dark red. | 1331 *newBitmap.getAddr32(bitmapX, bitmapY) = SkColorSetARGB(0xFF, 0x
A0, 0, 0); // Dark red. |
| 1324 } else { | 1332 } else { |
| 1325 *newBitmap.getAddr32(x, y) = SK_ColorTRANSPARENT; | 1333 *newBitmap.getAddr32(bitmapX, bitmapY) = SK_ColorTRANSPARENT; |
| 1326 } | 1334 } |
| 1327 } | 1335 } |
| 1328 } | 1336 } |
| 1329 | |
| 1330 oldBitmap.unlockPixels(); | 1337 oldBitmap.unlockPixels(); |
| 1331 newBitmap.unlockPixels(); | 1338 newBitmap.unlockPixels(); |
| 1332 | 1339 |
| 1333 // Visualize under-invalidations by overlaying the new bitmap (containing re
d pixels indicating under-invalidations, | 1340 // Visualize under-invalidations by overlaying the new bitmap (containing re
d pixels indicating under-invalidations, |
| 1334 // and transparent pixels otherwise) onto the painting. | 1341 // and transparent pixels otherwise) onto the painting. |
| 1335 SkPictureRecorder recorder; | 1342 SkPictureRecorder recorder; |
| 1336 recorder.beginRecording(width, height); | 1343 recorder.beginRecording(rect); |
| 1337 recorder.getRecordingCanvas()->drawBitmap(newBitmap, 0, 0); | 1344 recorder.getRecordingCanvas()->drawBitmap(newBitmap, rect.x(), rect.y()); |
| 1338 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); | 1345 sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); |
| 1339 getPaintController().appendDebugDrawingAfterCommit(*this, picture, offsetFro
mLayoutObjectWithSubpixelAccumulation()); | 1346 getPaintController().appendDebugDrawingAfterCommit(*this, picture, offsetFro
mLayoutObjectWithSubpixelAccumulation()); |
| 1340 } | 1347 } |
| 1341 | 1348 |
| 1342 } // namespace blink | 1349 } // namespace blink |
| 1343 | 1350 |
| 1344 #ifndef NDEBUG | 1351 #ifndef NDEBUG |
| 1345 void showGraphicsLayerTree(const blink::GraphicsLayer* layer) | 1352 void showGraphicsLayerTree(const blink::GraphicsLayer* layer) |
| 1346 { | 1353 { |
| 1347 if (!layer) { | 1354 if (!layer) { |
| 1348 fprintf(stderr, "Cannot showGraphicsLayerTree for (nil).\n"); | 1355 fprintf(stderr, "Cannot showGraphicsLayerTree for (nil).\n"); |
| 1349 return; | 1356 return; |
| 1350 } | 1357 } |
| 1351 | 1358 |
| 1352 String output = layer->layerTreeAsText(blink::LayerTreeIncludesDebugInfo); | 1359 String output = layer->layerTreeAsText(blink::LayerTreeIncludesDebugInfo); |
| 1353 fprintf(stderr, "%s\n", output.utf8().data()); | 1360 fprintf(stderr, "%s\n", output.utf8().data()); |
| 1354 } | 1361 } |
| 1355 #endif | 1362 #endif |
| OLD | NEW |