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

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

Issue 2531603003: Only scroll on main if the targeted frames need to scroll on main (Closed)
Patch Set: Resolve conflict Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 m_hiddenForThrottling(false), 187 m_hiddenForThrottling(false),
188 m_subtreeThrottled(false), 188 m_subtreeThrottled(false),
189 m_lifecycleUpdatesThrottled(false), 189 m_lifecycleUpdatesThrottled(false),
190 m_needsPaintPropertyUpdate(true), 190 m_needsPaintPropertyUpdate(true),
191 m_currentUpdateLifecyclePhasesTargetState( 191 m_currentUpdateLifecyclePhasesTargetState(
192 DocumentLifecycle::Uninitialized), 192 DocumentLifecycle::Uninitialized),
193 m_scrollAnchor(this), 193 m_scrollAnchor(this),
194 m_scrollbarManager(*this), 194 m_scrollbarManager(*this),
195 m_needsScrollbarsUpdate(false), 195 m_needsScrollbarsUpdate(false),
196 m_suppressAdjustViewSize(false), 196 m_suppressAdjustViewSize(false),
197 m_allowsLayoutInvalidationAfterLayoutClean(true) { 197 m_allowsLayoutInvalidationAfterLayoutClean(true),
198 m_mainThreadScrollingReasons(0) {
198 init(); 199 init();
199 } 200 }
200 201
201 FrameView* FrameView::create(LocalFrame& frame) { 202 FrameView* FrameView::create(LocalFrame& frame) {
202 FrameView* view = new FrameView(frame); 203 FrameView* view = new FrameView(frame);
203 view->show(); 204 view->show();
204 return view; 205 return view;
205 } 206 }
206 207
207 FrameView* FrameView::create(LocalFrame& frame, const IntSize& initialSize) { 208 FrameView* FrameView::create(LocalFrame& frame, const IntSize& initialSize) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 m_firstLayout = true; 251 m_firstLayout = true;
251 m_safeToPropagateScrollToParent = true; 252 m_safeToPropagateScrollToParent = true;
252 m_lastViewportSize = IntSize(); 253 m_lastViewportSize = IntSize();
253 m_lastZoomFactor = 1.0f; 254 m_lastZoomFactor = 1.0f;
254 m_trackedObjectPaintInvalidations = WTF::wrapUnique( 255 m_trackedObjectPaintInvalidations = WTF::wrapUnique(
255 s_initialTrackAllPaintInvalidations ? new Vector<ObjectPaintInvalidation> 256 s_initialTrackAllPaintInvalidations ? new Vector<ObjectPaintInvalidation>
256 : nullptr); 257 : nullptr);
257 m_visuallyNonEmptyCharacterCount = 0; 258 m_visuallyNonEmptyCharacterCount = 0;
258 m_visuallyNonEmptyPixelCount = 0; 259 m_visuallyNonEmptyPixelCount = 0;
259 m_isVisuallyNonEmpty = false; 260 m_isVisuallyNonEmpty = false;
261 m_mainThreadScrollingReasons = 0;
260 m_layoutObjectCounter.reset(); 262 m_layoutObjectCounter.reset();
261 clearFragmentAnchor(); 263 clearFragmentAnchor();
262 m_viewportConstrainedObjects.reset(); 264 m_viewportConstrainedObjects.reset();
263 m_layoutSubtreeRootList.clear(); 265 m_layoutSubtreeRootList.clear();
264 m_orthogonalWritingModeRootList.clear(); 266 m_orthogonalWritingModeRootList.clear();
265 } 267 }
266 268
267 // Call function for each non-throttled frame view in pre tree order. 269 // Call function for each non-throttled frame view in pre tree order.
268 // Note it needs a null check of the frame's layoutView to access it in case of 270 // Note it needs a null check of the frame's layoutView to access it in case of
269 // detached frames. 271 // detached frames.
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 adjustViewSize(); 698 adjustViewSize();
697 if (needsLayout()) { 699 if (needsLayout()) {
698 AutoReset<bool> suppressAdjustViewSize(&m_suppressAdjustViewSize, true); 700 AutoReset<bool> suppressAdjustViewSize(&m_suppressAdjustViewSize, true);
699 layout(); 701 layout();
700 } 702 }
701 } 703 }
702 704
703 void FrameView::calculateScrollbarModesFromOverflowStyle( 705 void FrameView::calculateScrollbarModesFromOverflowStyle(
704 const ComputedStyle* style, 706 const ComputedStyle* style,
705 ScrollbarMode& hMode, 707 ScrollbarMode& hMode,
706 ScrollbarMode& vMode) { 708 ScrollbarMode& vMode) const {
707 hMode = vMode = ScrollbarAuto; 709 hMode = vMode = ScrollbarAuto;
708 710
709 EOverflow overflowX = style->overflowX(); 711 EOverflow overflowX = style->overflowX();
710 EOverflow overflowY = style->overflowY(); 712 EOverflow overflowY = style->overflowY();
711 713
712 if (!shouldIgnoreOverflowHidden()) { 714 if (!shouldIgnoreOverflowHidden()) {
713 if (overflowX == EOverflow::Hidden) 715 if (overflowX == EOverflow::Hidden)
714 hMode = ScrollbarAlwaysOff; 716 hMode = ScrollbarAlwaysOff;
715 if (overflowY == EOverflow::Hidden) 717 if (overflowY == EOverflow::Hidden)
716 vMode = ScrollbarAlwaysOff; 718 vMode = ScrollbarAlwaysOff;
717 } 719 }
718 720
719 if (overflowX == EOverflow::Scroll) 721 if (overflowX == EOverflow::Scroll)
720 hMode = ScrollbarAlwaysOn; 722 hMode = ScrollbarAlwaysOn;
721 if (overflowY == EOverflow::Scroll) 723 if (overflowY == EOverflow::Scroll)
722 vMode = ScrollbarAlwaysOn; 724 vMode = ScrollbarAlwaysOn;
723 } 725 }
724 726
725 void FrameView::calculateScrollbarModes( 727 void FrameView::calculateScrollbarModes(
726 ScrollbarMode& hMode, 728 ScrollbarMode& hMode,
727 ScrollbarMode& vMode, 729 ScrollbarMode& vMode,
728 ScrollbarModesCalculationStrategy strategy) { 730 ScrollbarModesCalculationStrategy strategy) const {
729 #define RETURN_SCROLLBAR_MODE(mode) \ 731 #define RETURN_SCROLLBAR_MODE(mode) \
730 { \ 732 { \
731 hMode = vMode = mode; \ 733 hMode = vMode = mode; \
732 return; \ 734 return; \
733 } 735 }
734 736
735 // Setting scrolling="no" on an iframe element disables scrolling. 737 // Setting scrolling="no" on an iframe element disables scrolling.
736 if (m_frame->owner() && 738 if (m_frame->owner() &&
737 m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff) 739 m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff)
738 RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff); 740 RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 LayoutViewItem layoutView = this->layoutViewItem(); 827 LayoutViewItem layoutView = this->layoutViewItem();
826 if (layoutView.isNull()) 828 if (layoutView.isNull())
827 return false; 829 return false;
828 if (m_frame->settings() && 830 if (m_frame->settings() &&
829 m_frame->settings()->preferCompositingToLCDTextEnabled()) 831 m_frame->settings()->preferCompositingToLCDTextEnabled())
830 return layoutView.compositor()->inCompositingMode(); 832 return layoutView.compositor()->inCompositingMode();
831 return false; 833 return false;
832 } 834 }
833 835
834 bool FrameView::shouldScrollOnMainThread() const { 836 bool FrameView::shouldScrollOnMainThread() const {
835 if (ScrollingCoordinator* sc = scrollingCoordinator()) { 837 if (mainThreadScrollingReasons())
836 if (sc->shouldUpdateScrollLayerPositionOnMainThread()) 838 return true;
837 return true;
838 }
839 return ScrollableArea::shouldScrollOnMainThread(); 839 return ScrollableArea::shouldScrollOnMainThread();
840 } 840 }
841 841
842 GraphicsLayer* FrameView::layerForScrolling() const { 842 GraphicsLayer* FrameView::layerForScrolling() const {
843 LayoutViewItem layoutView = this->layoutViewItem(); 843 LayoutViewItem layoutView = this->layoutViewItem();
844 if (layoutView.isNull()) 844 if (layoutView.isNull())
845 return nullptr; 845 return nullptr;
846 return layoutView.compositor()->frameScrollLayer(); 846 return layoutView.compositor()->frameScrollLayer();
847 } 847 }
848 848
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after
2534 } 2534 }
2535 2535
2536 bool FrameView::isScrollable() { 2536 bool FrameView::isScrollable() {
2537 return getScrollingReasons() == Scrollable; 2537 return getScrollingReasons() == Scrollable;
2538 } 2538 }
2539 2539
2540 bool FrameView::isProgrammaticallyScrollable() { 2540 bool FrameView::isProgrammaticallyScrollable() {
2541 return !m_inUpdateScrollbars; 2541 return !m_inUpdateScrollbars;
2542 } 2542 }
2543 2543
2544 FrameView::ScrollingReasons FrameView::getScrollingReasons() { 2544 FrameView::ScrollingReasons FrameView::getScrollingReasons() const {
2545 // Check for: 2545 // Check for:
2546 // 1) If there an actual overflow. 2546 // 1) If there an actual overflow.
2547 // 2) display:none or visibility:hidden set to self or inherited. 2547 // 2) display:none or visibility:hidden set to self or inherited.
2548 // 3) overflow{-x,-y}: hidden; 2548 // 3) overflow{-x,-y}: hidden;
2549 // 4) scrolling: no; 2549 // 4) scrolling: no;
2550 2550
2551 // Covers #1 2551 // Covers #1
2552 IntSize contentsSize = this->contentsSize(); 2552 IntSize contentsSize = this->contentsSize();
2553 IntSize visibleContentSize = visibleContentRect().size(); 2553 IntSize visibleContentSize = visibleContentRect().size();
2554 if ((contentsSize.height() <= visibleContentSize.height() && 2554 if ((contentsSize.height() <= visibleContentSize.height() &&
(...skipping 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4697 int FrameView::initialViewportWidth() const { 4697 int FrameView::initialViewportWidth() const {
4698 DCHECK(m_frame->isMainFrame()); 4698 DCHECK(m_frame->isMainFrame());
4699 return m_initialViewportSize.width(); 4699 return m_initialViewportSize.width();
4700 } 4700 }
4701 4701
4702 int FrameView::initialViewportHeight() const { 4702 int FrameView::initialViewportHeight() const {
4703 DCHECK(m_frame->isMainFrame()); 4703 DCHECK(m_frame->isMainFrame());
4704 return m_initialViewportSize.height(); 4704 return m_initialViewportSize.height();
4705 } 4705 }
4706 4706
4707 bool FrameView::hasVisibleSlowRepaintViewportConstrainedObjects() const {
4708 if (!viewportConstrainedObjects())
4709 return false;
4710
4711 for (const LayoutObject* layoutObject : *viewportConstrainedObjects()) {
4712 DCHECK(layoutObject->isBoxModelObject() && layoutObject->hasLayer());
4713 DCHECK(layoutObject->style()->position() == FixedPosition ||
4714 layoutObject->style()->position() == StickyPosition);
4715 PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer();
4716
4717 // Whether the Layer sticks to the viewport is a tree-depenent
4718 // property and our viewportConstrainedObjects collection is maintained
4719 // with only LayoutObject-level information.
4720 if (!layer->sticksToViewport())
4721 continue;
4722
4723 // If the whole subtree is invisible, there's no reason to scroll on
4724 // the main thread because we don't need to generate invalidations
4725 // for invisible content.
4726 if (layer->subtreeIsInvisible())
4727 continue;
4728
4729 // We're only smart enough to scroll viewport-constrainted objects
4730 // in the compositor if they have their own backing or they paint
4731 // into a grouped back (which necessarily all have the same viewport
4732 // constraints).
4733 CompositingState compositingState = layer->compositingState();
4734 if (compositingState != PaintsIntoOwnBacking &&
4735 compositingState != PaintsIntoGroupedBacking)
4736 return true;
4737 }
4738 return false;
4739 }
4740
4741 void FrameView::updateSubFrameScrollOnMainReason(
4742 const Frame& frame,
4743 MainThreadScrollingReasons parentReason) {
4744 MainThreadScrollingReasons reasons = parentReason;
4745
4746 if (!page()->settings().threadedScrollingEnabled())
4747 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
4748
4749 if (!frame.isLocalFrame())
4750 return;
4751
4752 if (!toLocalFrame(frame).view()->layerForScrolling())
4753 return;
4754
4755 reasons |= toLocalFrame(frame).view()->mainThreadScrollingReasonsPerFrame();
4756 if (WebLayer* scrollLayer =
4757 toLocalFrame(frame).view()->layerForScrolling()->platformLayer()) {
4758 if (reasons) {
4759 scrollLayer->addMainThreadScrollingReasons(reasons);
4760 } else {
4761 // Clear all main thread scrolling reasons except the one that's set
4762 // if there is a running scroll animation.
4763 scrollLayer->clearMainThreadScrollingReasons(
4764 ~MainThreadScrollingReason::kHandlingScrollFromMainThread);
4765 }
4766 }
4767
4768 Frame* child = frame.tree().firstChild();
4769 while (child) {
4770 updateSubFrameScrollOnMainReason(*child, reasons);
4771 child = child->tree().nextSibling();
4772 }
4773
4774 if (frame.isMainFrame())
4775 m_mainThreadScrollingReasons = reasons;
4776 }
4777
4778 MainThreadScrollingReasons FrameView::mainThreadScrollingReasonsPerFrame()
4779 const {
4780 MainThreadScrollingReasons reasons =
4781 static_cast<MainThreadScrollingReasons>(0);
4782
4783 if (shouldThrottleRendering())
4784 return reasons;
4785
4786 if (hasBackgroundAttachmentFixedObjects())
4787 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects;
4788 ScrollingReasons scrollingReasons = getScrollingReasons();
4789 const bool mayBeScrolledByInput = (scrollingReasons == Scrollable);
4790 const bool mayBeScrolledByScript =
4791 mayBeScrolledByInput ||
4792 (scrollingReasons == NotScrollableExplicitlyDisabled);
4793
4794 // TODO(awoloszyn) Currently crbug.com/304810 will let certain
4795 // overflow:hidden elements scroll on the compositor thread, so we should
4796 // not let this move there path as an optimization, when we have
4797 // slow-repaint elements.
4798 if (mayBeScrolledByScript &&
4799 hasVisibleSlowRepaintViewportConstrainedObjects()) {
4800 reasons |=
4801 MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects;
4802 }
4803 return reasons;
4804 }
4805
4806 MainThreadScrollingReasons FrameView::mainThreadScrollingReasons() const {
4807 MainThreadScrollingReasons reasons =
4808 static_cast<MainThreadScrollingReasons>(0);
4809
4810 if (!page()->settings().threadedScrollingEnabled())
4811 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled;
4812
4813 if (!page()->mainFrame()->isLocalFrame())
4814 return reasons;
4815
4816 // TODO(alexmos,kenrb): For OOPIF, local roots that are different from
4817 // the main frame can't be used in the calculation, since they use
4818 // different compositors with unrelated state, which breaks some of the
4819 // calculations below.
4820 if (m_frame->localFrameRoot() != page()->mainFrame())
4821 return reasons;
4822
4823 // Walk the tree to the root. Use the gathered reasons to determine
4824 // whether the target frame should be scrolled on main thread regardless
4825 // other subframes on the same page.
4826 for (Frame* frame = m_frame; frame; frame = frame->tree().parent()) {
4827 if (!frame->isLocalFrame())
4828 continue;
4829 reasons |=
4830 toLocalFrame(frame)->view()->mainThreadScrollingReasonsPerFrame();
4831 }
4832
4833 return reasons;
4834 }
4835
4836 String FrameView::mainThreadScrollingReasonsAsText() const {
4837 DCHECK(lifecycle().state() >= DocumentLifecycle::CompositingClean);
4838 if (layerForScrolling() && layerForScrolling()->platformLayer()) {
4839 String result(
4840 MainThreadScrollingReason::mainThreadScrollingReasonsAsText(
4841 layerForScrolling()->platformLayer()->mainThreadScrollingReasons())
4842 .c_str());
4843 return result;
4844 }
4845
4846 String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText(
4847 m_mainThreadScrollingReasons)
4848 .c_str());
4849 return result;
4850 }
4851
4707 } // namespace blink 4852 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/frame/FrameView.h ('k') | third_party/WebKit/Source/core/page/Page.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698