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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 adjustViewSize(); | 693 adjustViewSize(); |
692 if (needsLayout()) { | 694 if (needsLayout()) { |
693 AutoReset<bool> suppressAdjustViewSize(&m_suppressAdjustViewSize, true); | 695 AutoReset<bool> suppressAdjustViewSize(&m_suppressAdjustViewSize, true); |
694 layout(); | 696 layout(); |
695 } | 697 } |
696 } | 698 } |
697 | 699 |
698 void FrameView::calculateScrollbarModesFromOverflowStyle( | 700 void FrameView::calculateScrollbarModesFromOverflowStyle( |
699 const ComputedStyle* style, | 701 const ComputedStyle* style, |
700 ScrollbarMode& hMode, | 702 ScrollbarMode& hMode, |
701 ScrollbarMode& vMode) { | 703 ScrollbarMode& vMode) const { |
702 hMode = vMode = ScrollbarAuto; | 704 hMode = vMode = ScrollbarAuto; |
703 | 705 |
704 EOverflow overflowX = style->overflowX(); | 706 EOverflow overflowX = style->overflowX(); |
705 EOverflow overflowY = style->overflowY(); | 707 EOverflow overflowY = style->overflowY(); |
706 | 708 |
707 if (!shouldIgnoreOverflowHidden()) { | 709 if (!shouldIgnoreOverflowHidden()) { |
708 if (overflowX == EOverflow::Hidden) | 710 if (overflowX == EOverflow::Hidden) |
709 hMode = ScrollbarAlwaysOff; | 711 hMode = ScrollbarAlwaysOff; |
710 if (overflowY == EOverflow::Hidden) | 712 if (overflowY == EOverflow::Hidden) |
711 vMode = ScrollbarAlwaysOff; | 713 vMode = ScrollbarAlwaysOff; |
712 } | 714 } |
713 | 715 |
714 if (overflowX == EOverflow::Scroll) | 716 if (overflowX == EOverflow::Scroll) |
715 hMode = ScrollbarAlwaysOn; | 717 hMode = ScrollbarAlwaysOn; |
716 if (overflowY == EOverflow::Scroll) | 718 if (overflowY == EOverflow::Scroll) |
717 vMode = ScrollbarAlwaysOn; | 719 vMode = ScrollbarAlwaysOn; |
718 } | 720 } |
719 | 721 |
720 void FrameView::calculateScrollbarModes( | 722 void FrameView::calculateScrollbarModes( |
721 ScrollbarMode& hMode, | 723 ScrollbarMode& hMode, |
722 ScrollbarMode& vMode, | 724 ScrollbarMode& vMode, |
723 ScrollbarModesCalculationStrategy strategy) { | 725 ScrollbarModesCalculationStrategy strategy) const { |
724 #define RETURN_SCROLLBAR_MODE(mode) \ | 726 #define RETURN_SCROLLBAR_MODE(mode) \ |
725 { \ | 727 { \ |
726 hMode = vMode = mode; \ | 728 hMode = vMode = mode; \ |
727 return; \ | 729 return; \ |
728 } | 730 } |
729 | 731 |
730 // Setting scrolling="no" on an iframe element disables scrolling. | 732 // Setting scrolling="no" on an iframe element disables scrolling. |
731 if (m_frame->owner() && | 733 if (m_frame->owner() && |
732 m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff) | 734 m_frame->owner()->scrollingMode() == ScrollbarAlwaysOff) |
733 RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff); | 735 RETURN_SCROLLBAR_MODE(ScrollbarAlwaysOff); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 LayoutViewItem layoutView = this->layoutViewItem(); | 822 LayoutViewItem layoutView = this->layoutViewItem(); |
821 if (layoutView.isNull()) | 823 if (layoutView.isNull()) |
822 return false; | 824 return false; |
823 if (m_frame->settings() && | 825 if (m_frame->settings() && |
824 m_frame->settings()->preferCompositingToLCDTextEnabled()) | 826 m_frame->settings()->preferCompositingToLCDTextEnabled()) |
825 return layoutView.compositor()->inCompositingMode(); | 827 return layoutView.compositor()->inCompositingMode(); |
826 return false; | 828 return false; |
827 } | 829 } |
828 | 830 |
829 bool FrameView::shouldScrollOnMainThread() const { | 831 bool FrameView::shouldScrollOnMainThread() const { |
830 if (ScrollingCoordinator* sc = scrollingCoordinator()) { | 832 if (mainThreadScrollingReasons()) |
831 if (sc->shouldUpdateScrollLayerPositionOnMainThread()) | 833 return true; |
832 return true; | |
833 } | |
834 return ScrollableArea::shouldScrollOnMainThread(); | 834 return ScrollableArea::shouldScrollOnMainThread(); |
835 } | 835 } |
836 | 836 |
837 GraphicsLayer* FrameView::layerForScrolling() const { | 837 GraphicsLayer* FrameView::layerForScrolling() const { |
838 LayoutViewItem layoutView = this->layoutViewItem(); | 838 LayoutViewItem layoutView = this->layoutViewItem(); |
839 if (layoutView.isNull()) | 839 if (layoutView.isNull()) |
840 return nullptr; | 840 return nullptr; |
841 return layoutView.compositor()->frameScrollLayer(); | 841 return layoutView.compositor()->frameScrollLayer(); |
842 } | 842 } |
843 | 843 |
(...skipping 1685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2529 } | 2529 } |
2530 | 2530 |
2531 bool FrameView::isScrollable() { | 2531 bool FrameView::isScrollable() { |
2532 return getScrollingReasons() == Scrollable; | 2532 return getScrollingReasons() == Scrollable; |
2533 } | 2533 } |
2534 | 2534 |
2535 bool FrameView::isProgrammaticallyScrollable() { | 2535 bool FrameView::isProgrammaticallyScrollable() { |
2536 return !m_inUpdateScrollbars; | 2536 return !m_inUpdateScrollbars; |
2537 } | 2537 } |
2538 | 2538 |
2539 FrameView::ScrollingReasons FrameView::getScrollingReasons() { | 2539 FrameView::ScrollingReasons FrameView::getScrollingReasons() const { |
2540 // Check for: | 2540 // Check for: |
2541 // 1) If there an actual overflow. | 2541 // 1) If there an actual overflow. |
2542 // 2) display:none or visibility:hidden set to self or inherited. | 2542 // 2) display:none or visibility:hidden set to self or inherited. |
2543 // 3) overflow{-x,-y}: hidden; | 2543 // 3) overflow{-x,-y}: hidden; |
2544 // 4) scrolling: no; | 2544 // 4) scrolling: no; |
2545 | 2545 |
2546 // Covers #1 | 2546 // Covers #1 |
2547 IntSize contentsSize = this->contentsSize(); | 2547 IntSize contentsSize = this->contentsSize(); |
2548 IntSize visibleContentSize = visibleContentRect().size(); | 2548 IntSize visibleContentSize = visibleContentRect().size(); |
2549 if ((contentsSize.height() <= visibleContentSize.height() && | 2549 if ((contentsSize.height() <= visibleContentSize.height() && |
(...skipping 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4692 int FrameView::initialViewportWidth() const { | 4692 int FrameView::initialViewportWidth() const { |
4693 DCHECK(m_frame->isMainFrame()); | 4693 DCHECK(m_frame->isMainFrame()); |
4694 return m_initialViewportSize.width(); | 4694 return m_initialViewportSize.width(); |
4695 } | 4695 } |
4696 | 4696 |
4697 int FrameView::initialViewportHeight() const { | 4697 int FrameView::initialViewportHeight() const { |
4698 DCHECK(m_frame->isMainFrame()); | 4698 DCHECK(m_frame->isMainFrame()); |
4699 return m_initialViewportSize.height(); | 4699 return m_initialViewportSize.height(); |
4700 } | 4700 } |
4701 | 4701 |
4702 bool FrameView::hasVisibleSlowRepaintViewportConstrainedObjects() const { | |
4703 if (!viewportConstrainedObjects()) | |
4704 return false; | |
4705 | |
4706 for (const LayoutObject* layoutObject : *viewportConstrainedObjects()) { | |
4707 DCHECK(layoutObject->isBoxModelObject() && layoutObject->hasLayer()); | |
4708 DCHECK(layoutObject->style()->position() == FixedPosition || | |
4709 layoutObject->style()->position() == StickyPosition); | |
4710 PaintLayer* layer = toLayoutBoxModelObject(layoutObject)->layer(); | |
4711 | |
4712 // Whether the Layer sticks to the viewport is a tree-depenent | |
4713 // property and our viewportConstrainedObjects collection is maintained | |
4714 // with only LayoutObject-level information. | |
4715 if (!layer->sticksToViewport()) | |
4716 continue; | |
4717 | |
4718 // If the whole subtree is invisible, there's no reason to scroll on | |
4719 // the main thread because we don't need to generate invalidations | |
4720 // for invisible content. | |
4721 if (layer->subtreeIsInvisible()) | |
4722 continue; | |
4723 | |
4724 // We're only smart enough to scroll viewport-constrainted objects | |
4725 // in the compositor if they have their own backing or they paint | |
4726 // into a grouped back (which necessarily all have the same viewport | |
4727 // constraints). | |
4728 CompositingState compositingState = layer->compositingState(); | |
4729 if (compositingState != PaintsIntoOwnBacking && | |
4730 compositingState != PaintsIntoGroupedBacking) | |
4731 return true; | |
4732 } | |
4733 return false; | |
4734 } | |
4735 | |
4736 void FrameView::updateSubFrameScrollOnMainReason( | |
4737 const Frame& frame, | |
4738 MainThreadScrollingReasons parentReason) { | |
4739 MainThreadScrollingReasons reasons = parentReason; | |
4740 | |
4741 if (!page()->settings().threadedScrollingEnabled()) | |
4742 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; | |
4743 | |
4744 if (!frame.isLocalFrame()) | |
4745 return; | |
4746 | |
4747 if (!toLocalFrame(frame).view()->layerForScrolling()) | |
4748 return; | |
4749 | |
4750 reasons |= toLocalFrame(frame).view()->mainThreadScrollingReasonsPerFrame(); | |
4751 if (WebLayer* scrollLayer = | |
4752 toLocalFrame(frame).view()->layerForScrolling()->platformLayer()) { | |
4753 if (reasons) { | |
4754 scrollLayer->addMainThreadScrollingReasons(reasons); | |
4755 } else { | |
4756 scrollLayer->clearMainThreadScrollingReasons( | |
pdr.
2016/12/19 04:04:28
Please add a comment here:
// Clear all main threa
yigu
2016/12/20 00:48:34
Done. Filed the bug as crbug.com/675677.
| |
4757 ~MainThreadScrollingReason::kHandlingScrollFromMainThread); | |
4758 } | |
4759 } | |
4760 | |
4761 Frame* child = frame.tree().firstChild(); | |
4762 while (child) { | |
4763 updateSubFrameScrollOnMainReason(*child, reasons); | |
4764 child = child->tree().nextSibling(); | |
4765 } | |
4766 | |
4767 if (frame.isMainFrame()) | |
4768 m_mainThreadScrollingReasons = reasons; | |
4769 } | |
4770 | |
4771 MainThreadScrollingReasons FrameView::mainThreadScrollingReasonsPerFrame() | |
4772 const { | |
4773 MainThreadScrollingReasons reasons = | |
4774 static_cast<MainThreadScrollingReasons>(0); | |
4775 | |
4776 if (shouldThrottleRendering()) | |
4777 return reasons; | |
4778 | |
4779 if (hasBackgroundAttachmentFixedObjects()) | |
4780 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; | |
4781 ScrollingReasons scrollingReasons = getScrollingReasons(); | |
pdr.
2016/12/19 04:04:28
I think there's a bug similar to https://crbug.com
yigu
2016/12/20 00:48:34
It seems we can handle it now. Unit test added.
| |
4782 const bool mayBeScrolledByInput = (scrollingReasons == Scrollable); | |
4783 const bool mayBeScrolledByScript = | |
4784 mayBeScrolledByInput || | |
4785 (scrollingReasons == NotScrollableExplicitlyDisabled); | |
4786 | |
4787 // TODO(awoloszyn) Currently crbug.com/304810 will let certain | |
4788 // overflow:hidden elements scroll on the compositor thread, so we should | |
4789 // not let this move there path as an optimization, when we have | |
4790 // slow-repaint elements. | |
4791 if (mayBeScrolledByScript && | |
4792 hasVisibleSlowRepaintViewportConstrainedObjects()) { | |
4793 reasons |= | |
4794 MainThreadScrollingReason::kHasNonLayerViewportConstrainedObjects; | |
4795 } | |
4796 return reasons; | |
4797 } | |
4798 | |
4799 MainThreadScrollingReasons FrameView::mainThreadScrollingReasons() const { | |
4800 MainThreadScrollingReasons reasons = | |
4801 static_cast<MainThreadScrollingReasons>(0); | |
4802 | |
4803 if (!page()->settings().threadedScrollingEnabled()) | |
4804 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; | |
4805 | |
4806 if (!page()->mainFrame()->isLocalFrame()) | |
4807 return reasons; | |
4808 | |
4809 // TODO(alexmos,kenrb): For OOPIF, local roots that are different from | |
4810 // the main frame can't be used in the calculation, since they use | |
4811 // different compositors with unrelated state, which breaks some of the | |
4812 // calculations below. | |
4813 if (m_frame->localFrameRoot() != page()->mainFrame()) | |
4814 return reasons; | |
4815 | |
4816 // Walk the tree to the root. Use the gathered reasons to determine | |
4817 // whether the target frame should be scrolled on main thread regardless | |
4818 // other subframes on the same page. | |
4819 for (Frame* frame = m_frame; frame; frame = frame->tree().parent()) { | |
4820 if (!frame->isLocalFrame()) | |
4821 continue; | |
4822 reasons |= | |
4823 toLocalFrame(frame)->view()->mainThreadScrollingReasonsPerFrame(); | |
4824 } | |
4825 | |
4826 return reasons; | |
4827 } | |
4828 | |
4829 String FrameView::mainThreadScrollingReasonsAsText() const { | |
4830 DCHECK(lifecycle().state() >= DocumentLifecycle::CompositingClean); | |
4831 if (layerForScrolling() && layerForScrolling()->platformLayer()) { | |
4832 String result( | |
4833 MainThreadScrollingReason::mainThreadScrollingReasonsAsText( | |
4834 layerForScrolling()->platformLayer()->mainThreadScrollingReasons()) | |
4835 .c_str()); | |
4836 return result; | |
4837 } | |
4838 | |
4839 String result(MainThreadScrollingReason::mainThreadScrollingReasonsAsText( | |
4840 m_mainThreadScrollingReasons) | |
4841 .c_str()); | |
4842 return result; | |
4843 } | |
4844 | |
4702 } // namespace blink | 4845 } // namespace blink |
OLD | NEW |