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 |