Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(193)

Side by Side Diff: third_party/WebKit/Source/core/frame/FrameView.cpp

Issue 1364063007: Throttle rendering pipeline for invisible frames (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: IntersectionObserverification Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 #include "platform/TraceEvent.h" 86 #include "platform/TraceEvent.h"
87 #include "platform/TracedValue.h" 87 #include "platform/TracedValue.h"
88 #include "platform/fonts/FontCache.h" 88 #include "platform/fonts/FontCache.h"
89 #include "platform/geometry/DoubleRect.h" 89 #include "platform/geometry/DoubleRect.h"
90 #include "platform/geometry/FloatRect.h" 90 #include "platform/geometry/FloatRect.h"
91 #include "platform/geometry/LayoutRect.h" 91 #include "platform/geometry/LayoutRect.h"
92 #include "platform/graphics/GraphicsContext.h" 92 #include "platform/graphics/GraphicsContext.h"
93 #include "platform/graphics/GraphicsLayer.h" 93 #include "platform/graphics/GraphicsLayer.h"
94 #include "platform/graphics/GraphicsLayerDebugInfo.h" 94 #include "platform/graphics/GraphicsLayerDebugInfo.h"
95 #include "platform/graphics/paint/DisplayItemList.h" 95 #include "platform/graphics/paint/DisplayItemList.h"
96 #include "platform/scheduler/CancellableTaskFactory.h"
96 #include "platform/scroll/ScrollAnimator.h" 97 #include "platform/scroll/ScrollAnimator.h"
97 #include "platform/text/TextStream.h" 98 #include "platform/text/TextStream.h"
98 #include "public/platform/WebDisplayItemList.h" 99 #include "public/platform/WebDisplayItemList.h"
100 #include "public/platform/WebFrameScheduler.h"
99 #include "wtf/CurrentTime.h" 101 #include "wtf/CurrentTime.h"
100 #include "wtf/StdLibExtras.h" 102 #include "wtf/StdLibExtras.h"
101 #include "wtf/TemporaryChange.h" 103 #include "wtf/TemporaryChange.h"
102 104
103 namespace blink { 105 namespace blink {
104 106
105 using namespace HTMLNames; 107 using namespace HTMLNames;
106 108
107 // The maximum number of updateWidgets iterations that should be done before ret urning. 109 // The maximum number of updateWidgets iterations that should be done before ret urning.
108 static const unsigned maxUpdateWidgetsIterations = 2; 110 static const unsigned maxUpdateWidgetsIterations = 2;
109 static const double resourcePriorityUpdateDelayAfterScroll = 0.250; 111 static const double resourcePriorityUpdateDelayAfterScroll = 0.250;
110 112
111 static bool s_initialTrackAllPaintInvalidations = false; 113 static bool s_initialTrackAllPaintInvalidations = false;
112 114
113 FrameView::FrameView(LocalFrame* frame) 115 FrameView::FrameView(LocalFrame* frame)
114 : m_frame(frame) 116 : m_frame(frame)
115 , m_displayMode(WebDisplayModeBrowser) 117 , m_displayMode(WebDisplayModeBrowser)
116 , m_canHaveScrollbars(true) 118 , m_canHaveScrollbars(true)
117 , m_slowRepaintObjectCount(0) 119 , m_slowRepaintObjectCount(0)
118 , m_hasPendingLayout(false) 120 , m_hasPendingLayout(false)
119 , m_inSynchronousPostLayout(false) 121 , m_inSynchronousPostLayout(false)
120 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) 122 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
121 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) 123 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
124 , m_intersectionObserverNotificationFactory(CancellableTaskFactory::create(t his, &FrameView::notifyIntersectionObservers))
122 , m_isTransparent(false) 125 , m_isTransparent(false)
123 , m_baseBackgroundColor(Color::white) 126 , m_baseBackgroundColor(Color::white)
124 , m_mediaType(MediaTypeNames::screen) 127 , m_mediaType(MediaTypeNames::screen)
125 , m_safeToPropagateScrollToParent(true) 128 , m_safeToPropagateScrollToParent(true)
126 , m_isTrackingPaintInvalidations(false) 129 , m_isTrackingPaintInvalidations(false)
127 , m_scrollCorner(nullptr) 130 , m_scrollCorner(nullptr)
128 , m_inputEventsScaleFactorForEmulation(1) 131 , m_inputEventsScaleFactorForEmulation(1)
129 , m_layoutSizeFixedToFrameSize(true) 132 , m_layoutSizeFixedToFrameSize(true)
130 , m_didScrollTimer(this, &FrameView::didScrollTimerFired) 133 , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
131 , m_topControlsViewportAdjustment(0) 134 , m_topControlsViewportAdjustment(0)
132 , m_needsUpdateWidgetPositions(false) 135 , m_needsUpdateWidgetPositions(false)
136 , m_needsUpdateViewportIntersection(true)
133 #if ENABLE(ASSERT) 137 #if ENABLE(ASSERT)
134 , m_hasBeenDisposed(false) 138 , m_hasBeenDisposed(false)
135 #endif 139 #endif
136 , m_horizontalScrollbarMode(ScrollbarAuto) 140 , m_horizontalScrollbarMode(ScrollbarAuto)
137 , m_verticalScrollbarMode(ScrollbarAuto) 141 , m_verticalScrollbarMode(ScrollbarAuto)
138 , m_horizontalScrollbarLock(false) 142 , m_horizontalScrollbarLock(false)
139 , m_verticalScrollbarLock(false) 143 , m_verticalScrollbarLock(false)
140 , m_scrollbarsAvoidingResizer(0) 144 , m_scrollbarsAvoidingResizer(0)
141 , m_scrollbarsSuppressed(false) 145 , m_scrollbarsSuppressed(false)
142 , m_inUpdateScrollbars(false) 146 , m_inUpdateScrollbars(false)
143 , m_frameTimingRequestsDirty(true) 147 , m_frameTimingRequestsDirty(true)
144 148 , m_viewportIntersectionValid(false)
149 , m_viewportVisibilityForThrottling(ViewportVisibility::Visible)
150 , m_securityOriginStatusForThrottling(SecurityOriginStatus::IsSameOrigin)
145 { 151 {
146 ASSERT(m_frame); 152 ASSERT(m_frame);
147 init(); 153 init();
148 } 154 }
149 155
150 PassRefPtrWillBeRawPtr<FrameView> FrameView::create(LocalFrame* frame) 156 PassRefPtrWillBeRawPtr<FrameView> FrameView::create(LocalFrame* frame)
151 { 157 {
152 RefPtrWillBeRawPtr<FrameView> view = adoptRefWillBeNoop(new FrameView(frame) ); 158 RefPtrWillBeRawPtr<FrameView> view = adoptRefWillBeNoop(new FrameView(frame) );
153 view->show(); 159 view->show();
154 return view.release(); 160 return view.release();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 266
261 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing 267 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
262 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|. 268 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
263 m_autoSizeInfo.clear(); 269 m_autoSizeInfo.clear();
264 270
265 if (m_postLayoutTasksTimer.isActive()) 271 if (m_postLayoutTasksTimer.isActive())
266 m_postLayoutTasksTimer.stop(); 272 m_postLayoutTasksTimer.stop();
267 273
268 if (m_didScrollTimer.isActive()) 274 if (m_didScrollTimer.isActive())
269 m_didScrollTimer.stop(); 275 m_didScrollTimer.stop();
276 m_intersectionObserverNotificationFactory->cancel();
270 277
271 // FIXME: Do we need to do something here for OOPI? 278 // FIXME: Do we need to do something here for OOPI?
272 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); 279 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
273 // TODO(dcheng): It seems buggy that we can have an owner element that 280 // TODO(dcheng): It seems buggy that we can have an owner element that
274 // points to another Widget. 281 // points to another Widget.
275 if (ownerElement && ownerElement->ownedWidget() == this) 282 if (ownerElement && ownerElement->ownedWidget() == this)
276 ownerElement->setWidget(nullptr); 283 ownerElement->setWidget(nullptr);
277 284
278 #if ENABLE(ASSERT) 285 #if ENABLE(ASSERT)
279 m_hasBeenDisposed = true; 286 m_hasBeenDisposed = true;
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 877
871 void FrameView::layout() 878 void FrameView::layout()
872 { 879 {
873 // We should never layout a Document which is not in a LocalFrame. 880 // We should never layout a Document which is not in a LocalFrame.
874 ASSERT(m_frame); 881 ASSERT(m_frame);
875 ASSERT(m_frame->view() == this); 882 ASSERT(m_frame->view() == this);
876 ASSERT(m_frame->page()); 883 ASSERT(m_frame->page());
877 884
878 ScriptForbiddenScope forbidScript; 885 ScriptForbiddenScope forbidScript;
879 886
880 if (isInPerformLayout() || !m_frame->document()->isActive()) 887 if (isInPerformLayout() || !m_frame->document()->isActive() || shouldThrottl eStyleLayoutAndCompositingUpdates())
881 return; 888 return;
882 889
883 TRACE_EVENT0("blink,benchmark", "FrameView::layout"); 890 TRACE_EVENT0("blink,benchmark", "FrameView::layout");
884 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout"); 891 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout");
885 892
886 // Protect the view from being deleted during layout (in recalcStyle) 893 // Protect the view from being deleted during layout (in recalcStyle)
887 RefPtrWillBeRawPtr<FrameView> protector(this); 894 RefPtrWillBeRawPtr<FrameView> protector(this);
888 895
889 if (m_autoSizeInfo) 896 if (m_autoSizeInfo)
890 m_autoSizeInfo->autoSizeIfNeeded(); 897 m_autoSizeInfo->autoSizeIfNeeded();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 1061
1055 frame().document()->layoutUpdated(); 1062 frame().document()->layoutUpdated();
1056 } 1063 }
1057 1064
1058 // The plan is to move to compositor-queried paint invalidation, in which case t his 1065 // The plan is to move to compositor-queried paint invalidation, in which case t his
1059 // method would setNeedsRedraw on the GraphicsLayers with invalidations and 1066 // method would setNeedsRedraw on the GraphicsLayers with invalidations and
1060 // let the compositor pick which to actually draw. 1067 // let the compositor pick which to actually draw.
1061 // See http://crbug.com/306706 1068 // See http://crbug.com/306706
1062 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State) 1069 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State)
1063 { 1070 {
1071 if (shouldThrottleRenderingPipeline())
1072 return;
1073
1064 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation); 1074 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation);
1065 1075
1066 ASSERT(layoutView()); 1076 ASSERT(layoutView());
1067 LayoutView& rootForPaintInvalidation = *layoutView(); 1077 LayoutView& rootForPaintInvalidation = *layoutView();
1068 ASSERT(!rootForPaintInvalidation.needsLayout()); 1078 ASSERT(!rootForPaintInvalidation.needsLayout());
1069 1079
1070 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii()); 1080 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii());
1071 1081
1072 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState); 1082 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState);
1073 1083
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 } 1273 }
1264 1274
1265 bool FrameView::shouldSetCursor() const 1275 bool FrameView::shouldSetCursor() const
1266 { 1276 {
1267 Page* page = frame().page(); 1277 Page* page = frame().page();
1268 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse(); 1278 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse();
1269 } 1279 }
1270 1280
1271 void FrameView::scrollContentsIfNeededRecursive() 1281 void FrameView::scrollContentsIfNeededRecursive()
1272 { 1282 {
1283 if (shouldThrottleStyleLayoutAndCompositingUpdates())
1284 return;
1273 scrollContentsIfNeeded(); 1285 scrollContentsIfNeeded();
1274 1286
1275 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) { 1287 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
1276 if (!child->isLocalFrame()) 1288 if (!child->isLocalFrame())
1277 continue; 1289 continue;
1278 if (FrameView* view = toLocalFrame(child)->view()) 1290 if (FrameView* view = toLocalFrame(child)->view())
1279 view->scrollContentsIfNeededRecursive(); 1291 view->scrollContentsIfNeededRecursive();
1280 } 1292 }
1281 } 1293 }
1282 1294
1295 void FrameView::setLifecycleThrottlingModeForSubtree(DocumentLifecycle::Throttli ngMode throttlingMode)
1296 {
1297 ASSERT(m_frame->isLocalRoot());
1298 for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext (m_frame.get())) {
1299 if (!frame->isLocalFrame())
1300 continue;
1301 if (FrameView* view = toLocalFrame(frame)->view())
1302 view->lifecycle().setThrottlingMode(throttlingMode);
1303 }
1304 }
1305
1283 bool FrameView::invalidateViewportConstrainedObjects() 1306 bool FrameView::invalidateViewportConstrainedObjects()
1284 { 1307 {
1285 for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) { 1308 for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) {
1286 LayoutObject* layoutObject = viewportConstrainedObject; 1309 LayoutObject* layoutObject = viewportConstrainedObject;
1287 ASSERT(layoutObject->style()->hasViewportConstrainedPosition()); 1310 ASSERT(layoutObject->style()->hasViewportConstrainedPosition());
1288 ASSERT(layoutObject->hasLayer()); 1311 ASSERT(layoutObject->hasLayer());
1289 PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer(); 1312 PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
1290 1313
1291 if (layer->isPaintInvalidationContainer()) 1314 if (layer->isPaintInvalidationContainer())
1292 continue; 1315 continue;
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 if (!m_frame->document()->shouldScheduleLayout()) 1706 if (!m_frame->document()->shouldScheduleLayout())
1684 return; 1707 return;
1685 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get())); 1708 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get()));
1686 1709
1687 clearLayoutSubtreeRootsAndMarkContainingBlocks(); 1710 clearLayoutSubtreeRootsAndMarkContainingBlocks();
1688 1711
1689 if (m_hasPendingLayout) 1712 if (m_hasPendingLayout)
1690 return; 1713 return;
1691 m_hasPendingLayout = true; 1714 m_hasPendingLayout = true;
1692 1715
1693 page()->animator().scheduleVisualUpdate(m_frame.get()); 1716 if (!shouldThrottleRenderingPipeline())
1717 page()->animator().scheduleVisualUpdate(m_frame.get());
1694 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); 1718 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
1695 } 1719 }
1696 1720
1697 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) 1721 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot)
1698 { 1722 {
1699 ASSERT(m_frame->view() == this); 1723 ASSERT(m_frame->view() == this);
1700 1724
1701 // FIXME: Should this call shouldScheduleLayout instead? 1725 // FIXME: Should this call shouldScheduleLayout instead?
1702 if (!m_frame->document()->isActive()) 1726 if (!m_frame->document()->isActive())
1703 return; 1727 return;
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 void FrameView::updateWidgetPositionsIfNeeded() 2397 void FrameView::updateWidgetPositionsIfNeeded()
2374 { 2398 {
2375 if (!m_needsUpdateWidgetPositions) 2399 if (!m_needsUpdateWidgetPositions)
2376 return; 2400 return;
2377 2401
2378 m_needsUpdateWidgetPositions = false; 2402 m_needsUpdateWidgetPositions = false;
2379 2403
2380 updateWidgetPositions(); 2404 updateWidgetPositions();
2381 } 2405 }
2382 2406
2383 void FrameView::updateAllLifecyclePhases(const LayoutRect& interestRect) 2407 void FrameView::updateAllLifecyclePhases(DocumentLifecycle::ThrottlingMode throt tlingMode, const LayoutRect& interestRect)
2384 { 2408 {
2385 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(AllPhases, i nterestRect); 2409 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(AllPhases, t hrottlingMode, interestRect);
2386 } 2410 }
2387 2411
2388 // TODO(chrishtr): add a scrolling update lifecycle phase. 2412 // TODO(chrishtr): add a scrolling update lifecycle phase.
2389 void FrameView::updateLifecycleToCompositingCleanPlusScrolling() 2413 void FrameView::updateLifecycleToCompositingCleanPlusScrolling(DocumentLifecycle ::ThrottlingMode throttlingMode)
2390 { 2414 {
2391 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToComp ositingCleanPlusScrolling); 2415 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToComp ositingCleanPlusScrolling, throttlingMode, LayoutRect::infiniteRect());
2392 } 2416 }
2393 2417
2394 void FrameView::updateLifecycleToLayoutClean() 2418 void FrameView::updateLifecycleToLayoutClean(DocumentLifecycle::ThrottlingMode t hrottlingMode)
2395 { 2419 {
2396 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToLayo utClean); 2420 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToLayo utClean, throttlingMode, LayoutRect::infiniteRect());
2397 } 2421 }
2398 2422
2399 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, cons t LayoutRect& interestRect) 2423 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, Docu mentLifecycle::ThrottlingMode throttlingMode, const LayoutRect& interestRect)
2400 { 2424 {
2401 // This must be called from the root frame, since it recurses down, not up. 2425 // This must be called from the root frame, since it recurses down, not up.
2402 // Otherwise the lifecycles of the frames might be out of sync. 2426 // Otherwise the lifecycles of the frames might be out of sync.
2403 ASSERT(m_frame->isLocalRoot()); 2427 ASSERT(m_frame->isLocalRoot());
2404 2428
2405 // Updating layout can run script, which can tear down the FrameView. 2429 // Updating layout can run script, which can tear down the FrameView.
2406 RefPtrWillBeRawPtr<FrameView> protector(this); 2430 RefPtrWillBeRawPtr<FrameView> protector(this);
2407 2431
2432 setLifecycleThrottlingModeForSubtree(throttlingMode);
ojan 2015/10/13 23:31:29 This call and the one below are unconditional walk
Sami 2015/10/14 16:52:11 Yeah, I wasn't crazy about the extra tree walks ei
2408 updateStyleAndLayoutIfNeededRecursive(); 2433 updateStyleAndLayoutIfNeededRecursive();
2409 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2434 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean);
2410 2435
2411 if (phases == OnlyUpToLayoutClean) 2436 LayoutView* view = layoutView();
2412 return; 2437 if (view && phases != OnlyUpToLayoutClean) {
2413
2414 if (LayoutView* view = layoutView()) {
2415 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get())); 2438 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get()));
2416 2439
2417 // This was required for slimming paint v1 but is only temporarily 2440 // This was required for slimming paint v1 but is only temporarily
2418 // needed for slimming paint v2. 2441 // needed for slimming paint v2.
2419 view->compositor()->updateIfNeededRecursive(); 2442 view->compositor()->updateIfNeededRecursive();
2420 scrollContentsIfNeededRecursive(); 2443 scrollContentsIfNeededRecursive();
2421 2444
2422 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); 2445 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
2423 2446
2424 if (phases == AllPhases) { 2447 if (phases == AllPhases) {
(...skipping 15 matching lines...) Expand all
2440 2463
2441 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) 2464 if (RuntimeEnabledFeatures::frameTimingSupportEnabled())
2442 updateFrameTimingRequestsIfNeeded(); 2465 updateFrameTimingRequestsIfNeeded();
2443 2466
2444 ASSERT(!view->hasPendingSelection()); 2467 ASSERT(!view->hasPendingSelection());
2445 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean 2468 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean
2446 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) 2469 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean)
2447 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); 2470 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean));
2448 } 2471 }
2449 } 2472 }
2473
2474 updateViewportIntersectionsForSubtree();
2475 setLifecycleThrottlingModeForSubtree(DocumentLifecycle::ThrottlingMode::Disa llow);
2450 } 2476 }
2451 2477
2452 void FrameView::updatePaintProperties() 2478 void FrameView::updatePaintProperties()
2453 { 2479 {
2454 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 2480 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2455 2481
2456 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); 2482 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties);
2457 // TODO(pdr): Calculate the paint properties by walking the layout tree. 2483 // TODO(pdr): Calculate the paint properties by walking the layout tree.
2458 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); 2484 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean);
2459 } 2485 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2523 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); 2549 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests);
2524 2550
2525 for (const auto& iter : graphicsLayerTimingRequests) { 2551 for (const auto& iter : graphicsLayerTimingRequests) {
2526 const GraphicsLayer* graphicsLayer = iter.key; 2552 const GraphicsLayer* graphicsLayer = iter.key;
2527 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value); 2553 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value);
2528 } 2554 }
2529 } 2555 }
2530 2556
2531 void FrameView::updateStyleAndLayoutIfNeededRecursive() 2557 void FrameView::updateStyleAndLayoutIfNeededRecursive()
2532 { 2558 {
2559 if (shouldThrottleStyleLayoutAndCompositingUpdates())
2560 return;
2561
2533 // We have to crawl our entire subtree looking for any FrameViews that need 2562 // We have to crawl our entire subtree looking for any FrameViews that need
2534 // layout and make sure they are up to date. 2563 // layout and make sure they are up to date.
2535 // Mac actually tests for intersection with the dirty region and tries not t o 2564 // Mac actually tests for intersection with the dirty region and tries not t o
2536 // update layout for frames that are outside the dirty region. Not only doe s this seem 2565 // update layout for frames that are outside the dirty region. Not only doe s this seem
2537 // pointless (since those frames will have set a zero timer to layout anyway ), but 2566 // pointless (since those frames will have set a zero timer to layout anyway ), but
2538 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2567 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
2539 // region but then become included later by the second frame adding rects to the dirty region 2568 // region but then become included later by the second frame adding rects to the dirty region
2540 // when it lays out. 2569 // when it lays out.
2541 2570
2542 m_frame->document()->updateLayoutTreeIfNeeded(); 2571 m_frame->document()->updateLayoutTreeIfNeeded();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 2606
2578 updateWidgetPositionsIfNeeded(); 2607 updateWidgetPositionsIfNeeded();
2579 2608
2580 if (lifecycle().state() < DocumentLifecycle::LayoutClean) 2609 if (lifecycle().state() < DocumentLifecycle::LayoutClean)
2581 lifecycle().advanceTo(DocumentLifecycle::LayoutClean); 2610 lifecycle().advanceTo(DocumentLifecycle::LayoutClean);
2582 } 2611 }
2583 2612
2584 void FrameView::invalidateTreeIfNeededRecursive() 2613 void FrameView::invalidateTreeIfNeededRecursive()
2585 { 2614 {
2586 ASSERT(layoutView()); 2615 ASSERT(layoutView());
2616
2617 // We need to stop recursing here since a child frame view might not be thro ttled
2618 // even though we are (e.g., it didn't compute its visibility yet).
2619 if (shouldThrottleRenderingPipeline())
2620 return;
2587 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii()); 2621 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii());
2588 2622
2589 Vector<LayoutObject*> pendingDelayedPaintInvalidations; 2623 Vector<LayoutObject*> pendingDelayedPaintInvalidations;
2590 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations); 2624 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations);
2591 2625
2592 invalidateTreeIfNeeded(rootPaintInvalidationState); 2626 invalidateTreeIfNeeded(rootPaintInvalidationState);
2593 2627
2594 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause 2628 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause
2595 // - the frame is a detached frame; or 2629 // - the frame is a detached frame; or
2596 // - it didn't need paint invalidation. 2630 // - it didn't need paint invalidation.
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2895 2929
2896 if (m_scrollbarsAvoidingResizer && parent()) 2930 if (m_scrollbarsAvoidingResizer && parent())
2897 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer); 2931 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer);
2898 2932
2899 Widget::setParent(parentView); 2933 Widget::setParent(parentView);
2900 2934
2901 if (m_scrollbarsAvoidingResizer && parent()) 2935 if (m_scrollbarsAvoidingResizer && parent())
2902 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer); 2936 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer);
2903 2937
2904 updateScrollableAreaSet(); 2938 updateScrollableAreaSet();
2939 m_needsUpdateViewportIntersection = true;
2905 } 2940 }
2906 2941
2907 void FrameView::removeChild(Widget* child) 2942 void FrameView::removeChild(Widget* child)
2908 { 2943 {
2909 ASSERT(child->parent() == this); 2944 ASSERT(child->parent() == this);
2910 2945
2911 if (child->isFrameView()) 2946 if (child->isFrameView())
2912 removeScrollableArea(toFrameView(child)); 2947 removeScrollableArea(toFrameView(child));
2913 2948
2914 child->setParent(0); 2949 child->setParent(0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 return; 2987 return;
2953 page->chromeClient().setCursor(cursor); 2988 page->chromeClient().setCursor(cursor);
2954 } 2989 }
2955 2990
2956 void FrameView::frameRectsChanged() 2991 void FrameView::frameRectsChanged()
2957 { 2992 {
2958 TRACE_EVENT0("blink", "FrameView::frameRectsChanged"); 2993 TRACE_EVENT0("blink", "FrameView::frameRectsChanged");
2959 if (layoutSizeFixedToFrameSize()) 2994 if (layoutSizeFixedToFrameSize())
2960 setLayoutSizeInternal(frameRect().size()); 2995 setLayoutSizeInternal(frameRect().size());
2961 2996
2997 m_needsUpdateViewportIntersection = true;
2962 for (const auto& child : m_children) 2998 for (const auto& child : m_children)
2963 child->frameRectsChanged(); 2999 child->frameRectsChanged();
2964 } 3000 }
2965 3001
2966 void FrameView::setLayoutSizeInternal(const IntSize& size) 3002 void FrameView::setLayoutSizeInternal(const IntSize& size)
2967 { 3003 {
2968 if (m_layoutSize == size) 3004 if (m_layoutSize == size)
2969 return; 3005 return;
2970 3006
2971 m_layoutSize = size; 3007 m_layoutSize = size;
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
3728 return ScrollBehaviorInstant; 3764 return ScrollBehaviorInstant;
3729 } 3765 }
3730 3766
3731 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const 3767 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const
3732 { 3768 {
3733 paint(context, GlobalPaintNormalPhase, rect); 3769 paint(context, GlobalPaintNormalPhase, rect);
3734 } 3770 }
3735 3771
3736 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const 3772 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const
3737 { 3773 {
3774 // TODO(skyostil): Remove this early-out in favor of painting cached scrollb ars.
3775 if (shouldThrottleRenderingPipeline())
3776 return;
3738 FramePainter(*this).paint(context, globalPaintFlags, rect); 3777 FramePainter(*this).paint(context, globalPaintFlags, rect);
3739 } 3778 }
3740 3779
3741 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const 3780 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const
3742 { 3781 {
3782 if (shouldThrottleRenderingPipeline())
3783 return;
3743 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect); 3784 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect);
3744 } 3785 }
3745 3786
3746 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint) 3787 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint)
3747 { 3788 {
3748 if (!scrollbarCornerPresent()) 3789 if (!scrollbarCornerPresent())
3749 return false; 3790 return false;
3750 3791
3751 IntPoint framePoint = convertFromContainingWindow(windowPoint); 3792 IntPoint framePoint = convertFromContainingWindow(windowPoint);
3752 3793
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3920 } 3961 }
3921 3962
3922 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests) 3963 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests)
3923 { 3964 {
3924 if (!m_frame->isLocalFrame()) 3965 if (!m_frame->isLocalFrame())
3925 return; 3966 return;
3926 Frame* frame = m_frame.get(); 3967 Frame* frame = m_frame.get();
3927 LocalFrame* localFrame = toLocalFrame(frame); 3968 LocalFrame* localFrame = toLocalFrame(frame);
3928 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect(); 3969 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect();
3929 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation(); 3970 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation();
3971 // If the frame is being throttled, its compositing state may not be up to d ate.
3972 if (!paintInvalidationContainer->enclosingLayer()->isAllowedToQueryCompositi ngState())
3973 return;
3930 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking(); 3974 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking();
3931 3975
3932 if (!graphicsLayer) 3976 if (!graphicsLayer)
3933 return; 3977 return;
3934 3978
3935 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect); 3979 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect);
3936 3980
3937 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect))); 3981 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect)));
3938 } 3982 }
3939 3983
3984 void FrameView::updateViewportIntersectionIfNeeded()
3985 {
3986 // TODO(skyostil): Replace this with a real intersection observer.
3987
3988 // Make sure we have valid layout data in our parent view.
3989 ASSERT(!parentFrameView() || parentFrameView()->lifecycle().state() >= Docum entLifecycle::LayoutClean);
3990 if (!m_needsUpdateViewportIntersection)
3991 return;
3992
3993 // Our frame's bounds in our parent's content coordinates.
3994 m_viewportIntersection = frameRect();
3995 m_needsUpdateViewportIntersection = false;
3996 m_viewportIntersectionValid = true;
3997
3998 FrameView* parent = parentFrameView();
3999 if (!parent)
4000 return;
4001 ASSERT(!parent->m_needsUpdateViewportIntersection);
4002
4003 // If our parent is hidden, then we are too.
4004 if (parent->m_viewportIntersection.isEmpty()) {
4005 m_viewportIntersection = parent->m_viewportIntersection;
4006 return;
4007 }
4008
4009 // Transform our bounds into the root frame's content coordinate space.
4010 m_viewportIntersection = parent->contentsToRootFrame(m_viewportIntersection) ;
4011
4012 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling.
4013 IntRect viewport = parent->m_viewportIntersection;
4014 m_viewportIntersection.intersect(viewport);
4015 }
4016
4017 void FrameView::updateViewportIntersectionsForSubtree()
4018 {
4019 bool hadValidIntersection = m_viewportIntersectionValid;
4020 bool hadEmptyIntersection = m_viewportIntersection.isEmpty();
4021 updateViewportIntersectionIfNeeded();
4022 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty();
4023 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending())
4024 m_frame->frameScheduler()->timerTaskRunner()->postTask(FROM_HERE, m_inte rsectionObserverNotificationFactory->cancelAndCreate());
4025
4026 // If this view is being throttled, don't recurse to update viewport
4027 // intersections for its children because their frame coordinates may not
4028 // be up to date.
4029 if (shouldThrottleStyleLayoutAndCompositingUpdates())
4030 return;
4031
4032 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
4033 if (!child->isLocalFrame())
4034 continue;
4035 if (FrameView* view = toLocalFrame(child)->view())
4036 view->updateViewportIntersectionsForSubtree();
4037 }
4038 }
4039
4040 void FrameView::notifyIntersectionObservers()
4041 {
4042 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers");
4043 ASSERT(!isInPerformLayout());
4044 bool wasThrottled = shouldThrottleRenderingPipeline();
4045
4046 // Only offscreen frames can be throttled.
4047 m_viewportVisibilityForThrottling = (m_viewportIntersectionValid && m_viewpo rtIntersection.isEmpty()) ? ViewportVisibility::Hidden : ViewportVisibility::Vis ible;
4048
4049 // We only throttle the rendering pipeline in cross-origin frames. This is
4050 // to avoid a situation where an ancestor frame directly depends on the
4051 // pipeline timing of a descendant and breaks as a result of throttling.
4052 // The rationale is that cross-origin frames must already communicate with
4053 // asynchronous messages, so they should be able to tolerate some delay in
4054 // receiving replies from a throttled peer.
4055 //
4056 // Check if we can access our parent's security origin.
4057 m_securityOriginStatusForThrottling = SecurityOriginStatus::IsSameOrigin;
4058 Frame* parentFrame = m_frame->tree().parent();
4059 const SecurityOrigin* origin = frame().securityContext()->securityOrigin();
4060 while (parentFrame) {
4061 const SecurityOrigin* parentOrigin = parentFrame->securityContext()->sec urityOrigin();
4062 if (!origin->canAccess(parentOrigin)) {
4063 m_securityOriginStatusForThrottling = SecurityOriginStatus::IsCrossO rigin;
4064 break;
4065 }
4066 parentFrame = parentFrame->tree().parent();
4067 }
4068
4069 bool becameUnthrottled = wasThrottled && !shouldThrottleRenderingPipeline();
4070 if (becameUnthrottled)
4071 page()->animator().scheduleVisualUpdate(m_frame.get());
4072 }
4073
4074 bool FrameView::shouldThrottleStyleLayoutAndCompositingUpdates() const
4075 {
4076 return lifecycle().throttlingMode() == DocumentLifecycle::ThrottlingMode::Al low
4077 && shouldThrottleRenderingPipeline();
4078 }
4079
4080 bool FrameView::shouldThrottleRenderingPipeline() const
4081 {
4082 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
4083 return false;
4084 return m_viewportVisibilityForThrottling == ViewportVisibility::Hidden
4085 && m_securityOriginStatusForThrottling == SecurityOriginStatus::IsCrossO rigin;
4086 }
4087
3940 } // namespace blink 4088 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698