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