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

Side by Side Diff: third_party/WebKit/Source/core/frame/FrameView.cpp

Issue 2120773002: Simplify and solidify FrameView dirty layout check (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: FrameView dirty layout check Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameView.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 , m_inUpdateScrollbars(false) 158 , m_inUpdateScrollbars(false)
159 , m_frameTimingRequestsDirty(true) 159 , m_frameTimingRequestsDirty(true)
160 , m_viewportIntersectionValid(false) 160 , m_viewportIntersectionValid(false)
161 , m_hiddenForThrottling(false) 161 , m_hiddenForThrottling(false)
162 , m_crossOriginForThrottling(false) 162 , m_crossOriginForThrottling(false)
163 , m_subtreeThrottled(false) 163 , m_subtreeThrottled(false)
164 , m_currentUpdateLifecyclePhasesTargetState(DocumentLifecycle::Uninitialized ) 164 , m_currentUpdateLifecyclePhasesTargetState(DocumentLifecycle::Uninitialized )
165 , m_scrollAnchor(this) 165 , m_scrollAnchor(this)
166 , m_needsScrollbarsUpdate(false) 166 , m_needsScrollbarsUpdate(false)
167 , m_suppressAdjustViewSize(false) 167 , m_suppressAdjustViewSize(false)
168 , m_inPluginUpdate(false) 168 , m_allowsLayoutInvalidationAfterLayoutClean(true)
169 , m_inForcedLayoutByChildEmbeddedReplacedContent(false)
170 , m_allowsLayoutInvalidationAfterLayoutClean(false)
171 { 169 {
172 ASSERT(m_frame); 170 ASSERT(m_frame);
173 init(); 171 init();
174 } 172 }
175 173
176 FrameView* FrameView::create(LocalFrame* frame) 174 FrameView* FrameView::create(LocalFrame* frame)
177 { 175 {
178 FrameView* view = new FrameView(frame); 176 FrameView* view = new FrameView(frame);
179 view->show(); 177 view->show();
180 return view; 178 return view;
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 return; 763 return;
766 764
767 // If the embedded SVG document appears the first time, the ownerLayoutObjec t has already finished 765 // If the embedded SVG document appears the first time, the ownerLayoutObjec t has already finished
768 // layout without knowing about the existence of the embedded SVG document, because LayoutReplaced 766 // layout without knowing about the existence of the embedded SVG document, because LayoutReplaced
769 // embeddedReplacedContent() returns 0, as long as the embedded document isn 't loaded yet. Before 767 // embeddedReplacedContent() returns 0, as long as the embedded document isn 't loaded yet. Before
770 // bothering to lay out the SVG document, mark the ownerLayoutObject needing layout and ask its 768 // bothering to lay out the SVG document, mark the ownerLayoutObject needing layout and ask its
771 // FrameView for a layout. After that the LayoutEmbeddedObject (ownerLayoutO bject) carries the 769 // FrameView for a layout. After that the LayoutEmbeddedObject (ownerLayoutO bject) carries the
772 // correct size, which LayoutSVGRoot::computeReplacedLogicalWidth/Height rel y on, when laying 770 // correct size, which LayoutSVGRoot::computeReplacedLogicalWidth/Height rel y on, when laying
773 // out for the first time, or when the LayoutSVGRoot size has changed dynami cally (eg. via <script>). 771 // out for the first time, or when the LayoutSVGRoot size has changed dynami cally (eg. via <script>).
774 FrameView* frameView = ownerLayoutObject->frame()->view(); 772 FrameView* frameView = ownerLayoutObject->frame()->view();
775 TemporaryChange<bool> t(frameView->m_inForcedLayoutByChildEmbeddedReplacedCo ntent, true);
776 773
777 // Mark the owner layoutObject as needing layout. 774 // Mark the owner layoutObject as needing layout.
778 ownerLayoutObject->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation (LayoutInvalidationReason::Unknown); 775 ownerLayoutObject->setNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation (LayoutInvalidationReason::Unknown);
779 776
780 // Synchronously enter layout, to layout the view containing the host object /embed/iframe. 777 // Synchronously enter layout, to layout the view containing the host object /embed/iframe.
781 ASSERT(frameView); 778 ASSERT(frameView);
782 frameView->layout(); 779 frameView->layout();
783 } 780 }
784 781
785 void FrameView::performPreLayoutTasks() 782 void FrameView::performPreLayoutTasks()
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 ASSERT(m_frame->page()); 936 ASSERT(m_frame->page());
940 937
941 ScriptForbiddenScope forbidScript; 938 ScriptForbiddenScope forbidScript;
942 939
943 if (isInPerformLayout() || shouldThrottleRendering() || !m_frame->document() ->isActive()) 940 if (isInPerformLayout() || shouldThrottleRendering() || !m_frame->document() ->isActive())
944 return; 941 return;
945 942
946 TRACE_EVENT0("blink,benchmark", "FrameView::layout"); 943 TRACE_EVENT0("blink,benchmark", "FrameView::layout");
947 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout"); 944 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "Layout");
948 945
949 TemporaryChange<bool> allowsLayoutInvalidation(m_allowsLayoutInvalidationAft erLayoutClean, true);
950
951 if (m_autoSizeInfo) 946 if (m_autoSizeInfo)
952 m_autoSizeInfo->autoSizeIfNeeded(); 947 m_autoSizeInfo->autoSizeIfNeeded();
953 948
954 m_hasPendingLayout = false; 949 m_hasPendingLayout = false;
955 DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::Layo utClean); 950 DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::Layo utClean);
956 951
957 TRACE_EVENT_BEGIN1("devtools.timeline", "Layout", "beginData", InspectorLayo utEvent::beginData(this)); 952 TRACE_EVENT_BEGIN1("devtools.timeline", "Layout", "beginData", InspectorLayo utEvent::beginData(this));
958 953
959 performPreLayoutTasks(); 954 performPreLayoutTasks();
960 955
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1229 1224
1230 for (auto part : parts) { 1225 for (auto part : parts) {
1231 // Script or plugins could detach the frame so abort processing if that happens. 1226 // Script or plugins could detach the frame so abort processing if that happens.
1232 if (layoutViewItem().isNull()) 1227 if (layoutViewItem().isNull())
1233 break; 1228 break;
1234 1229
1235 if (Widget* widget = part->widget()) { 1230 if (Widget* widget = part->widget()) {
1236 if (widget->isFrameView()) { 1231 if (widget->isFrameView()) {
1237 FrameView* frameView = toFrameView(widget); 1232 FrameView* frameView = toFrameView(widget);
1238 bool didNeedLayout = frameView->needsLayout(); 1233 bool didNeedLayout = frameView->needsLayout();
1239 // LayoutPart::updateWidgetGeometry() may invalidate and update layout of the sub-FrameView. This is
1240 // allowed, but layout should be clean after updateWidgetGeometr y unless the FrameView is throttled.
1241 TemporaryChange<bool> allowLayoutInvalidation(frameView->m_allow sLayoutInvalidationAfterLayoutClean, true);
1242 part->updateWidgetGeometry(); 1234 part->updateWidgetGeometry();
1243 if (!didNeedLayout && !frameView->shouldThrottleRendering()) 1235 if (!didNeedLayout && !frameView->shouldThrottleRendering())
1244 frameView->checkDoesNotNeedLayout(); 1236 frameView->checkDoesNotNeedLayout();
1245 } else { 1237 } else {
1246 part->updateWidgetGeometry(); 1238 part->updateWidgetGeometry();
1247 } 1239 }
1248 } 1240 }
1249 } 1241 }
1250 } 1242 }
1251 1243
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 || !root->styleRef().logicalHeight().isIntrinsicOrAuto()) { 1817 || !root->styleRef().logicalHeight().isIntrinsicOrAuto()) {
1826 continue; 1818 continue;
1827 } 1819 }
1828 LayoutState layoutState(*root); 1820 LayoutState layoutState(*root);
1829 root->layout(); 1821 root->layout();
1830 } 1822 }
1831 } 1823 }
1832 1824
1833 void FrameView::checkLayoutInvalidationIsAllowed() const 1825 void FrameView::checkLayoutInvalidationIsAllowed() const
1834 { 1826 {
1835 CHECK(!m_inPluginUpdate); 1827 if (m_allowsLayoutInvalidationAfterLayoutClean)
1828 return;
1836 1829
1837 if (!m_frame->document()) 1830 if (!m_frame->document())
1838 return; 1831 return;
1839 1832
1840 // TODO(crbug.com/442939): These are hacks to support embedded SVG. This is called from
1841 // FrameView::forceLayoutParentViewIfNeeded() and the dirty layout will be c leaned up immediately.
1842 // This is for the parent view of the view containing the embedded SVG.
1843 if (m_inForcedLayoutByChildEmbeddedReplacedContent)
1844 return;
1845 // This is for the view containing the embedded SVG.
1846 if (embeddedReplacedContent()) {
1847 if (const LayoutObject* ownerLayoutObject = m_frame->ownerLayoutObject() ) {
1848 if (LocalFrame* frame = ownerLayoutObject->frame()) {
1849 if (frame->view()->m_inForcedLayoutByChildEmbeddedReplacedConten t)
1850 return;
1851 }
1852 }
1853 }
1854
1855 CHECK(lifecycle().stateAllowsLayoutInvalidation());
1856
1857 if (m_allowsLayoutInvalidationAfterLayoutClean)
1858 return;
1859
1860 // If we are updating all lifecycle phases beyond LayoutClean, we don't expe ct dirty layout after LayoutClean. 1833 // If we are updating all lifecycle phases beyond LayoutClean, we don't expe ct dirty layout after LayoutClean.
1861 if (FrameView* rootFrameView = m_frame->localFrameRoot()->view()) { 1834 CHECK(lifecycle().state() < DocumentLifecycle::LayoutClean);
1862 if (rootFrameView->m_currentUpdateLifecyclePhasesTargetState > DocumentL ifecycle::LayoutClean)
1863 CHECK(lifecycle().state() < DocumentLifecycle::LayoutClean);
1864 }
1865 } 1835 }
1866 1836
1867 void FrameView::scheduleRelayout() 1837 void FrameView::scheduleRelayout()
1868 { 1838 {
1869 DCHECK(m_frame->view() == this); 1839 DCHECK(m_frame->view() == this);
1870 1840
1871 if (!m_layoutSchedulingEnabled) 1841 if (!m_layoutSchedulingEnabled)
1872 return; 1842 return;
1873 1843
1874 checkLayoutInvalidationIsAllowed(); 1844 checkLayoutInvalidationIsAllowed();
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after
2524 2494
2525 updateStyleAndLayoutIfNeededRecursive(); 2495 updateStyleAndLayoutIfNeededRecursive();
2526 DCHECK(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2496 DCHECK(lifecycle().state() >= DocumentLifecycle::LayoutClean);
2527 2497
2528 if (targetState == DocumentLifecycle::LayoutClean) { 2498 if (targetState == DocumentLifecycle::LayoutClean) {
2529 updateViewportIntersectionsForSubtree(targetState); 2499 updateViewportIntersectionsForSubtree(targetState);
2530 return; 2500 return;
2531 } 2501 }
2532 2502
2533 if (LayoutViewItem view = layoutViewItem()) { 2503 if (LayoutViewItem view = layoutViewItem()) {
2504 forAllNonThrottledFrameViews([](FrameView& frameView) {
szager1 2016/07/07 18:55:29 It's probably a minor point, but this becomes O(N^
Xianzhu 2016/07/07 19:06:06 It seems wrong that this function is recursed. Try
szager1 2016/07/07 19:12:41 Oh yes, you are right; never mind my comment.
2505 frameView.checkDoesNotNeedLayout();
2506 frameView.m_allowsLayoutInvalidationAfterLayoutClean = false;
2507 });
2508
2534 { 2509 {
2535 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", Inspect orUpdateLayerTreeEvent::data(m_frame.get())); 2510 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", Inspect orUpdateLayerTreeEvent::data(m_frame.get()));
2536 2511
2537 // This was required for slimming paint v1 but is only temporarily 2512 // This was required for slimming paint v1 but is only temporarily
2538 // needed for slimming paint v2. 2513 // needed for slimming paint v2.
2539 view.compositor()->updateIfNeededRecursive(); 2514 view.compositor()->updateIfNeededRecursive();
2540 scrollContentsIfNeededRecursive(); 2515 scrollContentsIfNeededRecursive();
2541 2516
2542 ASSERT(lifecycle().state() >= DocumentLifecycle::CompositingClean); 2517 DCHECK(lifecycle().state() >= DocumentLifecycle::CompositingClean);
2543 2518
2544 if (targetState >= DocumentLifecycle::PrePaintClean) { 2519 if (targetState >= DocumentLifecycle::PrePaintClean) {
2545 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) 2520 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled())
2546 invalidateTreeIfNeededRecursive(); 2521 invalidateTreeIfNeededRecursive();
2547 2522
2548 if (view.compositor()->inCompositingMode()) 2523 if (view.compositor()->inCompositingMode())
2549 scrollingCoordinator()->updateAfterCompositingChangeIfNeeded (); 2524 scrollingCoordinator()->updateAfterCompositingChangeIfNeeded ();
2550 2525
2551 updateCompositedSelectionIfNeeded(); 2526 updateCompositedSelectionIfNeeded();
2552 } 2527 }
2553 } 2528 }
2554 2529
2555 if (targetState >= DocumentLifecycle::PrePaintClean) { 2530 if (targetState >= DocumentLifecycle::PrePaintClean) {
2556 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 2531 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
2557 updatePaintProperties(); 2532 updatePaintProperties();
2558 } 2533 }
2559 2534
2560 if (targetState == DocumentLifecycle::PaintClean) { 2535 if (targetState == DocumentLifecycle::PaintClean) {
2561 if (!m_frame->document()->printing()) 2536 if (!m_frame->document()->printing())
2562 synchronizedPaint(); 2537 synchronizedPaint();
2563 2538
2564 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 2539 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
2565 pushPaintArtifactToCompositor(); 2540 pushPaintArtifactToCompositor();
2566 2541
2567 ASSERT(!view.hasPendingSelection()); 2542 DCHECK(!view.hasPendingSelection());
2568 ASSERT((m_frame->document()->printing() && lifecycle().state() == Do cumentLifecycle::PaintInvalidationClean) 2543 DCHECK((m_frame->document()->printing() && lifecycle().state() == Do cumentLifecycle::PaintInvalidationClean)
2569 || lifecycle().state() == DocumentLifecycle::PaintClean); 2544 || lifecycle().state() == DocumentLifecycle::PaintClean);
2570 } 2545 }
2546
2547 forAllNonThrottledFrameViews([](FrameView& frameView) {
2548 frameView.checkDoesNotNeedLayout();
2549 frameView.m_allowsLayoutInvalidationAfterLayoutClean = true;
2550 });
2571 } 2551 }
2572 2552
2573 updateViewportIntersectionsForSubtree(targetState); 2553 updateViewportIntersectionsForSubtree(targetState);
2574 } 2554 }
2575 2555
2576 void FrameView::updatePaintProperties() 2556 void FrameView::updatePaintProperties()
2577 { 2557 {
2578 TRACE_EVENT0("blink", "FrameView::updatePaintProperties"); 2558 TRACE_EVENT0("blink", "FrameView::updatePaintProperties");
2579 2559
2580 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 2560 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
2685 // Mac actually tests for intersection with the dirty region and tries not t o 2665 // Mac actually tests for intersection with the dirty region and tries not t o
2686 // update layout for frames that are outside the dirty region. Not only doe s this seem 2666 // update layout for frames that are outside the dirty region. Not only doe s this seem
2687 // pointless (since those frames will have set a zero timer to layout anyway ), but 2667 // pointless (since those frames will have set a zero timer to layout anyway ), but
2688 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty 2668 // it is also incorrect, since if two frames overlap, the first could be exc luded from the dirty
2689 // region but then become included later by the second frame adding rects to the dirty region 2669 // region but then become included later by the second frame adding rects to the dirty region
2690 // when it lays out. 2670 // when it lays out.
2691 2671
2692 m_frame->document()->updateStyleAndLayoutTree(); 2672 m_frame->document()->updateStyleAndLayoutTree();
2693 2673
2694 CHECK(!shouldThrottleRendering()); 2674 CHECK(!shouldThrottleRendering());
2675 CHECK(m_frame->document()->isActive());
2676 CHECK(!m_nestedLayoutCount);
szager1 2016/07/07 18:55:29 Nice!
2695 2677
2696 if (needsLayout()) 2678 if (needsLayout())
2697 layout(); 2679 layout();
2698 2680
2699 checkDoesNotNeedLayout(); 2681 checkDoesNotNeedLayout();
2700 2682
2701 // WebView plugins need to update regardless of whether the LayoutEmbeddedOb ject 2683 // WebView plugins need to update regardless of whether the LayoutEmbeddedOb ject
2702 // that owns them needed layout. 2684 // that owns them needed layout.
2703 // TODO(leviw): This currently runs the entire lifecycle on plugin WebViews. We 2685 // TODO(leviw): This currently runs the entire lifecycle on plugin WebViews. We
2704 // should have a way to only run these other Documents to the same lifecycle stage 2686 // should have a way to only run these other Documents to the same lifecycle stage
2705 // as this frame. 2687 // as this frame.
2706 { 2688 const ChildrenWidgetSet* viewChildren = children();
2707 TemporaryChange<bool> t(m_inPluginUpdate, true); 2689 for (const Member<Widget>& child : *viewChildren) {
2708 const ChildrenWidgetSet* viewChildren = children(); 2690 if ((*child).isPluginContainer())
2709 for (const Member<Widget>& child : *viewChildren) { 2691 toPluginView(child.get())->updateAllLifecyclePhases();
2710 if ((*child).isPluginContainer())
2711 toPluginView(child.get())->updateAllLifecyclePhases();
2712 }
2713 checkDoesNotNeedLayout();
2714 } 2692 }
2693 checkDoesNotNeedLayout();
2715 2694
2716 // FIXME: Calling layout() shouldn't trigger script execution or have any 2695 // FIXME: Calling layout() shouldn't trigger script execution or have any
2717 // observable effects on the frame tree but we're not quite there yet. 2696 // observable effects on the frame tree but we're not quite there yet.
2718 HeapVector<Member<FrameView>> frameViews; 2697 HeapVector<Member<FrameView>> frameViews;
2719 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) { 2698 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
2720 if (!child->isLocalFrame()) 2699 if (!child->isLocalFrame())
2721 continue; 2700 continue;
2722 if (FrameView* view = toLocalFrame(child)->view()) 2701 if (FrameView* view = toLocalFrame(child)->view())
2723 frameViews.append(view); 2702 frameViews.append(view);
2724 } 2703 }
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after
4243 return m_subtreeThrottled || (m_hiddenForThrottling && m_crossOriginForThrot tling); 4222 return m_subtreeThrottled || (m_hiddenForThrottling && m_crossOriginForThrot tling);
4244 } 4223 }
4245 4224
4246 LayoutBox& FrameView::boxForScrollControlPaintInvalidation() const 4225 LayoutBox& FrameView::boxForScrollControlPaintInvalidation() const
4247 { 4226 {
4248 ASSERT(!layoutViewItem().isNull()); 4227 ASSERT(!layoutViewItem().isNull());
4249 return *layoutView(); 4228 return *layoutView();
4250 } 4229 }
4251 4230
4252 } // namespace blink 4231 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameView.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698