| Index: third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
|
| index adb68b5359ffb690a7a26a390696de71a5646151..3437cf4296e70ae3d4d4bbdf1ffbe584cd95c7a5 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
|
| @@ -92,6 +92,7 @@ struct PaintInvalidationTracking {
|
| DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
| Vector<PaintInvalidationInfo> trackedPaintInvalidations;
|
| sk_sp<SkPicture> lastPaintedPicture;
|
| + IntRect lastInterestRect;
|
| Region paintInvalidationRegionSinceLastPaint;
|
| Vector<UnderPaintInvalidation> underPaintInvalidations;
|
| };
|
| @@ -337,6 +338,7 @@ void GraphicsLayer::paint(const IntRect* interestRect, GraphicsContext::Disabled
|
| checkPaintUnderInvalidations(*newPicture);
|
| PaintInvalidationTracking& tracking = paintInvalidationTrackingMap().add(this, PaintInvalidationTracking()).storedValue->value;
|
| tracking.lastPaintedPicture = std::move(newPicture);
|
| + tracking.lastInterestRect = m_previousInterestRect;
|
| tracking.paintInvalidationRegionSinceLastPaint = Region();
|
| }
|
| }
|
| @@ -1285,21 +1287,25 @@ void GraphicsLayer::checkPaintUnderInvalidations(const SkPicture& newPicture)
|
| if (!tracking.lastPaintedPicture)
|
| return;
|
|
|
| + IntRect rect = intersection(tracking.lastInterestRect, interestRect());
|
| + if (rect.isEmpty())
|
| + return;
|
| +
|
| SkBitmap oldBitmap;
|
| - int width = static_cast<int>(ceilf(std::min(tracking.lastPaintedPicture->cullRect().width(), newPicture.cullRect().width())));
|
| - int height = static_cast<int>(ceilf(std::min(tracking.lastPaintedPicture->cullRect().height(), newPicture.cullRect().height())));
|
| - oldBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
|
| + oldBitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height()));
|
| {
|
| SkCanvas canvas(oldBitmap);
|
| canvas.clear(SK_ColorTRANSPARENT);
|
| + canvas.translate(-rect.x(), -rect.y());
|
| canvas.drawPicture(tracking.lastPaintedPicture.get());
|
| }
|
|
|
| SkBitmap newBitmap;
|
| - newBitmap.allocPixels(SkImageInfo::MakeN32Premul(width, height));
|
| + newBitmap.allocPixels(SkImageInfo::MakeN32Premul(rect.width(), rect.height()));
|
| {
|
| SkCanvas canvas(newBitmap);
|
| canvas.clear(SK_ColorTRANSPARENT);
|
| + canvas.translate(-rect.x(), -rect.y());
|
| canvas.drawPicture(&newPicture);
|
| }
|
|
|
| @@ -1307,34 +1313,35 @@ void GraphicsLayer::checkPaintUnderInvalidations(const SkPicture& newPicture)
|
| newBitmap.lockPixels();
|
| int mismatchingPixels = 0;
|
| static const int maxMismatchesToReport = 50;
|
| - for (int y = 0; y < height; ++y) {
|
| - for (int x = 0; x < width; ++x) {
|
| - SkColor oldPixel = oldBitmap.getColor(x, y);
|
| - SkColor newPixel = newBitmap.getColor(x, y);
|
| - if (pixelsDiffer(oldPixel, newPixel) && !tracking.paintInvalidationRegionSinceLastPaint.contains(IntPoint(x, y))) {
|
| + for (int bitmapY = 0; bitmapY < rect.height(); ++bitmapY) {
|
| + int layerY = bitmapY + rect.y();
|
| + for (int bitmapX = 0; bitmapX < rect.width(); ++bitmapX) {
|
| + int layerX = bitmapX + rect.x();
|
| + SkColor oldPixel = oldBitmap.getColor(bitmapX, bitmapY);
|
| + SkColor newPixel = newBitmap.getColor(bitmapX, bitmapY);
|
| + if (pixelsDiffer(oldPixel, newPixel) && !tracking.paintInvalidationRegionSinceLastPaint.contains(IntPoint(layerX, layerY))) {
|
| if (mismatchingPixels < maxMismatchesToReport) {
|
| - UnderPaintInvalidation underPaintInvalidation = { x, y, oldPixel, newPixel };
|
| + UnderPaintInvalidation underPaintInvalidation = { layerX, layerY, oldPixel, newPixel };
|
| tracking.underPaintInvalidations.append(underPaintInvalidation);
|
| - LOG(ERROR) << debugName() << " Uninvalidated old/new pixels mismatch at " << x << "," << y << " old:" << std::hex << oldPixel << " new:" << newPixel;
|
| + LOG(ERROR) << debugName() << " Uninvalidated old/new pixels mismatch at " << layerX << "," << layerY << " old:" << std::hex << oldPixel << " new:" << newPixel;
|
| } else if (mismatchingPixels == maxMismatchesToReport) {
|
| LOG(ERROR) << "and more...";
|
| }
|
| ++mismatchingPixels;
|
| - *newBitmap.getAddr32(x, y) = SkColorSetARGB(0xFF, 0xA0, 0, 0); // Dark red.
|
| + *newBitmap.getAddr32(bitmapX, bitmapY) = SkColorSetARGB(0xFF, 0xA0, 0, 0); // Dark red.
|
| } else {
|
| - *newBitmap.getAddr32(x, y) = SK_ColorTRANSPARENT;
|
| + *newBitmap.getAddr32(bitmapX, bitmapY) = SK_ColorTRANSPARENT;
|
| }
|
| }
|
| }
|
| -
|
| oldBitmap.unlockPixels();
|
| newBitmap.unlockPixels();
|
|
|
| // Visualize under-invalidations by overlaying the new bitmap (containing red pixels indicating under-invalidations,
|
| // and transparent pixels otherwise) onto the painting.
|
| SkPictureRecorder recorder;
|
| - recorder.beginRecording(width, height);
|
| - recorder.getRecordingCanvas()->drawBitmap(newBitmap, 0, 0);
|
| + recorder.beginRecording(rect);
|
| + recorder.getRecordingCanvas()->drawBitmap(newBitmap, rect.x(), rect.y());
|
| sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
|
| getPaintController().appendDebugDrawingAfterCommit(*this, picture, offsetFromLayoutObjectWithSubpixelAccumulation());
|
| }
|
|
|