- Revision
- 267270
- Author
- [email protected]
- Date
- 2020-09-18 12:36:17 -0700 (Fri, 18 Sep 2020)
Log Message
Cherry-pick r266677. rdar://problem/68740521
[MotionMark] RenderLayer::paintLayerContents spends ~5% of the time in MonotonicTime::now() in Multiply
https://bugs.webkit.org/show_bug.cgi?id=216190
Reviewed by Darin Adler.
Source/WebCore:
In several of MotionMark's subtests (for instance, Multiply), we spent a large amount of time underneath
`RenderLayer::paintLayerContents` due to both the large number of layers and the need to frequently repaint
each layer (all of which are constantly being animated). Underneath this method, a nontrivial amount of time
(~5%) is then spent grabbing the system time via `MonotonicTime::now()`.
We can avoid this extra work by instead using the timestamp of the last rendering update (before we started
painting), which we keep track of using a new member variable on `Page`. See below for more details, as well as
the WebKit2 ChangeLog.
* page/ChromeClient.h:
(WebCore::ChromeClient::timestampForPaintFrequencyTracking const):
Add a client hook to fetch the timestamp to use when tracking painting frequency. See the WebKit2 ChangeLog for
more details.
* page/Page.cpp:
(WebCore::Page::updateRendering):
Update `m_lastRenderingUpdateTimestamp`.
* page/Page.h:
(WebCore::Page::lastRenderingUpdateTimestamp const):
* rendering/PaintFrequencyTracker.h:
Drive-by cleanup: narrow the `PaintFrequency` enum to `bool` width.
(WebCore::PaintFrequencyTracker::begin):
(WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents):
Call out to the client layer to return a timestamp for tracking painting frequency. By default, this is simply
the current time (`MonotonicTime::now()`), but ports (namely, WebKit2) may opt for a coarser granularity.
(WebCore::RenderLayer::simulateFrequentPaint):
* rendering/RenderLayer.h:
Source/WebKit:
* WebProcess/WebCoreSupport/WebChromeClient.cpp:
(WebKit::WebChromeClient::timestampForPaintFrequencyTracking const):
In WebKit2, we can assume (with the exception of SVG pages) that we must've performed a rendering update prior
to tracking painting frequencies. As such, we can use the page's rendering update timestamp instead of the real
current time (`MonotonicTime::now()`).
Note that in WebKit1, it is possible for any client to force a synchronous paint of the page before the page has
performed a rendering update, which triggers assertions in `SinglePaintFrequencyTracking::end()`. As such, we
stick with `MonotonicTime::now()` in WebKit1.
* WebProcess/WebCoreSupport/WebChromeClient.h:
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266677 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Modified Paths
Diff
Modified: branches/safari-610-branch/Source/WebCore/ChangeLog (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/ChangeLog 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/ChangeLog 2020-09-18 19:36:17 UTC (rev 267270)
@@ -1,5 +1,115 @@
2020-09-17 Alan Coon <[email protected]>
+ Cherry-pick r266677. rdar://problem/68740521
+
+ [MotionMark] RenderLayer::paintLayerContents spends ~5% of the time in MonotonicTime::now() in Multiply
+ https://bugs.webkit.org/show_bug.cgi?id=216190
+
+ Reviewed by Darin Adler.
+
+ Source/WebCore:
+
+ In several of MotionMark's subtests (for instance, Multiply), we spent a large amount of time underneath
+ `RenderLayer::paintLayerContents` due to both the large number of layers and the need to frequently repaint
+ each layer (all of which are constantly being animated). Underneath this method, a nontrivial amount of time
+ (~5%) is then spent grabbing the system time via `MonotonicTime::now()`.
+
+ We can avoid this extra work by instead using the timestamp of the last rendering update (before we started
+ painting), which we keep track of using a new member variable on `Page`. See below for more details, as well as
+ the WebKit2 ChangeLog.
+
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::timestampForPaintFrequencyTracking const):
+
+ Add a client hook to fetch the timestamp to use when tracking painting frequency. See the WebKit2 ChangeLog for
+ more details.
+
+ * page/Page.cpp:
+ (WebCore::Page::updateRendering):
+
+ Update `m_lastRenderingUpdateTimestamp`.
+
+ * page/Page.h:
+ (WebCore::Page::lastRenderingUpdateTimestamp const):
+ * rendering/PaintFrequencyTracker.h:
+
+ Drive-by cleanup: narrow the `PaintFrequency` enum to `bool` width.
+
+ (WebCore::PaintFrequencyTracker::begin):
+ (WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+
+ Call out to the client layer to return a timestamp for tracking painting frequency. By default, this is simply
+ the current time (`MonotonicTime::now()`), but ports (namely, WebKit2) may opt for a coarser granularity.
+
+ (WebCore::RenderLayer::simulateFrequentPaint):
+ * rendering/RenderLayer.h:
+
+ Source/WebKit:
+
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::timestampForPaintFrequencyTracking const):
+
+ In WebKit2, we can assume (with the exception of SVG pages) that we must've performed a rendering update prior
+ to tracking painting frequencies. As such, we can use the page's rendering update timestamp instead of the real
+ current time (`MonotonicTime::now()`).
+
+ Note that in WebKit1, it is possible for any client to force a synchronous paint of the page before the page has
+ performed a rendering update, which triggers assertions in `SinglePaintFrequencyTracking::end()`. As such, we
+ stick with `MonotonicTime::now()` in WebKit1.
+
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266677 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2020-09-05 Wenson Hsieh <[email protected]>
+
+ [MotionMark] RenderLayer::paintLayerContents spends ~5% of the time in MonotonicTime::now() in Multiply
+ https://bugs.webkit.org/show_bug.cgi?id=216190
+
+ Reviewed by Darin Adler.
+
+ In several of MotionMark's subtests (for instance, Multiply), we spent a large amount of time underneath
+ `RenderLayer::paintLayerContents` due to both the large number of layers and the need to frequently repaint
+ each layer (all of which are constantly being animated). Underneath this method, a nontrivial amount of time
+ (~5%) is then spent grabbing the system time via `MonotonicTime::now()`.
+
+ We can avoid this extra work by instead using the timestamp of the last rendering update (before we started
+ painting), which we keep track of using a new member variable on `Page`. See below for more details, as well as
+ the WebKit2 ChangeLog.
+
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::timestampForPaintFrequencyTracking const):
+
+ Add a client hook to fetch the timestamp to use when tracking painting frequency. See the WebKit2 ChangeLog for
+ more details.
+
+ * page/Page.cpp:
+ (WebCore::Page::updateRendering):
+
+ Update `m_lastRenderingUpdateTimestamp`.
+
+ * page/Page.h:
+ (WebCore::Page::lastRenderingUpdateTimestamp const):
+ * rendering/PaintFrequencyTracker.h:
+
+ Drive-by cleanup: narrow the `PaintFrequency` enum to `bool` width.
+
+ (WebCore::PaintFrequencyTracker::begin):
+ (WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+
+ Call out to the client layer to return a timestamp for tracking painting frequency. By default, this is simply
+ the current time (`MonotonicTime::now()`), but ports (namely, WebKit2) may opt for a coarser granularity.
+
+ (WebCore::RenderLayer::simulateFrequentPaint):
+ * rendering/RenderLayer.h:
+
+2020-09-17 Alan Coon <[email protected]>
+
Cherry-pick r266232. rdar://problem/68178664
Step animations invalidate style on every rendering update whether or not they need to
Modified: branches/safari-610-branch/Source/WebCore/page/ChromeClient.h (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/page/ChromeClient.h 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/page/ChromeClient.h 2020-09-18 19:36:17 UTC (rev 267270)
@@ -51,6 +51,7 @@
#include <wtf/Assertions.h>
#include <wtf/CompletionHandler.h>
#include <wtf/Forward.h>
+#include <wtf/MonotonicTime.h>
#include <wtf/Seconds.h>
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
@@ -455,6 +456,8 @@
virtual bool shouldUseTiledBackingForFrameView(const FrameView&) const { return false; }
+ virtual MonotonicTime timestampForPaintFrequencyTracking() const { return MonotonicTime::now(); }
+
virtual void isPlayingMediaDidChange(MediaProducer::MediaStateFlags, uint64_t) { }
virtual void handleAutoplayEvent(AutoplayEvent, OptionSet<AutoplayEventFlags>) { }
Modified: branches/safari-610-branch/Source/WebCore/page/Page.cpp (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/page/Page.cpp 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/page/Page.cpp 2020-09-18 19:36:17 UTC (rev 267270)
@@ -1437,6 +1437,8 @@
return;
}
+ m_lastRenderingUpdateTimestamp = MonotonicTime::now();
+
bool isSVGImagePage = chrome().client().isSVGImageChromeClient();
if (!isSVGImagePage)
tracePoint(RenderingUpdateStart);
Modified: branches/safari-610-branch/Source/WebCore/page/Page.h (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/page/Page.h 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/page/Page.h 2020-09-18 19:36:17 UTC (rev 267270)
@@ -779,6 +779,8 @@
bool hasBeenNotifiedToInjectUserScripts() const { return m_hasBeenNotifiedToInjectUserScripts; }
WEBCORE_EXPORT void notifyToInjectUserScripts();
+ MonotonicTime lastRenderingUpdateTimestamp() const { return m_lastRenderingUpdateTimestamp; }
+
private:
struct Navigation {
RegistrableDomain domain;
@@ -1073,6 +1075,8 @@
bool m_canUseCredentialStorage { true };
ShouldRelaxThirdPartyCookieBlocking m_shouldRelaxThirdPartyCookieBlocking { ShouldRelaxThirdPartyCookieBlocking::No };
bool m_hasBeenNotifiedToInjectUserScripts { false };
+
+ MonotonicTime m_lastRenderingUpdateTimestamp;
};
inline PageGroup& Page::group()
Modified: branches/safari-610-branch/Source/WebCore/rendering/PaintFrequencyTracker.h (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/rendering/PaintFrequencyTracker.h 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/rendering/PaintFrequencyTracker.h 2020-09-18 19:36:17 UTC (rev 267270)
@@ -37,7 +37,7 @@
public:
PaintFrequencyTracker() = default;
- void begin()
+ void begin(MonotonicTime timestamp)
{
static unsigned paintFrequencyPaintCountThreshold = 30;
static Seconds paintFrequencyTimePerFrameThreshold = 32_ms;
@@ -46,14 +46,13 @@
// Start by assuming the paint frequency is low
m_paintFrequency = PaintFrequency::Low;
- MonotonicTime now = MonotonicTime::now();
if (!m_firstPaintTime) {
// Handle the first time this method is called.
- m_firstPaintTime = now;
- } else if (now - m_lastPaintTime > paintFrequencySecondsIdleThreshold) {
+ m_firstPaintTime = timestamp;
+ } else if (timestamp - m_lastPaintTime > paintFrequencySecondsIdleThreshold) {
// It has been 5 seconds since last time we draw this renderer. Reset the state
// of this object as if, we've just started tracking the paint frequency.
- m_firstPaintTime = now;
+ m_firstPaintTime = timestamp;
m_totalPaints = 0;
} else if (m_totalPaints >= paintFrequencyPaintCountThreshold && ((m_lastPaintTime - m_firstPaintTime) / m_totalPaints) <= paintFrequencyTimePerFrameThreshold) {
// Change the paint frequency to be high only if:
@@ -62,7 +61,7 @@
m_paintFrequency = PaintFrequency::High;
}
- m_lastPaintTime = now;
+ m_lastPaintTime = timestamp;
++m_totalPaints;
}
@@ -79,7 +78,7 @@
MonotonicTime m_lastPaintTime;
unsigned m_totalPaints { 0 };
- enum class PaintFrequency { Low, High };
+ enum class PaintFrequency : bool { Low, High };
PaintFrequency m_paintFrequency { PaintFrequency::Low };
};
@@ -86,12 +85,12 @@
class SinglePaintFrequencyTracking {
WTF_MAKE_FAST_ALLOCATED;
public:
- SinglePaintFrequencyTracking(PaintFrequencyTracker& paintFrequencyTracker, bool track = true)
+ SinglePaintFrequencyTracking(PaintFrequencyTracker& paintFrequencyTracker, MonotonicTime timestamp, bool track = true)
: m_paintFrequencyTracker(paintFrequencyTracker)
, m_track(track)
{
if (m_track)
- m_paintFrequencyTracker.begin();
+ m_paintFrequencyTracker.begin(timestamp);
}
~SinglePaintFrequencyTracking()
Modified: branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.cpp (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.cpp 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.cpp 2020-09-18 19:36:17 UTC (rev 267270)
@@ -4630,7 +4630,7 @@
bool selectionAndBackgroundsOnly = paintingInfo.paintBehavior.contains(PaintBehavior::SelectionAndBackgroundsOnly);
bool selectionOnly = paintingInfo.paintBehavior.contains(PaintBehavior::SelectionOnly);
- SinglePaintFrequencyTracking singlePaintFrequencyTracking(m_paintFrequencyTracker, shouldPaintContent);
+ SinglePaintFrequencyTracking singlePaintFrequencyTracking(m_paintFrequencyTracker, page().chrome().client().timestampForPaintFrequencyTracking(), shouldPaintContent && !context.performingPaintInvalidation());
LayerFragments layerFragments;
RenderObject* subtreePaintRootForRenderer = nullptr;
@@ -7027,6 +7027,11 @@
return false;
}
+void RenderLayer::simulateFrequentPaint()
+{
+ SinglePaintFrequencyTracking { m_paintFrequencyTracker, page().chrome().client().timestampForPaintFrequencyTracking() };
+}
+
#if !LOG_DISABLED
static TextStream& operator<<(TextStream& ts, RenderLayer::EventRegionInvalidationReason reason)
{
Modified: branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.h (267269 => 267270)
--- branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.h 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebCore/rendering/RenderLayer.h 2020-09-18 19:36:17 UTC (rev 267270)
@@ -920,7 +920,7 @@
bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return renderer().shouldPlaceBlockDirectionScrollbarOnLeft(); }
- void simulateFrequentPaint() { SinglePaintFrequencyTracking { m_paintFrequencyTracker }; }
+ WEBCORE_EXPORT void simulateFrequentPaint();
bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); }
WEBCORE_EXPORT bool isTransparentRespectingParentFrames() const;
Modified: branches/safari-610-branch/Source/WebKit/ChangeLog (267269 => 267270)
--- branches/safari-610-branch/Source/WebKit/ChangeLog 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebKit/ChangeLog 2020-09-18 19:36:17 UTC (rev 267270)
@@ -1,5 +1,91 @@
2020-09-17 Alan Coon <[email protected]>
+ Cherry-pick r266677. rdar://problem/68740521
+
+ [MotionMark] RenderLayer::paintLayerContents spends ~5% of the time in MonotonicTime::now() in Multiply
+ https://bugs.webkit.org/show_bug.cgi?id=216190
+
+ Reviewed by Darin Adler.
+
+ Source/WebCore:
+
+ In several of MotionMark's subtests (for instance, Multiply), we spent a large amount of time underneath
+ `RenderLayer::paintLayerContents` due to both the large number of layers and the need to frequently repaint
+ each layer (all of which are constantly being animated). Underneath this method, a nontrivial amount of time
+ (~5%) is then spent grabbing the system time via `MonotonicTime::now()`.
+
+ We can avoid this extra work by instead using the timestamp of the last rendering update (before we started
+ painting), which we keep track of using a new member variable on `Page`. See below for more details, as well as
+ the WebKit2 ChangeLog.
+
+ * page/ChromeClient.h:
+ (WebCore::ChromeClient::timestampForPaintFrequencyTracking const):
+
+ Add a client hook to fetch the timestamp to use when tracking painting frequency. See the WebKit2 ChangeLog for
+ more details.
+
+ * page/Page.cpp:
+ (WebCore::Page::updateRendering):
+
+ Update `m_lastRenderingUpdateTimestamp`.
+
+ * page/Page.h:
+ (WebCore::Page::lastRenderingUpdateTimestamp const):
+ * rendering/PaintFrequencyTracker.h:
+
+ Drive-by cleanup: narrow the `PaintFrequency` enum to `bool` width.
+
+ (WebCore::PaintFrequencyTracker::begin):
+ (WebCore::SinglePaintFrequencyTracking::SinglePaintFrequencyTracking):
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+
+ Call out to the client layer to return a timestamp for tracking painting frequency. By default, this is simply
+ the current time (`MonotonicTime::now()`), but ports (namely, WebKit2) may opt for a coarser granularity.
+
+ (WebCore::RenderLayer::simulateFrequentPaint):
+ * rendering/RenderLayer.h:
+
+ Source/WebKit:
+
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::timestampForPaintFrequencyTracking const):
+
+ In WebKit2, we can assume (with the exception of SVG pages) that we must've performed a rendering update prior
+ to tracking painting frequencies. As such, we can use the page's rendering update timestamp instead of the real
+ current time (`MonotonicTime::now()`).
+
+ Note that in WebKit1, it is possible for any client to force a synchronous paint of the page before the page has
+ performed a rendering update, which triggers assertions in `SinglePaintFrequencyTracking::end()`. As such, we
+ stick with `MonotonicTime::now()` in WebKit1.
+
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@266677 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2020-09-05 Wenson Hsieh <[email protected]>
+
+ [MotionMark] RenderLayer::paintLayerContents spends ~5% of the time in MonotonicTime::now() in Multiply
+ https://bugs.webkit.org/show_bug.cgi?id=216190
+
+ Reviewed by Darin Adler.
+
+ * WebProcess/WebCoreSupport/WebChromeClient.cpp:
+ (WebKit::WebChromeClient::timestampForPaintFrequencyTracking const):
+
+ In WebKit2, we can assume (with the exception of SVG pages) that we must've performed a rendering update prior
+ to tracking painting frequencies. As such, we can use the page's rendering update timestamp instead of the real
+ current time (`MonotonicTime::now()`).
+
+ Note that in WebKit1, it is possible for any client to force a synchronous paint of the page before the page has
+ performed a rendering update, which triggers assertions in `SinglePaintFrequencyTracking::end()`. As such, we
+ stick with `MonotonicTime::now()` in WebKit1.
+
+ * WebProcess/WebCoreSupport/WebChromeClient.h:
+
+2020-09-17 Alan Coon <[email protected]>
+
Cherry-pick r267031. rdar://problem/69101165
Web Inspector: docking buttons don't work when already docked if window is too small
Modified: branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp (267269 => 267270)
--- branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.cpp 2020-09-18 19:36:17 UTC (rev 267270)
@@ -1150,6 +1150,11 @@
return m_page.drawingArea()->shouldUseTiledBackingForFrameView(frameView);
}
+MonotonicTime WebChromeClient::timestampForPaintFrequencyTracking() const
+{
+ return isSVGImageChromeClient() ? MonotonicTime::now() : m_page.corePage()->lastRenderingUpdateTimestamp();
+}
+
void WebChromeClient::isPlayingMediaDidChange(MediaProducer::MediaStateFlags state, uint64_t sourceElementID)
{
m_page.send(Messages::WebPageProxy::IsPlayingMediaDidChange(state, sourceElementID));
Modified: branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h (267269 => 267270)
--- branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2020-09-18 19:36:14 UTC (rev 267269)
+++ branches/safari-610-branch/Source/WebKit/WebProcess/WebCoreSupport/WebChromeClient.h 2020-09-18 19:36:17 UTC (rev 267270)
@@ -333,6 +333,8 @@
bool shouldUseTiledBackingForFrameView(const WebCore::FrameView&) const final;
+ MonotonicTime timestampForPaintFrequencyTracking() const final;
+
void isPlayingMediaDidChange(WebCore::MediaProducer::MediaStateFlags, uint64_t) final;
void handleAutoplayEvent(WebCore::AutoplayEvent, OptionSet<WebCore::AutoplayEventFlags>) final;