| Index: third_party/WebKit/Source/core/paint/PaintTiming.cpp
|
| diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.cpp b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
|
| index 29b9507d92f900416f65e32390d69d7e04b6269d..b404df422040d2e054629705025bbf284560b9ee 100644
|
| --- a/third_party/WebKit/Source/core/paint/PaintTiming.cpp
|
| +++ b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
|
| @@ -12,6 +12,22 @@
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +unsigned getRectHash(const IntRect& rect)
|
| +{
|
| + // Divide by 10 so similar rectangles are treated the same.
|
| + unsigned positionHash = ((rect.x() / 10) << 16) + (rect.y() / 10);
|
| + unsigned sizeHash = ((rect.width() / 10) << 16) + (rect.height() / 10);
|
| + unsigned rectHash = positionHash ^ sizeHash;
|
| + // HashSets do not allow null values.
|
| + if (rectHash == 0)
|
| + rectHash++;
|
| + return rectHash;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| static const char kSupplementName[] = "PaintTiming";
|
|
|
| PaintTiming& PaintTiming::from(Document& document)
|
| @@ -27,6 +43,8 @@ PaintTiming& PaintTiming::from(Document& document)
|
| PaintTiming::PaintTiming(Document& document)
|
| : m_document(document)
|
| {
|
| + ASSERT(document.domWindow());
|
| + m_viewPortRect = IntRect(0, 0, document.domWindow()->innerWidth(), document.domWindow()->innerHeight());
|
| }
|
|
|
| DEFINE_TRACE(PaintTiming)
|
| @@ -66,4 +84,62 @@ void PaintTiming::markFirstImagePaint()
|
| notifyPaintTimingChanged();
|
| }
|
|
|
| +void PaintTiming::markPaintInvalidation(const IntRect* visualRect, int paintCount)
|
| +{
|
| + if (m_speedIndex || !m_loadCommitted)
|
| + return;
|
| + if (!frame() || !frame()->isMainFrame())
|
| + return;
|
| + if (!visualRect->size().area() || !visualRect->intersects(m_viewPortRect))
|
| + return;
|
| +
|
| + IntRect intersect = intersection(*visualRect, m_viewPortRect);
|
| + unsigned rectHash = getRectHash(intersect);
|
| + unsigned long size = intersect.size().area();
|
| + double timestamp = monotonicallyIncreasingTime();
|
| +
|
| + // Don't double count invalidation rects before any painting occurs.
|
| + if (paintCount != m_lastPaintCount && frameRects.size())
|
| + frameRects.clear();
|
| + if (!frameRects.add(rectHash).isNewEntry)
|
| + return;
|
| +
|
| + // Add the area under the curve that the previous invalidation rect
|
| + // contributed.
|
| + if (m_lastPaintInvalidationTime) {
|
| + m_totalLoadedArea += (timestamp - m_lastPaintInvalidationTime) * m_totalContributions;
|
| + }
|
| + m_lastPaintInvalidationTime = timestamp;
|
| +
|
| + // Adjust the size of the painted area based on how many times this rect has
|
| + // been invalidated, as well as if it is a full sized invalidation.
|
| + double adjustedSize = size;
|
| + int count = ++(m_rectCounts.add(rectHash, 0).storedValue->value);
|
| + adjustedSize /= count;
|
| + if (size == m_viewPortRect.size().area())
|
| + adjustedSize /= 2.0;
|
| +
|
| + m_totalContributions += adjustedSize;
|
| + m_lastPaintCount = paintCount;
|
| +}
|
| +
|
| +double PaintTiming::speedIndex(double referenceTime) const
|
| +{
|
| + if (m_speedIndex)
|
| + return m_speedIndex;
|
| + if (!m_totalContributions)
|
| + return 0.0;
|
| +
|
| + double totalArea = (m_lastPaintInvalidationTime - referenceTime) * m_totalContributions;
|
| + m_speedIndex = (totalArea - m_totalLoadedArea) / m_totalContributions;
|
| +
|
| + // Unfortunate hack because we can mark invalidations before the first
|
| + // paint in some circumstances.
|
| + if (m_firstPaint)
|
| + m_speedIndex = std::max(m_speedIndex, m_firstPaint - referenceTime);
|
| +
|
| + TRACE_EVENT2("blink.user_timing", "speedIndex", "value", m_speedIndex * 1000.0, "frame", frame());
|
| + return m_speedIndex;
|
| +}
|
| +
|
| } // namespace blink
|
|
|