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 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |