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/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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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
eRendering()) |
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 Loading... |
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()) |
| 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 Loading... |
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 (shouldThrottleRendering()) |
| 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 Loading... |
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()) |
| 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 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 |
2408 updateStyleAndLayoutIfNeededRecursive(); | 2422 updateStyleAndLayoutIfNeededRecursive(); |
2409 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); | 2423 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); |
2410 | 2424 |
2411 if (phases == OnlyUpToLayoutClean) | 2425 if (phases == OnlyUpToLayoutClean) { |
| 2426 updateViewportIntersectionsForSubtree(); |
2412 return; | 2427 return; |
| 2428 } |
2413 | 2429 |
2414 if (LayoutView* view = layoutView()) { | 2430 if (LayoutView* view = layoutView()) { |
2415 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp
dateLayerTreeEvent::data(m_frame.get())); | 2431 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", InspectorUp
dateLayerTreeEvent::data(m_frame.get())); |
2416 | 2432 |
2417 // This was required for slimming paint v1 but is only temporarily | 2433 // This was required for slimming paint v1 but is only temporarily |
2418 // needed for slimming paint v2. | 2434 // needed for slimming paint v2. |
2419 view->compositor()->updateIfNeededRecursive(); | 2435 view->compositor()->updateIfNeededRecursive(); |
2420 scrollContentsIfNeededRecursive(); | 2436 scrollContentsIfNeededRecursive(); |
2421 | 2437 |
2422 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); | 2438 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); |
(...skipping 17 matching lines...) Expand all Loading... |
2440 | 2456 |
2441 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) | 2457 if (RuntimeEnabledFeatures::frameTimingSupportEnabled()) |
2442 updateFrameTimingRequestsIfNeeded(); | 2458 updateFrameTimingRequestsIfNeeded(); |
2443 | 2459 |
2444 ASSERT(!view->hasPendingSelection()); | 2460 ASSERT(!view->hasPendingSelection()); |
2445 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl
ean | 2461 ASSERT(lifecycle().state() == DocumentLifecycle::PaintInvalidationCl
ean |
2446 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl
e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) | 2462 || (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && lifecycl
e().state() == DocumentLifecycle::CompositingForSlimmingPaintV2Clean) |
2447 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna
bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); | 2463 || (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEna
bled() && lifecycle().state() == DocumentLifecycle::PaintClean)); |
2448 } | 2464 } |
2449 } | 2465 } |
| 2466 |
| 2467 updateViewportIntersectionsForSubtree(); |
2450 } | 2468 } |
2451 | 2469 |
2452 void FrameView::updatePaintProperties() | 2470 void FrameView::updatePaintProperties() |
2453 { | 2471 { |
2454 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | 2472 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); |
2455 | 2473 |
2456 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); | 2474 lifecycle().advanceTo(DocumentLifecycle::InUpdatePaintProperties); |
2457 // TODO(pdr): Calculate the paint properties by walking the layout tree. | 2475 // TODO(pdr): Calculate the paint properties by walking the layout tree. |
2458 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); | 2476 lifecycle().advanceTo(DocumentLifecycle::UpdatePaintPropertiesClean); |
2459 } | 2477 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2530 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); | 2548 collectFrameTimingRequestsRecursive(graphicsLayerTimingRequests); |
2531 | 2549 |
2532 for (const auto& iter : graphicsLayerTimingRequests) { | 2550 for (const auto& iter : graphicsLayerTimingRequests) { |
2533 const GraphicsLayer* graphicsLayer = iter.key; | 2551 const GraphicsLayer* graphicsLayer = iter.key; |
2534 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value); | 2552 graphicsLayer->platformLayer()->setFrameTimingRequests(iter.value); |
2535 } | 2553 } |
2536 } | 2554 } |
2537 | 2555 |
2538 void FrameView::updateStyleAndLayoutIfNeededRecursive() | 2556 void FrameView::updateStyleAndLayoutIfNeededRecursive() |
2539 { | 2557 { |
| 2558 if (shouldThrottleRendering()) |
| 2559 return; |
| 2560 |
2540 // We have to crawl our entire subtree looking for any FrameViews that need | 2561 // We have to crawl our entire subtree looking for any FrameViews that need |
2541 // layout and make sure they are up to date. | 2562 // layout and make sure they are up to date. |
2542 // Mac actually tests for intersection with the dirty region and tries not t
o | 2563 // 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 | 2564 // 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 | 2565 // 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 | 2566 // 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 | 2567 // region but then become included later by the second frame adding rects to
the dirty region |
2547 // when it lays out. | 2568 // when it lays out. |
2548 | 2569 |
2549 m_frame->document()->updateLayoutTreeIfNeeded(); | 2570 m_frame->document()->updateLayoutTreeIfNeeded(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 | 2605 |
2585 updateWidgetPositionsIfNeeded(); | 2606 updateWidgetPositionsIfNeeded(); |
2586 | 2607 |
2587 if (lifecycle().state() < DocumentLifecycle::LayoutClean) | 2608 if (lifecycle().state() < DocumentLifecycle::LayoutClean) |
2588 lifecycle().advanceTo(DocumentLifecycle::LayoutClean); | 2609 lifecycle().advanceTo(DocumentLifecycle::LayoutClean); |
2589 } | 2610 } |
2590 | 2611 |
2591 void FrameView::invalidateTreeIfNeededRecursive() | 2612 void FrameView::invalidateTreeIfNeededRecursive() |
2592 { | 2613 { |
2593 ASSERT(layoutView()); | 2614 ASSERT(layoutView()); |
| 2615 |
| 2616 // We need to stop recursing here since a child frame view might not be thro
ttled |
| 2617 // even though we are (e.g., it didn't compute its visibility yet). |
| 2618 if (shouldThrottleRendering()) |
| 2619 return; |
2594 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root",
layoutView()->debugName().ascii()); | 2620 TRACE_EVENT1("blink", "FrameView::invalidateTreeIfNeededRecursive", "root",
layoutView()->debugName().ascii()); |
2595 | 2621 |
2596 Vector<LayoutObject*> pendingDelayedPaintInvalidations; | 2622 Vector<LayoutObject*> pendingDelayedPaintInvalidations; |
2597 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela
yedPaintInvalidations); | 2623 PaintInvalidationState rootPaintInvalidationState(*layoutView(), pendingDela
yedPaintInvalidations); |
2598 | 2624 |
2599 invalidateTreeIfNeeded(rootPaintInvalidationState); | 2625 invalidateTreeIfNeeded(rootPaintInvalidationState); |
2600 | 2626 |
2601 // Some frames may be not reached during the above invalidateTreeIfNeeded be
cause | 2627 // Some frames may be not reached during the above invalidateTreeIfNeeded be
cause |
2602 // - the frame is a detached frame; or | 2628 // - the frame is a detached frame; or |
2603 // - it didn't need paint invalidation. | 2629 // - it didn't need paint invalidation. |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2902 | 2928 |
2903 if (m_scrollbarsAvoidingResizer && parent()) | 2929 if (m_scrollbarsAvoidingResizer && parent()) |
2904 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar
sAvoidingResizer); | 2930 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(-m_scrollbar
sAvoidingResizer); |
2905 | 2931 |
2906 Widget::setParent(parentView); | 2932 Widget::setParent(parentView); |
2907 | 2933 |
2908 if (m_scrollbarsAvoidingResizer && parent()) | 2934 if (m_scrollbarsAvoidingResizer && parent()) |
2909 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars
AvoidingResizer); | 2935 toFrameView(parent())->adjustScrollbarsAvoidingResizerCount(m_scrollbars
AvoidingResizer); |
2910 | 2936 |
2911 updateScrollableAreaSet(); | 2937 updateScrollableAreaSet(); |
| 2938 setNeedsUpdateViewportIntersection(); |
2912 } | 2939 } |
2913 | 2940 |
2914 void FrameView::removeChild(Widget* child) | 2941 void FrameView::removeChild(Widget* child) |
2915 { | 2942 { |
2916 ASSERT(child->parent() == this); | 2943 ASSERT(child->parent() == this); |
2917 | 2944 |
2918 if (child->isFrameView()) | 2945 if (child->isFrameView()) |
2919 removeScrollableArea(toFrameView(child)); | 2946 removeScrollableArea(toFrameView(child)); |
2920 | 2947 |
2921 child->setParent(0); | 2948 child->setParent(0); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2959 return; | 2986 return; |
2960 page->chromeClient().setCursor(cursor); | 2987 page->chromeClient().setCursor(cursor); |
2961 } | 2988 } |
2962 | 2989 |
2963 void FrameView::frameRectsChanged() | 2990 void FrameView::frameRectsChanged() |
2964 { | 2991 { |
2965 TRACE_EVENT0("blink", "FrameView::frameRectsChanged"); | 2992 TRACE_EVENT0("blink", "FrameView::frameRectsChanged"); |
2966 if (layoutSizeFixedToFrameSize()) | 2993 if (layoutSizeFixedToFrameSize()) |
2967 setLayoutSizeInternal(frameRect().size()); | 2994 setLayoutSizeInternal(frameRect().size()); |
2968 | 2995 |
| 2996 setNeedsUpdateViewportIntersection(); |
2969 for (const auto& child : m_children) | 2997 for (const auto& child : m_children) |
2970 child->frameRectsChanged(); | 2998 child->frameRectsChanged(); |
2971 } | 2999 } |
2972 | 3000 |
2973 void FrameView::setLayoutSizeInternal(const IntSize& size) | 3001 void FrameView::setLayoutSizeInternal(const IntSize& size) |
2974 { | 3002 { |
2975 if (m_layoutSize == size) | 3003 if (m_layoutSize == size) |
2976 return; | 3004 return; |
2977 | 3005 |
2978 m_layoutSize = size; | 3006 m_layoutSize = size; |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3735 return ScrollBehaviorInstant; | 3763 return ScrollBehaviorInstant; |
3736 } | 3764 } |
3737 | 3765 |
3738 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const | 3766 void FrameView::paint(GraphicsContext* context, const IntRect& rect) const |
3739 { | 3767 { |
3740 paint(context, GlobalPaintNormalPhase, rect); | 3768 paint(context, GlobalPaintNormalPhase, rect); |
3741 } | 3769 } |
3742 | 3770 |
3743 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai
ntFlags, const IntRect& rect) const | 3771 void FrameView::paint(GraphicsContext* context, const GlobalPaintFlags globalPai
ntFlags, const IntRect& rect) const |
3744 { | 3772 { |
| 3773 // TODO(skyostil): Remove this early-out in favor of painting cached scrollb
ars. |
| 3774 if (shouldThrottleRendering()) |
| 3775 return; |
3745 FramePainter(*this).paint(context, globalPaintFlags, rect); | 3776 FramePainter(*this).paint(context, globalPaintFlags, rect); |
3746 } | 3777 } |
3747 | 3778 |
3748 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g
lobalPaintFlags, const IntRect& damageRect) const | 3779 void FrameView::paintContents(GraphicsContext* context, const GlobalPaintFlags g
lobalPaintFlags, const IntRect& damageRect) const |
3749 { | 3780 { |
| 3781 if (shouldThrottleRendering()) |
| 3782 return; |
3750 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect); | 3783 FramePainter(*this).paintContents(context, globalPaintFlags, damageRect); |
3751 } | 3784 } |
3752 | 3785 |
3753 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint) | 3786 bool FrameView::isPointInScrollbarCorner(const IntPoint& windowPoint) |
3754 { | 3787 { |
3755 if (!scrollbarCornerPresent()) | 3788 if (!scrollbarCornerPresent()) |
3756 return false; | 3789 return false; |
3757 | 3790 |
3758 IntPoint framePoint = convertFromContainingWindow(windowPoint); | 3791 IntPoint framePoint = convertFromContainingWindow(windowPoint); |
3759 | 3792 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3927 } | 3960 } |
3928 | 3961 |
3929 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra
phicsLayerTimingRequests) | 3962 void FrameView::collectFrameTimingRequests(GraphicsLayerFrameTimingRequests& gra
phicsLayerTimingRequests) |
3930 { | 3963 { |
3931 if (!m_frame->isLocalFrame()) | 3964 if (!m_frame->isLocalFrame()) |
3932 return; | 3965 return; |
3933 Frame* frame = m_frame.get(); | 3966 Frame* frame = m_frame.get(); |
3934 LocalFrame* localFrame = toLocalFrame(frame); | 3967 LocalFrame* localFrame = toLocalFrame(frame); |
3935 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect(); | 3968 LayoutRect viewRect = localFrame->contentLayoutObject()->viewRect(); |
3936 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content
LayoutObject()->containerForPaintInvalidation(); | 3969 const LayoutBoxModelObject* paintInvalidationContainer = localFrame->content
LayoutObject()->containerForPaintInvalidation(); |
| 3970 // If the frame is being throttled, its compositing state may not be up to d
ate. |
| 3971 if (!paintInvalidationContainer->enclosingLayer()->isAllowedToQueryCompositi
ngState()) |
| 3972 return; |
3937 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa
yer()->graphicsLayerBacking(); | 3973 const GraphicsLayer* graphicsLayer = paintInvalidationContainer->enclosingLa
yer()->graphicsLayerBacking(); |
3938 | 3974 |
3939 if (!graphicsLayer) | 3975 if (!graphicsLayer) |
3940 return; | 3976 return; |
3941 | 3977 |
3942 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec
t(), paintInvalidationContainer, viewRect); | 3978 PaintLayer::mapRectToPaintInvalidationBacking(localFrame->contentLayoutObjec
t(), paintInvalidationContainer, viewRect); |
3943 | 3979 |
3944 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web
Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing
IntRect(viewRect))); | 3980 graphicsLayerTimingRequests.add(graphicsLayer, Vector<std::pair<int64_t, Web
Rect>>()).storedValue->value.append(std::make_pair(m_frame->frameID(), enclosing
IntRect(viewRect))); |
3945 } | 3981 } |
3946 | 3982 |
| 3983 void FrameView::setNeedsUpdateViewportIntersection() |
| 3984 { |
| 3985 m_needsUpdateViewportIntersection = true; |
| 3986 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF
rameView()) |
| 3987 parent->m_needsUpdateViewportIntersectionInSubtree = true; |
| 3988 } |
| 3989 |
| 3990 void FrameView::updateViewportIntersectionIfNeeded() |
| 3991 { |
| 3992 // TODO(skyostil): Replace this with a real intersection observer. |
| 3993 if (!m_needsUpdateViewportIntersection) |
| 3994 return; |
| 3995 m_needsUpdateViewportIntersection = false; |
| 3996 m_viewportIntersectionValid = true; |
| 3997 |
| 3998 FrameView* parent = parentFrameView(); |
| 3999 if (!parent) { |
| 4000 m_viewportIntersection = frameRect(); |
| 4001 return; |
| 4002 } |
| 4003 ASSERT(!parent->m_needsUpdateViewportIntersection); |
| 4004 |
| 4005 // If our parent is hidden, then we are too. |
| 4006 if (parent->m_viewportIntersection.isEmpty()) { |
| 4007 m_viewportIntersection = parent->m_viewportIntersection; |
| 4008 return; |
| 4009 } |
| 4010 |
| 4011 // Transform our bounds into the root frame's content coordinate space, |
| 4012 // making sure we have valid layout data in our parent document. If our |
| 4013 // parent is throttled, we'll use possible stale layout information and |
| 4014 // rely on the fact that another lifecycle update will be scheduled once |
| 4015 // our parent becomes unthrottled. |
| 4016 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutClean || pare
nt->shouldThrottleRendering()); |
| 4017 m_viewportIntersection = parent->contentsToRootFrame(frameRect()); |
| 4018 |
| 4019 // TODO(skyostil): Expand the viewport to make it less likely to see stale c
ontent while scrolling. |
| 4020 IntRect viewport = parent->m_viewportIntersection; |
| 4021 m_viewportIntersection.intersect(viewport); |
| 4022 } |
| 4023 |
| 4024 void FrameView::updateViewportIntersectionsForSubtree() |
| 4025 { |
| 4026 bool hadValidIntersection = m_viewportIntersectionValid; |
| 4027 bool hadEmptyIntersection = m_viewportIntersection.isEmpty(); |
| 4028 updateViewportIntersectionIfNeeded(); |
| 4029 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp
ortIntersection.isEmpty(); |
| 4030 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending()) |
| 4031 m_frame->frameScheduler()->timerTaskRunner()->postTask(FROM_HERE, m_inte
rsectionObserverNotificationFactory->cancelAndCreate()); |
| 4032 |
| 4033 if (!m_needsUpdateViewportIntersectionInSubtree) |
| 4034 return; |
| 4035 m_needsUpdateViewportIntersectionInSubtree = false; |
| 4036 |
| 4037 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree
().nextSibling()) { |
| 4038 if (!child->isLocalFrame()) |
| 4039 continue; |
| 4040 if (FrameView* view = toLocalFrame(child)->view()) |
| 4041 view->updateViewportIntersectionsForSubtree(); |
| 4042 } |
| 4043 } |
| 4044 |
| 4045 void FrameView::notifyIntersectionObservers() |
| 4046 { |
| 4047 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers"); |
| 4048 ASSERT(!isInPerformLayout()); |
| 4049 ASSERT(!m_frame->document()->inStyleRecalc()); |
| 4050 bool wasThrottled = canThrottleRendering(); |
| 4051 |
| 4052 // Only offscreen frames can be throttled. |
| 4053 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio
n.isEmpty(); |
| 4054 |
| 4055 // We only throttle the rendering pipeline in cross-origin frames. This is |
| 4056 // to avoid a situation where an ancestor frame directly depends on the |
| 4057 // pipeline timing of a descendant and breaks as a result of throttling. |
| 4058 // The rationale is that cross-origin frames must already communicate with |
| 4059 // asynchronous messages, so they should be able to tolerate some delay in |
| 4060 // receiving replies from a throttled peer. |
| 4061 // |
| 4062 // Check if we can access our parent's security origin. |
| 4063 m_crossOriginForThrottling = false; |
| 4064 const SecurityOrigin* origin = frame().securityContext()->securityOrigin(); |
| 4065 for (Frame* parentFrame = m_frame->tree().parent(); parentFrame; parentFrame
= parentFrame->tree().parent()) { |
| 4066 const SecurityOrigin* parentOrigin = parentFrame->securityContext()->sec
urityOrigin(); |
| 4067 if (!origin->canAccess(parentOrigin)) { |
| 4068 m_crossOriginForThrottling = true; |
| 4069 break; |
| 4070 } |
| 4071 } |
| 4072 |
| 4073 bool becameUnthrottled = wasThrottled && !canThrottleRendering(); |
| 4074 if (becameUnthrottled) |
| 4075 page()->animator().scheduleVisualUpdate(m_frame.get()); |
| 4076 } |
| 4077 |
| 4078 bool FrameView::shouldThrottleRendering() const |
| 4079 { |
| 4080 return canThrottleRendering() && lifecycle().throttlingAllowed(); |
| 4081 } |
| 4082 |
| 4083 bool FrameView::canThrottleRendering() const |
| 4084 { |
| 4085 if (!RuntimeEnabledFeatures::renderingPipelineThrottlingEnabled()) |
| 4086 return false; |
| 4087 return m_hiddenForThrottling && m_crossOriginForThrottling; |
| 4088 } |
| 4089 |
3947 } // namespace blink | 4090 } // namespace blink |
OLD | NEW |