| Index: third_party/WebKit/Source/core/frame/FrameView.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| index d72cf5eeb900e3de2c4832ecce03c1e90cefbd1e..935e99f1e23153a62f2fa288fef8548cc1b65c6f 100644
|
| --- a/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
|
| @@ -180,6 +180,7 @@ FrameView::FrameView(LocalFrame* frame)
|
| m_frameTimingRequestsDirty(true),
|
| m_hiddenForThrottling(false),
|
| m_subtreeThrottled(false),
|
| + m_lifecycleUpdatesThrottled(false),
|
| m_currentUpdateLifecyclePhasesTargetState(
|
| DocumentLifecycle::Uninitialized),
|
| m_scrollAnchor(this),
|
| @@ -227,6 +228,12 @@ DEFINE_TRACE(FrameView) {
|
| }
|
|
|
| void FrameView::reset() {
|
| + // The compositor throttles the main frame using deferred commits, we can't
|
| + // throttle it here or it seems the root compositor doesn't get setup
|
| + // properly.
|
| + if (RuntimeEnabledFeatures::
|
| + renderingPipelineThrottlingLoadingIframesEnabled())
|
| + m_lifecycleUpdatesThrottled = !frame().isMainFrame();
|
| m_hasPendingLayout = false;
|
| m_layoutSchedulingEnabled = true;
|
| m_inSynchronousPostLayout = false;
|
| @@ -298,6 +305,7 @@ void FrameView::setupRenderThrottling() {
|
| [](FrameView* frameView, bool isVisible) {
|
| frameView->updateRenderThrottlingStatus(
|
| !isVisible, frameView->m_subtreeThrottled);
|
| + frameView->maybeRecordLoadReason();
|
| },
|
| wrapWeakPersistent(this)));
|
| m_visibilityObserver->start();
|
| @@ -4440,6 +4448,19 @@ void FrameView::updateRenderThrottlingStatus(bool hidden,
|
| hasHandlers)
|
| scrollingCoordinator->touchEventTargetRectsDidChange();
|
|
|
| +#if DCHECK_IS_ON()
|
| + // Make sure we never have an unthrottled frame inside a throttled one.
|
| + FrameView* parent = parentFrameView();
|
| + while (parent) {
|
| + DCHECK(canThrottleRendering() || !parent->canThrottleRendering());
|
| + parent = parent->parentFrameView();
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +// TODO(esprehn): Rename this and the method on Document to
|
| +// recordDeferredLoadReason().
|
| +void FrameView::maybeRecordLoadReason() {
|
| FrameView* parent = parentFrameView();
|
| if (frame().document()->frame()) {
|
| if (!parent) {
|
| @@ -4470,14 +4491,6 @@ void FrameView::updateRenderThrottlingStatus(bool hidden,
|
| }
|
| }
|
| }
|
| -
|
| -#if DCHECK_IS_ON()
|
| - // Make sure we never have an unthrottled frame inside a throttled one.
|
| - while (parent) {
|
| - DCHECK(canThrottleRendering() || !parent->canThrottleRendering());
|
| - parent = parent->parentFrameView();
|
| - }
|
| -#endif
|
| }
|
|
|
| bool FrameView::shouldThrottleRendering() const {
|
| @@ -4485,16 +4498,32 @@ bool FrameView::shouldThrottleRendering() const {
|
| }
|
|
|
| bool FrameView::canThrottleRendering() const {
|
| + if (m_lifecycleUpdatesThrottled)
|
| + return true;
|
| if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
|
| return false;
|
| - // We only throttle the rendering pipeline in cross-origin frames. This is
|
| - // to avoid a situation where an ancestor frame directly depends on the
|
| - // pipeline timing of a descendant and breaks as a result of throttling.
|
| - // The rationale is that cross-origin frames must already communicate with
|
| - // asynchronous messages, so they should be able to tolerate some delay in
|
| - // receiving replies from a throttled peer.
|
| - return m_subtreeThrottled ||
|
| - (m_hiddenForThrottling && m_frame->isCrossOriginSubframe());
|
| + if (m_subtreeThrottled)
|
| + return true;
|
| + // We only throttle hidden cross-origin frames. This is to avoid a situation
|
| + // where an ancestor frame directly depends on the pipeline timing of a
|
| + // descendant and breaks as a result of throttling. The rationale is that
|
| + // cross-origin frames must already communicate with asynchronous messages,
|
| + // so they should be able to tolerate some delay in receiving replies from a
|
| + // throttled peer.
|
| + return m_hiddenForThrottling && m_frame->isCrossOriginSubframe();
|
| +}
|
| +
|
| +void FrameView::beginLifecycleUpdates() {
|
| + // Avoid pumping frames for the initially empty document.
|
| + if (!frame().loader().stateMachine()->committedFirstRealDocumentLoad())
|
| + return;
|
| + m_lifecycleUpdatesThrottled = false;
|
| + setupRenderThrottling();
|
| + updateRenderThrottlingStatus(m_hiddenForThrottling, m_subtreeThrottled);
|
| + // The compositor will "defer commits" for the main frame until we
|
| + // explicitly request them.
|
| + if (frame().isMainFrame())
|
| + frame().host()->chromeClient().beginLifecycleUpdates();
|
| }
|
|
|
| void FrameView::setInitialViewportSize(const IntSize& viewportSize) {
|
|
|