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

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: Early-out for intersection update walk. 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/PaintController.h" 95 #include "platform/graphics/paint/PaintController.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)
137 , m_needsUpdateViewportIntersectionInSubtree(true)
133 #if ENABLE(ASSERT) 138 #if ENABLE(ASSERT)
134 , m_hasBeenDisposed(false) 139 , m_hasBeenDisposed(false)
135 #endif 140 #endif
136 , m_horizontalScrollbarMode(ScrollbarAuto) 141 , m_horizontalScrollbarMode(ScrollbarAuto)
137 , m_verticalScrollbarMode(ScrollbarAuto) 142 , m_verticalScrollbarMode(ScrollbarAuto)
138 , m_horizontalScrollbarLock(false) 143 , m_horizontalScrollbarLock(false)
139 , m_verticalScrollbarLock(false) 144 , m_verticalScrollbarLock(false)
140 , m_scrollbarsAvoidingResizer(0) 145 , m_scrollbarsAvoidingResizer(0)
141 , m_scrollbarsSuppressed(false) 146 , m_scrollbarsSuppressed(false)
142 , m_inUpdateScrollbars(false) 147 , m_inUpdateScrollbars(false)
143 , m_frameTimingRequestsDirty(true) 148 , m_frameTimingRequestsDirty(true)
144 149 , m_viewportIntersectionValid(false)
150 , m_viewportVisibilityForThrottling(ViewportVisibility::Visible)
151 , m_securityOriginStatusForThrottling(SecurityOriginStatus::IsSameOrigin)
145 { 152 {
146 ASSERT(m_frame); 153 ASSERT(m_frame);
147 init(); 154 init();
148 } 155 }
149 156
150 PassRefPtrWillBeRawPtr<FrameView> FrameView::create(LocalFrame* frame) 157 PassRefPtrWillBeRawPtr<FrameView> FrameView::create(LocalFrame* frame)
151 { 158 {
152 RefPtrWillBeRawPtr<FrameView> view = adoptRefWillBeNoop(new FrameView(frame) ); 159 RefPtrWillBeRawPtr<FrameView> view = adoptRefWillBeNoop(new FrameView(frame) );
153 view->show(); 160 view->show();
154 return view.release(); 161 return view.release();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 267
261 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing 268 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
262 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|. 269 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
263 m_autoSizeInfo.clear(); 270 m_autoSizeInfo.clear();
264 271
265 if (m_postLayoutTasksTimer.isActive()) 272 if (m_postLayoutTasksTimer.isActive())
266 m_postLayoutTasksTimer.stop(); 273 m_postLayoutTasksTimer.stop();
267 274
268 if (m_didScrollTimer.isActive()) 275 if (m_didScrollTimer.isActive())
269 m_didScrollTimer.stop(); 276 m_didScrollTimer.stop();
277 m_intersectionObserverNotificationFactory->cancel();
270 278
271 // FIXME: Do we need to do something here for OOPI? 279 // FIXME: Do we need to do something here for OOPI?
272 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); 280 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
273 // TODO(dcheng): It seems buggy that we can have an owner element that 281 // TODO(dcheng): It seems buggy that we can have an owner element that
274 // points to another Widget. 282 // points to another Widget.
275 if (ownerElement && ownerElement->ownedWidget() == this) 283 if (ownerElement && ownerElement->ownedWidget() == this)
276 ownerElement->setWidget(nullptr); 284 ownerElement->setWidget(nullptr);
277 285
278 #if ENABLE(ASSERT) 286 #if ENABLE(ASSERT)
279 m_hasBeenDisposed = true; 287 m_hasBeenDisposed = true;
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 878
871 void FrameView::layout() 879 void FrameView::layout()
872 { 880 {
873 // We should never layout a Document which is not in a LocalFrame. 881 // We should never layout a Document which is not in a LocalFrame.
874 ASSERT(m_frame); 882 ASSERT(m_frame);
875 ASSERT(m_frame->view() == this); 883 ASSERT(m_frame->view() == this);
876 ASSERT(m_frame->page()); 884 ASSERT(m_frame->page());
877 885
878 ScriptForbiddenScope forbidScript; 886 ScriptForbiddenScope forbidScript;
879 887
880 if (isInPerformLayout() || !m_frame->document()->isActive()) 888 if (isInPerformLayout() || !m_frame->document()->isActive() || shouldThrottl eRenderingIfAllowed())
881 return; 889 return;
882 890
883 TRACE_EVENT0("blink,benchmark", "FrameView::layout"); 891 TRACE_EVENT0("blink,benchmark", "FrameView::layout");
884 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout"); 892 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout");
885 893
886 // Protect the view from being deleted during layout (in recalcStyle) 894 // Protect the view from being deleted during layout (in recalcStyle)
887 RefPtrWillBeRawPtr<FrameView> protector(this); 895 RefPtrWillBeRawPtr<FrameView> protector(this);
888 896
889 if (m_autoSizeInfo) 897 if (m_autoSizeInfo)
890 m_autoSizeInfo->autoSizeIfNeeded(); 898 m_autoSizeInfo->autoSizeIfNeeded();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 1062
1055 frame().document()->layoutUpdated(); 1063 frame().document()->layoutUpdated();
1056 } 1064 }
1057 1065
1058 // The plan is to move to compositor-queried paint invalidation, in which case t his 1066 // 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 1067 // method would setNeedsRedraw on the GraphicsLayers with invalidations and
1060 // let the compositor pick which to actually draw. 1068 // let the compositor pick which to actually draw.
1061 // See http://crbug.com/306706 1069 // See http://crbug.com/306706
1062 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State) 1070 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State)
1063 { 1071 {
1072 if (shouldThrottleRendering())
esprehn 2015/10/14 22:09:46 why not the ifAllowed() version? it's confusing wh
Sami 2015/10/16 16:48:08 Agreed. How about this: - shouldThrottleRendering
1073 return;
1074
1064 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation); 1075 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation);
1065 1076
1066 ASSERT(layoutView()); 1077 ASSERT(layoutView());
1067 LayoutView& rootForPaintInvalidation = *layoutView(); 1078 LayoutView& rootForPaintInvalidation = *layoutView();
1068 ASSERT(!rootForPaintInvalidation.needsLayout()); 1079 ASSERT(!rootForPaintInvalidation.needsLayout());
1069 1080
1070 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii()); 1081 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii());
1071 1082
1072 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState); 1083 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState);
1073 1084
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 } 1274 }
1264 1275
1265 bool FrameView::shouldSetCursor() const 1276 bool FrameView::shouldSetCursor() const
1266 { 1277 {
1267 Page* page = frame().page(); 1278 Page* page = frame().page();
1268 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse(); 1279 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse();
1269 } 1280 }
1270 1281
1271 void FrameView::scrollContentsIfNeededRecursive() 1282 void FrameView::scrollContentsIfNeededRecursive()
1272 { 1283 {
1284 if (shouldThrottleRenderingIfAllowed())
1285 return;
1273 scrollContentsIfNeeded(); 1286 scrollContentsIfNeeded();
1274 1287
1275 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) { 1288 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
1276 if (!child->isLocalFrame()) 1289 if (!child->isLocalFrame())
1277 continue; 1290 continue;
1278 if (FrameView* view = toLocalFrame(child)->view()) 1291 if (FrameView* view = toLocalFrame(child)->view())
1279 view->scrollContentsIfNeededRecursive(); 1292 view->scrollContentsIfNeededRecursive();
1280 } 1293 }
1281 } 1294 }
1282 1295
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1683 if (!m_frame->document()->shouldScheduleLayout()) 1696 if (!m_frame->document()->shouldScheduleLayout())
1684 return; 1697 return;
1685 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get())); 1698 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get()));
1686 1699
1687 clearLayoutSubtreeRootsAndMarkContainingBlocks(); 1700 clearLayoutSubtreeRootsAndMarkContainingBlocks();
1688 1701
1689 if (m_hasPendingLayout) 1702 if (m_hasPendingLayout)
1690 return; 1703 return;
1691 m_hasPendingLayout = true; 1704 m_hasPendingLayout = true;
1692 1705
1693 page()->animator().scheduleVisualUpdate(m_frame.get()); 1706 if (!shouldThrottleRendering())
esprehn 2015/10/14 22:09:46 this is suble, why not the IfAllowed() version?
Sami 2015/10/16 16:48:08 Fixed.
1707 page()->animator().scheduleVisualUpdate(m_frame.get());
1694 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); 1708 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
1695 } 1709 }
1696 1710
1697 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) 1711 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot)
1698 { 1712 {
1699 ASSERT(m_frame->view() == this); 1713 ASSERT(m_frame->view() == this);
1700 1714
1701 // FIXME: Should this call shouldScheduleLayout instead? 1715 // FIXME: Should this call shouldScheduleLayout instead?
1702 if (!m_frame->document()->isActive()) 1716 if (!m_frame->document()->isActive())
1703 return; 1717 return;
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 void FrameView::updateWidgetPositionsIfNeeded() 2387 void FrameView::updateWidgetPositionsIfNeeded()
2374 { 2388 {
2375 if (!m_needsUpdateWidgetPositions) 2389 if (!m_needsUpdateWidgetPositions)
2376 return; 2390 return;
2377 2391
2378 m_needsUpdateWidgetPositions = false; 2392 m_needsUpdateWidgetPositions = false;
2379 2393
2380 updateWidgetPositions(); 2394 updateWidgetPositions();
2381 } 2395 }
2382 2396
2383 void FrameView::updateAllLifecyclePhases(const LayoutRect* interestRect) 2397 void FrameView::updateAllLifecyclePhases(DocumentLifecycle::ThrottlingMode throt tlingMode, const LayoutRect* interestRect)
2384 { 2398 {
2385 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(AllPhases, i nterestRect); 2399 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(AllPhases, t hrottlingMode, interestRect);
2386 } 2400 }
2387 2401
2388 // TODO(chrishtr): add a scrolling update lifecycle phase. 2402 // TODO(chrishtr): add a scrolling update lifecycle phase.
2389 void FrameView::updateLifecycleToCompositingCleanPlusScrolling() 2403 void FrameView::updateLifecycleToCompositingCleanPlusScrolling(DocumentLifecycle ::ThrottlingMode throttlingMode)
2390 { 2404 {
2391 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToComp ositingCleanPlusScrolling, nullptr); 2405 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToComp ositingCleanPlusScrolling, throttlingMode, nullptr);
2392 } 2406 }
2393 2407
2394 void FrameView::updateLifecycleToLayoutClean() 2408 void FrameView::updateLifecycleToLayoutClean(DocumentLifecycle::ThrottlingMode t hrottlingMode)
esprehn 2015/10/14 22:09:46 you can remove all these and just use the static g
Sami 2015/10/16 16:48:08 Done.
2395 { 2409 {
2396 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToLayo utClean, nullptr); 2410 frame().localFrameRoot()->view()->updateLifecyclePhasesInternal(OnlyUpToLayo utClean, throttlingMode, nullptr);
2397 } 2411 }
2398 2412
2399 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, cons t LayoutRect* interestRect) 2413 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, Docu mentLifecycle::ThrottlingMode throttlingMode, const LayoutRect* interestRect)
2400 { 2414 {
2401 // This must be called from the root frame, since it recurses down, not up. 2415 // 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. 2416 // Otherwise the lifecycles of the frames might be out of sync.
2403 ASSERT(m_frame->isLocalRoot()); 2417 ASSERT(m_frame->isLocalRoot());
2404 2418
2405 // Updating layout can run script, which can tear down the FrameView. 2419 // Updating layout can run script, which can tear down the FrameView.
2406 RefPtrWillBeRawPtr<FrameView> protector(this); 2420 RefPtrWillBeRawPtr<FrameView> protector(this);
2407 2421
2422 ASSERT(lifecycle().throttlingMode() == DocumentLifecycle::ThrottlingMode::Al low);
2423 lifecycle().setThrottlingMode(throttlingMode);
esprehn 2015/10/14 22:09:46 use the ThrottleScope object
Sami 2015/10/16 16:48:08 Done. (Actually there's no need to do anything her
2408 updateStyleAndLayoutIfNeededRecursive(); 2424 updateStyleAndLayoutIfNeededRecursive();
2409 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2425 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean);
2410 2426
2411 if (phases == OnlyUpToLayoutClean) 2427 LayoutView* view = layoutView();
2412 return; 2428 if (view && phases != OnlyUpToLayoutClean) {
2413
2414 if (LayoutView* view = layoutView()) {
2415 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get())); 2429 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get()));
2416 2430
2417 // This was required for slimming paint v1 but is only temporarily 2431 // This was required for slimming paint v1 but is only temporarily
2418 // needed for slimming paint v2. 2432 // needed for slimming paint v2.
2419 view->compositor()->updateIfNeededRecursive(); 2433 view->compositor()->updateIfNeededRecursive();
2420 scrollContentsIfNeededRecursive(); 2434 scrollContentsIfNeededRecursive();
2421 2435
2422 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); 2436 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
2423 2437
2424 if (phases == AllPhases) { 2438 if (phases == AllPhases) {
(...skipping 15 matching lines...) Expand all
2440 2454
2441 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) 2455 if (RuntimeEnabledFeatures::frameTimingSupportEnabled())
2442 updateFrameTimingRequestsIfNeeded(); 2456 updateFrameTimingRequestsIfNeeded();
2443 2457
2444 ASSERT(!view->hasPendingSelection()); 2458 ASSERT(!view->hasPendingSelection());
2445 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean 2459 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean
2446 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) 2460 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean)
2447 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); 2461 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean));
2448 } 2462 }
2449 } 2463 }
2464
2465 updateViewportIntersectionsForSubtree();
2466 lifecycle().setThrottlingMode(DocumentLifecycle::ThrottlingMode::Allow);
2450 } 2467 }
2451 2468
2452 void FrameView::updatePaintProperties() 2469 void FrameView::updatePaintProperties()
2453 { 2470 {
2454 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 2471 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2455 2472
2456 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); 2473 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties);
2457 // TODO(pdr): Calculate the paint properties by walking the layout tree. 2474 // TODO(pdr): Calculate the paint properties by walking the layout tree.
2458 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); 2475 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean);
2459 } 2476 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); 2547 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests);
2531 2548
2532 for (const auto& iter : graphicsLayerTimingRequests) { 2549 for (const auto& iter : graphicsLayerTimingRequests) {
2533 const GraphicsLayer* graphicsLayer = iter.key; 2550 const GraphicsLayer* graphicsLayer = iter.key;
2534 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value); 2551 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value);
2535 } 2552 }
2536 } 2553 }
2537 2554
2538 void FrameView::updateStyleAndLayoutIfNeededRecursive() 2555 void FrameView::updateStyleAndLayoutIfNeededRecursive()
2539 { 2556 {
2557 if (shouldThrottleRenderingIfAllowed())
2558 return;
2559
2540 // We have to crawl our entire subtree looking for any FrameViews that need 2560 // We have to crawl our entire subtree looking for any FrameViews that need
2541 // layout and make sure they are up to date. 2561 // layout and make sure they are up to date.
2542 // Mac actually tests for intersection with the dirty region and tries not t o 2562 // Mac actually tests for intersection with the dirty region and tries not t o
2543 // update layout for frames that are outside the dirty region. Not only doe s this seem 2563 // update layout for frames that are outside the dirty region. Not only doe s this seem
2544 // pointless (since those frames will have set a zero timer to layout anyway ), but 2564 // pointless (since those frames will have set a zero timer to layout anyway ), but
2545 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2565 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
2546 // region but then become included later by the second frame adding rects to the dirty region 2566 // region but then become included later by the second frame adding rects to the dirty region
2547 // when it lays out. 2567 // when it lays out.
2548 2568
2549 m_frame->document()->updateLayoutTreeIfNeeded(); 2569 m_frame->document()->updateLayoutTreeIfNeeded();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 2604
2585 updateWidgetPositionsIfNeeded(); 2605 updateWidgetPositionsIfNeeded();
2586 2606
2587 if (lifecycle().state() < DocumentLifecycle::LayoutClean) 2607 if (lifecycle().state() < DocumentLifecycle::LayoutClean)
2588 lifecycle().advanceTo(DocumentLifecycle::LayoutClean); 2608 lifecycle().advanceTo(DocumentLifecycle::LayoutClean);
2589 } 2609 }
2590 2610
2591 void FrameView::invalidateTreeIfNeededRecursive() 2611 void FrameView::invalidateTreeIfNeededRecursive()
2592 { 2612 {
2593 ASSERT(layoutView()); 2613 ASSERT(layoutView());
2614
2615 // We need to stop recursing here since a child frame view might not be thro ttled
2616 // even though we are (e.g., it didn't compute its visibility yet).
2617 if (shouldThrottleRendering())
2618 return;
2594 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii()); 2619 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii());
2595 2620
2596 Vector<LayoutObject*> pendingDelayedPaintInvalidations; 2621 Vector<LayoutObject*> pendingDelayedPaintInvalidations;
2597 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations); 2622 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations);
2598 2623
2599 invalidateTreeIfNeeded(rootPaintInvalidationState); 2624 invalidateTreeIfNeeded(rootPaintInvalidationState);
2600 2625
2601 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause 2626 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause
2602 // - the frame is a detached frame; or 2627 // - the frame is a detached frame; or
2603 // - it didn't need paint invalidation. 2628 // - it didn't need paint invalidation.
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2902 2927
2903 if (m_scrollbarsAvoidingResizer && parent()) 2928 if (m_scrollbarsAvoidingResizer && parent())
2904 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer); 2929 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer);
2905 2930
2906 Widget::setParent(parentView); 2931 Widget::setParent(parentView);
2907 2932
2908 if (m_scrollbarsAvoidingResizer && parent()) 2933 if (m_scrollbarsAvoidingResizer && parent())
2909 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer); 2934 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer);
2910 2935
2911 updateScrollableAreaSet(); 2936 updateScrollableAreaSet();
2937 setNeedsUpdateViewportIntersection();
2912 } 2938 }
2913 2939
2914 void FrameView::removeChild(Widget* child) 2940 void FrameView::removeChild(Widget* child)
2915 { 2941 {
2916 ASSERT(child->parent() == this); 2942 ASSERT(child->parent() == this);
2917 2943
2918 if (child->isFrameView()) 2944 if (child->isFrameView())
2919 removeScrollableArea(toFrameView(child)); 2945 removeScrollableArea(toFrameView(child));
2920 2946
2921 child->setParent(0); 2947 child->setParent(0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 return; 2985 return;
2960 page->chromeClient().setCursor(cursor); 2986 page->chromeClient().setCursor(cursor);
2961 } 2987 }
2962 2988
2963 void FrameView::frameRectsChanged() 2989 void FrameView::frameRectsChanged()
2964 { 2990 {
2965 TRACE_EVENT0("blink", "FrameView::frameRectsChanged"); 2991 TRACE_EVENT0("blink", "FrameView::frameRectsChanged");
2966 if (layoutSizeFixedToFrameSize()) 2992 if (layoutSizeFixedToFrameSize())
2967 setLayoutSizeInternal(frameRect().size()); 2993 setLayoutSizeInternal(frameRect().size());
2968 2994
2995 setNeedsUpdateViewportIntersection();
2969 for (const auto& child : m_children) 2996 for (const auto& child : m_children)
2970 child->frameRectsChanged(); 2997 child->frameRectsChanged();
2971 } 2998 }
2972 2999
2973 void FrameView::setLayoutSizeInternal(const IntSize& size) 3000 void FrameView::setLayoutSizeInternal(const IntSize& size)
2974 { 3001 {
2975 if (m_layoutSize == size) 3002 if (m_layoutSize == size)
2976 return; 3003 return;
2977 3004
2978 m_layoutSize = size; 3005 m_layoutSize = size;
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
3735 return ScrollBehaviorInstant; 3762 return ScrollBehaviorInstant;
3736 } 3763 }
3737 3764
3738 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const 3765 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const
3739 { 3766 {
3740 paint(context, GlobalPaintNormalPhase, rect); 3767 paint(context, GlobalPaintNormalPhase, rect);
3741 } 3768 }
3742 3769
3743 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const 3770 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const
3744 { 3771 {
3772 // TODO(skyostil): Remove this early-out in favor of painting cached scrollb ars.
3773 if (shouldThrottleRendering())
3774 return;
3745 FramePainter(*this).paint(context, globalPaintFlags, rect); 3775 FramePainter(*this).paint(context, globalPaintFlags, rect);
3746 } 3776 }
3747 3777
3748 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const 3778 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const
3749 { 3779 {
3780 if (shouldThrottleRendering())
3781 return;
3750 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect); 3782 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect);
3751 } 3783 }
3752 3784
3753 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint) 3785 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint)
3754 { 3786 {
3755 if (!scrollbarCornerPresent()) 3787 if (!scrollbarCornerPresent())
3756 return false; 3788 return false;
3757 3789
3758 IntPoint framePoint = convertFromContainingWindow(windowPoint); 3790 IntPoint framePoint = convertFromContainingWindow(windowPoint);
3759 3791
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3927 } 3959 }
3928 3960
3929 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests) 3961 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests)
3930 { 3962 {
3931 if (!m_frame->isLocalFrame()) 3963 if (!m_frame->isLocalFrame())
3932 return; 3964 return;
3933 Frame* frame = m_frame.get(); 3965 Frame* frame = m_frame.get();
3934 LocalFrame* localFrame = toLocalFrame(frame); 3966 LocalFrame* localFrame = toLocalFrame(frame);
3935 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect(); 3967 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect();
3936 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation(); 3968 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation();
3969 // If the frame is being throttled, its compositing state may not be up to d ate.
3970 if (!paintInvalidationContainer->enclosingLayer()->isAllowedToQueryCompositi ngState())
3971 return;
3937 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking(); 3972 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking();
3938 3973
3939 if (!graphicsLayer) 3974 if (!graphicsLayer)
3940 return; 3975 return;
3941 3976
3942 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect); 3977 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect);
3943 3978
3944 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect))); 3979 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect)));
3945 } 3980 }
3946 3981
3982 void FrameView::setNeedsUpdateViewportIntersection()
3983 {
3984 m_needsUpdateViewportIntersection = true;
3985 FrameView* parent = parentFrameView();
3986 while (parent) {
esprehn 2015/10/14 22:09:46 for (FrameView* parent = parentFrameView(); parent
Sami 2015/10/16 16:48:08 Done.
3987 parent->m_needsUpdateViewportIntersectionInSubtree = true;
3988 parent = parent->parentFrameView();
3989 }
3990 }
3991
3992 void FrameView::updateViewportIntersectionIfNeeded()
3993 {
3994 // TODO(skyostil): Replace this with a real intersection observer.
3995
3996 // Make sure we have valid layout data in our parent view.
3997 ASSERT(!parentFrameView() || parentFrameView()->lifecycle().state() >= Docum entLifecycle::LayoutClean);
3998 if (!m_needsUpdateViewportIntersection)
3999 return;
4000
4001 // Our frame's bounds in our parent's content coordinates.
4002 m_viewportIntersection = frameRect();
4003 m_needsUpdateViewportIntersection = false;
4004 m_viewportIntersectionValid = true;
4005
4006 FrameView* parent = parentFrameView();
4007 if (!parent)
4008 return;
4009 ASSERT(!parent->m_needsUpdateViewportIntersection);
4010
4011 // If our parent is hidden, then we are too.
4012 if (parent->m_viewportIntersection.isEmpty()) {
4013 m_viewportIntersection = parent->m_viewportIntersection;
4014 return;
4015 }
4016
4017 // Transform our bounds into the root frame's content coordinate space.
4018 m_viewportIntersection = parent->contentsToRootFrame(m_viewportIntersection) ;
4019
4020 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling.
4021 IntRect viewport = parent->m_viewportIntersection;
4022 m_viewportIntersection.intersect(viewport);
4023 }
4024
4025 void FrameView::updateViewportIntersectionsForSubtree()
4026 {
4027 bool hadValidIntersection = m_viewportIntersectionValid;
4028 bool hadEmptyIntersection = m_viewportIntersection.isEmpty();
4029 updateViewportIntersectionIfNeeded();
4030 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty();
4031 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending())
4032 m_frame->frameScheduler()->timerTaskRunner()->postTask(FROM_HERE, m_inte rsectionObserverNotificationFactory->cancelAndCreate());
4033
4034 // If this view is being throttled, don't recurse to update viewport
4035 // intersections for its children because their frame coordinates may not
4036 // be up to date.
4037 if (shouldThrottleRenderingIfAllowed() || !m_needsUpdateViewportIntersection InSubtree)
4038 return;
4039 m_needsUpdateViewportIntersectionInSubtree = false;
4040
4041 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
4042 if (!child->isLocalFrame())
4043 continue;
4044 if (FrameView* view = toLocalFrame(child)->view())
4045 view->updateViewportIntersectionsForSubtree();
4046 }
4047 }
4048
4049 void FrameView::notifyIntersectionObservers()
4050 {
4051 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers");
4052 ASSERT(!isInPerformLayout());
esprehn 2015/10/14 22:09:46 !inStyleRecalc() as well
Sami 2015/10/16 16:48:08 Done.
4053 bool wasThrottled = shouldThrottleRendering();
4054
4055 // Only offscreen frames can be throttled.
4056 m_viewportVisibilityForThrottling = (m_viewportIntersectionValid && m_viewpo rtIntersection.isEmpty()) ? ViewportVisibility::Hidden : ViewportVisibility::Vis ible;
4057
4058 // We only throttle the rendering pipeline in cross-origin frames. This is
4059 // to avoid a situation where an ancestor frame directly depends on the
4060 // pipeline timing of a descendant and breaks as a result of throttling.
4061 // The rationale is that cross-origin frames must already communicate with
4062 // asynchronous messages, so they should be able to tolerate some delay in
4063 // receiving replies from a throttled peer.
4064 //
4065 // Check if we can access our parent's security origin.
4066 m_securityOriginStatusForThrottling = SecurityOriginStatus::IsSameOrigin;
4067 Frame* parentFrame = m_frame->tree().parent();
4068 const SecurityOrigin* origin = frame().securityContext()->securityOrigin();
4069 while (parentFrame) {
esprehn 2015/10/14 22:09:46 for loop
Sami 2015/10/16 16:48:08 Done.
4070 const SecurityOrigin* parentOrigin = parentFrame->securityContext()->sec urityOrigin();
4071 if (!origin->canAccess(parentOrigin)) {
4072 m_securityOriginStatusForThrottling = SecurityOriginStatus::IsCrossO rigin;
4073 break;
4074 }
4075 parentFrame = parentFrame->tree().parent();
4076 }
4077
4078 bool becameUnthrottled = wasThrottled && !shouldThrottleRendering();
4079 if (becameUnthrottled)
4080 page()->animator().scheduleVisualUpdate(m_frame.get());
4081 }
4082
4083 bool FrameView::shouldThrottleRenderingIfAllowed() const
4084 {
4085 return shouldThrottleRendering() && lifecycle().throttlingMode() == Document Lifecycle::ThrottlingMode::Allow;
esprehn 2015/10/14 22:09:46 static getter
Sami 2015/10/16 16:48:08 Done.
4086 }
4087
4088 bool FrameView::shouldThrottleRendering() const
4089 {
4090 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
4091 return false;
4092 return m_viewportVisibilityForThrottling == ViewportVisibility::Hidden
esprehn 2015/10/14 22:09:46 m_isViewportVisibleForThrottling and make it a boo
Sami 2015/10/16 16:48:08 Done.
4093 && m_securityOriginStatusForThrottling == SecurityOriginStatus::IsCrossO rigin;
4094 }
4095
3947 } // namespace blink 4096 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698