OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |