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

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: Fix layout test by not dumping throttled FrameViews. 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_hiddenForThrottling(false)
151 , m_crossOriginForThrottling(false)
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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 278
272 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing 279 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
273 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|. 280 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
274 m_autoSizeInfo.clear(); 281 m_autoSizeInfo.clear();
275 282
276 if (m_postLayoutTasksTimer.isActive()) 283 if (m_postLayoutTasksTimer.isActive())
277 m_postLayoutTasksTimer.stop(); 284 m_postLayoutTasksTimer.stop();
278 285
279 if (m_didScrollTimer.isActive()) 286 if (m_didScrollTimer.isActive())
280 m_didScrollTimer.stop(); 287 m_didScrollTimer.stop();
288 m_intersectionObserverNotificationFactory->cancel();
281 289
282 // FIXME: Do we need to do something here for OOPI? 290 // FIXME: Do we need to do something here for OOPI?
283 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); 291 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
284 // TODO(dcheng): It seems buggy that we can have an owner element that 292 // TODO(dcheng): It seems buggy that we can have an owner element that
285 // points to another Widget. 293 // points to another Widget.
286 if (ownerElement && ownerElement->ownedWidget() == this) 294 if (ownerElement && ownerElement->ownedWidget() == this)
287 ownerElement->setWidget(nullptr); 295 ownerElement->setWidget(nullptr);
288 296
289 #if ENABLE(ASSERT) 297 #if ENABLE(ASSERT)
290 m_hasBeenDisposed = true; 298 m_hasBeenDisposed = true;
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 889
882 void FrameView::layout() 890 void FrameView::layout()
883 { 891 {
884 // We should never layout a Document which is not in a LocalFrame. 892 // We should never layout a Document which is not in a LocalFrame.
885 ASSERT(m_frame); 893 ASSERT(m_frame);
886 ASSERT(m_frame->view() == this); 894 ASSERT(m_frame->view() == this);
887 ASSERT(m_frame->page()); 895 ASSERT(m_frame->page());
888 896
889 ScriptForbiddenScope forbidScript; 897 ScriptForbiddenScope forbidScript;
890 898
891 if (isInPerformLayout() || !m_frame->document()->isActive()) 899 if (isInPerformLayout() || !m_frame->document()->isActive() || shouldThrottl eRendering())
892 return; 900 return;
893 901
894 TRACE_EVENT0("blink,benchmark", "FrameView::layout"); 902 TRACE_EVENT0("blink,benchmark", "FrameView::layout");
895 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout"); 903 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout");
896 904
897 // Protect the view from being deleted during layout (in recalcStyle) 905 // Protect the view from being deleted during layout (in recalcStyle)
898 RefPtrWillBeRawPtr<FrameView> protector(this); 906 RefPtrWillBeRawPtr<FrameView> protector(this);
899 907
900 if (m_autoSizeInfo) 908 if (m_autoSizeInfo)
901 m_autoSizeInfo->autoSizeIfNeeded(); 909 m_autoSizeInfo->autoSizeIfNeeded();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 1073
1066 frame().document()->layoutUpdated(); 1074 frame().document()->layoutUpdated();
1067 } 1075 }
1068 1076
1069 // The plan is to move to compositor-queried paint invalidation, in which case t his 1077 // The plan is to move to compositor-queried paint invalidation, in which case t his
1070 // method would setNeedsRedraw on the GraphicsLayers with invalidations and 1078 // method would setNeedsRedraw on the GraphicsLayers with invalidations and
1071 // let the compositor pick which to actually draw. 1079 // let the compositor pick which to actually draw.
1072 // See http://crbug.com/306706 1080 // See http://crbug.com/306706
1073 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State) 1081 void FrameView::invalidateTreeIfNeeded(PaintInvalidationState& paintInvalidation State)
1074 { 1082 {
1083 if (shouldThrottleRendering())
1084 return;
1085
1075 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation); 1086 lifecycle().advanceTo(DocumentLifecycle::InPaintInvalidation);
1076 1087
1077 ASSERT(layoutView()); 1088 ASSERT(layoutView());
1078 LayoutView& rootForPaintInvalidation = *layoutView(); 1089 LayoutView& rootForPaintInvalidation = *layoutView();
1079 ASSERT(!rootForPaintInvalidation.needsLayout()); 1090 ASSERT(!rootForPaintInvalidation.needsLayout());
1080 1091
1081 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii()); 1092 TRACE_EVENT1("blink", "FrameView::invalidateTree", "root", rootForPaintInval idation.debugName().ascii());
1082 1093
1083 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState); 1094 rootForPaintInvalidation.invalidateTreeIfNeeded(paintInvalidationState);
1084 1095
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 1286
1276 bool FrameView::shouldSetCursor() const 1287 bool FrameView::shouldSetCursor() const
1277 { 1288 {
1278 Page* page = frame().page(); 1289 Page* page = frame().page();
1279 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse(); 1290 return page && page->visibilityState() != PageVisibilityStateHidden && page- >focusController().isActive() && page->settings().deviceSupportsMouse();
1280 } 1291 }
1281 1292
1282 void FrameView::scrollContentsIfNeededRecursive() 1293 void FrameView::scrollContentsIfNeededRecursive()
1283 { 1294 {
1284 forAllFrameViews([](FrameView& frameView) { 1295 forAllFrameViews([](FrameView& frameView) {
1296 if (frameView.shouldThrottleRendering())
1297 return;
1285 frameView.scrollContentsIfNeeded(); 1298 frameView.scrollContentsIfNeeded();
1286 }); 1299 });
1287 } 1300 }
1288 1301
1289 bool FrameView::invalidateViewportConstrainedObjects() 1302 bool FrameView::invalidateViewportConstrainedObjects()
1290 { 1303 {
1291 for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) { 1304 for (const auto& viewportConstrainedObject : *m_viewportConstrainedObjects) {
1292 LayoutObject* layoutObject = viewportConstrainedObject; 1305 LayoutObject* layoutObject = viewportConstrainedObject;
1293 ASSERT(layoutObject->style()->hasViewportConstrainedPosition()); 1306 ASSERT(layoutObject->style()->hasViewportConstrainedPosition());
1294 ASSERT(layoutObject->hasLayer()); 1307 ASSERT(layoutObject->hasLayer());
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 if (!m_frame->document()->shouldScheduleLayout()) 1702 if (!m_frame->document()->shouldScheduleLayout())
1690 return; 1703 return;
1691 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get())); 1704 TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "Invali dateLayout", TRACE_EVENT_SCOPE_THREAD, "data", InspectorInvalidateLayoutEvent::d ata(m_frame.get()));
1692 1705
1693 clearLayoutSubtreeRootsAndMarkContainingBlocks(); 1706 clearLayoutSubtreeRootsAndMarkContainingBlocks();
1694 1707
1695 if (m_hasPendingLayout) 1708 if (m_hasPendingLayout)
1696 return; 1709 return;
1697 m_hasPendingLayout = true; 1710 m_hasPendingLayout = true;
1698 1711
1699 page()->animator().scheduleVisualUpdate(m_frame.get()); 1712 if (!shouldThrottleRendering())
1713 page()->animator().scheduleVisualUpdate(m_frame.get());
1700 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean); 1714 lifecycle().ensureStateAtMost(DocumentLifecycle::StyleClean);
1701 } 1715 }
1702 1716
1703 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot) 1717 void FrameView::scheduleRelayoutOfSubtree(LayoutObject* relayoutRoot)
1704 { 1718 {
1705 ASSERT(m_frame->view() == this); 1719 ASSERT(m_frame->view() == this);
1706 1720
1707 // FIXME: Should this call shouldScheduleLayout instead? 1721 // FIXME: Should this call shouldScheduleLayout instead?
1708 if (!m_frame->document()->isActive()) 1722 if (!m_frame->document()->isActive())
1709 return; 1723 return;
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, cons t LayoutRect* interestRect) 2415 void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases, cons t LayoutRect* interestRect)
2402 { 2416 {
2403 // This must be called from the root frame, since it recurses down, not up. 2417 // This must be called from the root frame, since it recurses down, not up.
2404 // Otherwise the lifecycles of the frames might be out of sync. 2418 // Otherwise the lifecycles of the frames might be out of sync.
2405 ASSERT(m_frame->isLocalRoot()); 2419 ASSERT(m_frame->isLocalRoot());
2406 2420
2407 // Updating layout can run script, which can tear down the FrameView. 2421 // Updating layout can run script, which can tear down the FrameView.
2408 RefPtrWillBeRawPtr<FrameView> protector(this); 2422 RefPtrWillBeRawPtr<FrameView> protector(this);
2409 2423
2410 updateStyleAndLayoutIfNeededRecursive(); 2424 updateStyleAndLayoutIfNeededRecursive();
2411 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2425 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean);
alogvinov 2015/10/21 13:02:44 Shouldn't this assert be removed or amended now th
Sami 2015/10/21 13:15:16 Right now I think this works since we never thrott
2412 2426
2413 if (phases == OnlyUpToLayoutClean) 2427 if (phases == OnlyUpToLayoutClean) {
2428 updateViewportIntersectionsForSubtree();
2414 return; 2429 return;
2430 }
2415 2431
2416 if (LayoutView* view = layoutView()) { 2432 if (LayoutView* view = layoutView()) {
2417 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get())); 2433 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp dateLayerTreeEvent::data(m_frame.get()));
2418 2434
2419 // This was required for slimming paint v1 but is only temporarily 2435 // This was required for slimming paint v1 but is only temporarily
2420 // needed for slimming paint v2. 2436 // needed for slimming paint v2.
2421 view->compositor()->updateIfNeededRecursive(); 2437 view->compositor()->updateIfNeededRecursive();
2422 scrollContentsIfNeededRecursive(); 2438 scrollContentsIfNeededRecursive();
2423 2439
2424 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); 2440 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean);
(...skipping 17 matching lines...) Expand all
2442 2458
2443 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) 2459 if (RuntimeEnabledFeatures::frameTimingSupportEnabled())
2444 updateFrameTimingRequestsIfNeeded(); 2460 updateFrameTimingRequestsIfNeeded();
2445 2461
2446 ASSERT(!view->hasPendingSelection()); 2462 ASSERT(!view->hasPendingSelection());
2447 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean 2463 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl ean
2448 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) 2464 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean)
2449 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); 2465 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna bled() && lifecycle().state() == DocumentLifecycle::PaintClean));
2450 } 2466 }
2451 } 2467 }
2468
2469 updateViewportIntersectionsForSubtree();
2452 } 2470 }
2453 2471
2454 void FrameView::updatePaintProperties() 2472 void FrameView::updatePaintProperties()
2455 { 2473 {
2456 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 2474 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2457 2475
2458 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo( DocumentLifecycle::InUpdatePaintProperties); }); 2476 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo( DocumentLifecycle::InUpdatePaintProperties); });
2459 // TODO(pdr): Calculate the paint properties by walking the layout tree. 2477 // TODO(pdr): Calculate the paint properties by walking the layout tree.
2460 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo( DocumentLifecycle::UpdatePaintPropertiesClean); }); 2478 forAllFrameViews([](FrameView& frameView) { frameView.lifecycle().advanceTo( DocumentLifecycle::UpdatePaintPropertiesClean); });
2461 } 2479 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2527 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); 2545 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests);
2528 2546
2529 for (const auto& iter : graphicsLayerTimingRequests) { 2547 for (const auto& iter : graphicsLayerTimingRequests) {
2530 const GraphicsLayer* graphicsLayer = iter.key; 2548 const GraphicsLayer* graphicsLayer = iter.key;
2531 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value); 2549 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value);
2532 } 2550 }
2533 } 2551 }
2534 2552
2535 void FrameView::updateStyleAndLayoutIfNeededRecursive() 2553 void FrameView::updateStyleAndLayoutIfNeededRecursive()
2536 { 2554 {
2555 if (shouldThrottleRendering())
2556 return;
2557
2537 // We have to crawl our entire subtree looking for any FrameViews that need 2558 // We have to crawl our entire subtree looking for any FrameViews that need
2538 // layout and make sure they are up to date. 2559 // layout and make sure they are up to date.
2539 // Mac actually tests for intersection with the dirty region and tries not t o 2560 // Mac actually tests for intersection with the dirty region and tries not t o
2540 // update layout for frames that are outside the dirty region. Not only doe s this seem 2561 // update layout for frames that are outside the dirty region. Not only doe s this seem
2541 // pointless (since those frames will have set a zero timer to layout anyway ), but 2562 // pointless (since those frames will have set a zero timer to layout anyway ), but
2542 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2563 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
2543 // region but then become included later by the second frame adding rects to the dirty region 2564 // region but then become included later by the second frame adding rects to the dirty region
2544 // when it lays out. 2565 // when it lays out.
2545 2566
2546 m_frame->document()->updateLayoutTreeIfNeeded(); 2567 m_frame->document()->updateLayoutTreeIfNeeded();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2581 2602
2582 updateWidgetPositionsIfNeeded(); 2603 updateWidgetPositionsIfNeeded();
2583 2604
2584 if (lifecycle().state() < DocumentLifecycle::LayoutClean) 2605 if (lifecycle().state() < DocumentLifecycle::LayoutClean)
2585 lifecycle().advanceTo(DocumentLifecycle::LayoutClean); 2606 lifecycle().advanceTo(DocumentLifecycle::LayoutClean);
2586 } 2607 }
2587 2608
2588 void FrameView::invalidateTreeIfNeededRecursive() 2609 void FrameView::invalidateTreeIfNeededRecursive()
2589 { 2610 {
2590 ASSERT(layoutView()); 2611 ASSERT(layoutView());
2612
2613 // We need to stop recursing here since a child frame view might not be thro ttled
2614 // even though we are (e.g., it didn't compute its visibility yet).
2615 if (shouldThrottleRendering())
2616 return;
2591 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii()); 2617 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root", layoutView()->debugName().ascii());
2592 2618
2593 Vector<LayoutObject*> pendingDelayedPaintInvalidations; 2619 Vector<LayoutObject*> pendingDelayedPaintInvalidations;
2594 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations); 2620 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela yedPaintInvalidations);
2595 2621
2596 invalidateTreeIfNeeded(rootPaintInvalidationState); 2622 invalidateTreeIfNeeded(rootPaintInvalidationState);
2597 2623
2598 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause 2624 // Some frames may be not reached during the above invalidateTreeIfNeeded be cause
2599 // - the frame is a detached frame; or 2625 // - the frame is a detached frame; or
2600 // - it didn't need paint invalidation. 2626 // - it didn't need paint invalidation.
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 2925
2900 if (m_scrollbarsAvoidingResizer && parent()) 2926 if (m_scrollbarsAvoidingResizer && parent())
2901 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer); 2927 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar sAvoidingResizer);
2902 2928
2903 Widget::setParent(parentView); 2929 Widget::setParent(parentView);
2904 2930
2905 if (m_scrollbarsAvoidingResizer && parent()) 2931 if (m_scrollbarsAvoidingResizer && parent())
2906 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer); 2932 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars AvoidingResizer);
2907 2933
2908 updateScrollableAreaSet(); 2934 updateScrollableAreaSet();
2935 setNeedsUpdateViewportIntersection();
2909 } 2936 }
2910 2937
2911 void FrameView::removeChild(Widget* child) 2938 void FrameView::removeChild(Widget* child)
2912 { 2939 {
2913 ASSERT(child->parent() == this); 2940 ASSERT(child->parent() == this);
2914 2941
2915 if (child->isFrameView()) 2942 if (child->isFrameView())
2916 removeScrollableArea(toFrameView(child)); 2943 removeScrollableArea(toFrameView(child));
2917 2944
2918 child->setParent(0); 2945 child->setParent(0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2956 return; 2983 return;
2957 page->chromeClient().setCursor(cursor, m_frame->localFrameRoot()); 2984 page->chromeClient().setCursor(cursor, m_frame->localFrameRoot());
2958 } 2985 }
2959 2986
2960 void FrameView::frameRectsChanged() 2987 void FrameView::frameRectsChanged()
2961 { 2988 {
2962 TRACE_EVENT0("blink", "FrameView::frameRectsChanged"); 2989 TRACE_EVENT0("blink", "FrameView::frameRectsChanged");
2963 if (layoutSizeFixedToFrameSize()) 2990 if (layoutSizeFixedToFrameSize())
2964 setLayoutSizeInternal(frameRect().size()); 2991 setLayoutSizeInternal(frameRect().size());
2965 2992
2993 setNeedsUpdateViewportIntersection();
2966 for (const auto& child : m_children) 2994 for (const auto& child : m_children)
2967 child->frameRectsChanged(); 2995 child->frameRectsChanged();
2968 } 2996 }
2969 2997
2970 void FrameView::setLayoutSizeInternal(const IntSize& size) 2998 void FrameView::setLayoutSizeInternal(const IntSize& size)
2971 { 2999 {
2972 if (m_layoutSize == size) 3000 if (m_layoutSize == size)
2973 return; 3001 return;
2974 3002
2975 m_layoutSize = size; 3003 m_layoutSize = size;
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after
3732 return ScrollBehaviorInstant; 3760 return ScrollBehaviorInstant;
3733 } 3761 }
3734 3762
3735 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const 3763 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const
3736 { 3764 {
3737 paint(context, GlobalPaintNormalPhase, rect); 3765 paint(context, GlobalPaintNormalPhase, rect);
3738 } 3766 }
3739 3767
3740 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const 3768 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai ntFlags, const IntRect& rect) const
3741 { 3769 {
3770 // TODO(skyostil): Remove this early-out in favor of painting cached scrollb ars.
3771 if (shouldThrottleRendering())
3772 return;
3742 FramePainter(*this).paint(context, globalPaintFlags, rect); 3773 FramePainter(*this).paint(context, globalPaintFlags, rect);
3743 } 3774 }
3744 3775
3745 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const 3776 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g lobalPaintFlags, const IntRect& damageRect) const
3746 { 3777 {
3778 if (shouldThrottleRendering())
3779 return;
3747 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect); 3780 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect);
3748 } 3781 }
3749 3782
3750 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint) 3783 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint)
3751 { 3784 {
3752 if (!scrollbarCornerPresent()) 3785 if (!scrollbarCornerPresent())
3753 return false; 3786 return false;
3754 3787
3755 IntPoint framePoint = convertFromContainingWindow(windowPoint); 3788 IntPoint framePoint = convertFromContainingWindow(windowPoint);
3756 3789
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 } 3957 }
3925 3958
3926 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests) 3959 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra phicsLayerTimingRequests)
3927 { 3960 {
3928 if (!m_frame->isLocalFrame()) 3961 if (!m_frame->isLocalFrame())
3929 return; 3962 return;
3930 Frame* frame = m_frame.get(); 3963 Frame* frame = m_frame.get();
3931 LocalFrame* localFrame = toLocalFrame(frame); 3964 LocalFrame* localFrame = toLocalFrame(frame);
3932 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect(); 3965 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect();
3933 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation(); 3966 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content LayoutObject()->containerForPaintInvalidation();
3967 // If the frame is being throttled, its compositing state may not be up to d ate.
3968 if (!paintInvalidationContainer->enclosingLayer()->isAllowedToQueryCompositi ngState())
3969 return;
3934 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking(); 3970 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa yer()->graphicsLayerBacking();
3935 3971
3936 if (!graphicsLayer) 3972 if (!graphicsLayer)
3937 return; 3973 return;
3938 3974
3939 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect); 3975 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec t(), paintInvalidationContainer, viewRect);
3940 3976
3941 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect))); 3977 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing IntRect(viewRect)));
3942 } 3978 }
3943 3979
3980 void FrameView::setNeedsUpdateViewportIntersection()
3981 {
3982 m_needsUpdateViewportIntersection = true;
3983 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF rameView())
3984 parent->m_needsUpdateViewportIntersectionInSubtree = true;
3985 }
3986
3987 void FrameView::updateViewportIntersectionIfNeeded()
3988 {
3989 // TODO(skyostil): Replace this with a real intersection observer.
3990 if (!m_needsUpdateViewportIntersection)
3991 return;
3992 m_needsUpdateViewportIntersection = false;
3993 m_viewportIntersectionValid = true;
3994
3995 FrameView* parent = parentFrameView();
3996 if (!parent) {
3997 m_viewportIntersection = frameRect();
3998 return;
3999 }
4000 ASSERT(!parent->m_needsUpdateViewportIntersection);
4001
4002 // If our parent is hidden, then we are too.
4003 if (parent->m_viewportIntersection.isEmpty()) {
4004 m_viewportIntersection = parent->m_viewportIntersection;
4005 return;
4006 }
4007
4008 // Transform our bounds into the root frame's content coordinate space,
4009 // making sure we have valid layout data in our parent document. If our
4010 // parent is throttled, we'll use possible stale layout information and
4011 // rely on the fact that another lifecycle update will be scheduled once
4012 // our parent becomes unthrottled.
4013 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutClean || pare nt->shouldThrottleRendering());
4014 m_viewportIntersection = parent->contentsToRootFrame(frameRect());
4015
4016 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling.
4017 IntRect viewport = parent->m_viewportIntersection;
4018 m_viewportIntersection.intersect(viewport);
4019 }
4020
4021 void FrameView::updateViewportIntersectionsForSubtree()
4022 {
4023 bool hadValidIntersection = m_viewportIntersectionValid;
4024 bool hadEmptyIntersection = m_viewportIntersection.isEmpty();
4025 updateViewportIntersectionIfNeeded();
4026 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty();
4027 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending())
4028 m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_intersectionObserverNotificationFactory->cancelAndCreate());
4029
4030 if (!m_needsUpdateViewportIntersectionInSubtree)
4031 return;
4032 m_needsUpdateViewportIntersectionInSubtree = false;
4033
4034 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
4035 if (!child->isLocalFrame())
4036 continue;
4037 if (FrameView* view = toLocalFrame(child)->view())
4038 view->updateViewportIntersectionsForSubtree();
4039 }
4040 }
4041
4042 void FrameView::notifyIntersectionObservers()
4043 {
4044 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers");
4045 ASSERT(!isInPerformLayout());
4046 ASSERT(!m_frame->document()->inStyleRecalc());
4047 bool wasThrottled = canThrottleRendering();
4048
4049 // Only offscreen frames can be throttled.
4050 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio n.isEmpty();
4051
4052 // We only throttle the rendering pipeline in cross-origin frames. This is
4053 // to avoid a situation where an ancestor frame directly depends on the
4054 // pipeline timing of a descendant and breaks as a result of throttling.
4055 // The rationale is that cross-origin frames must already communicate with
4056 // asynchronous messages, so they should be able to tolerate some delay in
4057 // receiving replies from a throttled peer.
4058 //
4059 // Check if we can access our parent's security origin.
4060 m_crossOriginForThrottling = false;
4061 const SecurityOrigin* origin = frame().securityContext()->securityOrigin();
4062 for (Frame* parentFrame = m_frame->tree().parent(); parentFrame; parentFrame = parentFrame->tree().parent()) {
4063 const SecurityOrigin* parentOrigin = parentFrame->securityContext()->sec urityOrigin();
4064 if (!origin->canAccess(parentOrigin)) {
4065 m_crossOriginForThrottling = true;
4066 break;
4067 }
4068 }
4069
4070 bool becameUnthrottled = wasThrottled && !canThrottleRendering();
4071 if (becameUnthrottled)
4072 page()->animator().scheduleVisualUpdate(m_frame.get());
4073 }
4074
4075 bool FrameView::shouldThrottleRendering() const
4076 {
4077 return canThrottleRendering() && lifecycle().throttlingAllowed();
4078 }
4079
4080 bool FrameView::canThrottleRendering() const
4081 {
4082 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled())
4083 return false;
4084 return m_hiddenForThrottling && m_crossOriginForThrottling;
4085 }
4086
3944 } // namespace blink 4087 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameView.h ('k') | third_party/WebKit/Source/core/frame/LocalFrame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698