| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/PaintPropertyTreeBuilder.h" | 5 #include "core/paint/PaintPropertyTreeBuilder.h" |
| 6 | 6 |
| 7 #include "core/dom/DOMNodeIds.h" | 7 #include "core/dom/DOMNodeIds.h" |
| 8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
| 9 #include "core/frame/LocalFrame.h" | 9 #include "core/frame/LocalFrame.h" |
| 10 #include "core/frame/Settings.h" | 10 #include "core/frame/Settings.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); | 78 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| 79 if (auto* existingScrollTranslation = frameView.scrollTranslation()) { | 79 if (auto* existingScrollTranslation = frameView.scrollTranslation()) { |
| 80 existingScrollTranslation->update(std::move(parent), matrix, origin); | 80 existingScrollTranslation->update(std::move(parent), matrix, origin); |
| 81 return false; | 81 return false; |
| 82 } | 82 } |
| 83 frameView.setScrollTranslation( | 83 frameView.setScrollTranslation( |
| 84 TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); | 84 TransformPaintPropertyNode::create(std::move(parent), matrix, origin)); |
| 85 return true; | 85 return true; |
| 86 } | 86 } |
| 87 | 87 |
| 88 // True if a new property was created, false if an existing one was updated. | 88 // True if a new property was created or a main thread scrolling reason changed |
| 89 // (which can affect descendants), false if an existing one was updated. |
| 89 bool updateScroll(FrameView& frameView, | 90 bool updateScroll(FrameView& frameView, |
| 90 PassRefPtr<const ScrollPaintPropertyNode> parent, | 91 PassRefPtr<const ScrollPaintPropertyNode> parent, |
| 91 PassRefPtr<const TransformPaintPropertyNode> scrollOffset, | 92 PassRefPtr<const TransformPaintPropertyNode> scrollOffset, |
| 92 const IntSize& clip, | 93 const IntSize& clip, |
| 93 const IntSize& bounds, | 94 const IntSize& bounds, |
| 94 bool userScrollableHorizontal, | 95 bool userScrollableHorizontal, |
| 95 bool userScrollableVertical, | 96 bool userScrollableVertical, |
| 96 MainThreadScrollingReasons mainThreadScrollingReasons) { | 97 MainThreadScrollingReasons mainThreadScrollingReasons) { |
| 97 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); | 98 DCHECK(!RuntimeEnabledFeatures::rootLayerScrollingEnabled()); |
| 98 if (auto* existingScroll = frameView.scroll()) { | 99 if (auto* existingScroll = frameView.scroll()) { |
| 100 auto existingReasons = existingScroll->mainThreadScrollingReasons(); |
| 99 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, | 101 existingScroll->update(std::move(parent), std::move(scrollOffset), clip, |
| 100 bounds, userScrollableHorizontal, | 102 bounds, userScrollableHorizontal, |
| 101 userScrollableVertical, mainThreadScrollingReasons); | 103 userScrollableVertical, mainThreadScrollingReasons); |
| 102 return false; | 104 return existingReasons != mainThreadScrollingReasons; |
| 103 } | 105 } |
| 104 frameView.setScroll(ScrollPaintPropertyNode::create( | 106 frameView.setScroll(ScrollPaintPropertyNode::create( |
| 105 std::move(parent), std::move(scrollOffset), clip, bounds, | 107 std::move(parent), std::move(scrollOffset), clip, bounds, |
| 106 userScrollableHorizontal, userScrollableVertical, | 108 userScrollableHorizontal, userScrollableVertical, |
| 107 mainThreadScrollingReasons)); | 109 mainThreadScrollingReasons)); |
| 108 return true; | 110 return true; |
| 109 } | 111 } |
| 110 | 112 |
| 113 MainThreadScrollingReasons mainThreadScrollingReasons( |
| 114 const FrameView& frameView, |
| 115 MainThreadScrollingReasons ancestorReasons) { |
| 116 auto reasons = ancestorReasons; |
| 117 if (!frameView.frame().settings()->getThreadedScrollingEnabled()) |
| 118 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; |
| 119 if (frameView.hasBackgroundAttachmentFixedObjects()) |
| 120 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; |
| 121 return reasons; |
| 122 } |
| 123 |
| 111 void PaintPropertyTreeBuilder::updateProperties( | 124 void PaintPropertyTreeBuilder::updateProperties( |
| 112 FrameView& frameView, | 125 FrameView& frameView, |
| 113 PaintPropertyTreeBuilderContext& context) { | 126 PaintPropertyTreeBuilderContext& context) { |
| 114 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 127 if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
| 115 // With root layer scrolling, the LayoutView (a LayoutObject) properties are | 128 // With root layer scrolling, the LayoutView (a LayoutObject) properties are |
| 116 // updated like other objects (see updatePropertiesAndContextForSelf and | 129 // updated like other objects (see updatePropertiesAndContextForSelf and |
| 117 // updatePropertiesAndContextForChildren) instead of needing LayoutView- | 130 // updatePropertiesAndContextForChildren) instead of needing LayoutView- |
| 118 // specific property updates here. | 131 // specific property updates here. |
| 119 context.current.paintOffset.moveBy(frameView.location()); | 132 context.current.paintOffset.moveBy(frameView.location()); |
| 120 context.current.renderingContextId = 0; | 133 context.current.renderingContextId = 0; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 149 context.forceSubtreeUpdate |= updateScrollTranslation( | 162 context.forceSubtreeUpdate |= updateScrollTranslation( |
| 150 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); | 163 frameView, frameView.preTranslation(), frameScroll, FloatPoint3D()); |
| 151 | 164 |
| 152 IntSize scrollClip = frameView.visibleContentSize(); | 165 IntSize scrollClip = frameView.visibleContentSize(); |
| 153 IntSize scrollBounds = frameView.contentsSize(); | 166 IntSize scrollBounds = frameView.contentsSize(); |
| 154 bool userScrollableHorizontal = | 167 bool userScrollableHorizontal = |
| 155 frameView.userInputScrollable(HorizontalScrollbar); | 168 frameView.userInputScrollable(HorizontalScrollbar); |
| 156 bool userScrollableVertical = | 169 bool userScrollableVertical = |
| 157 frameView.userInputScrollable(VerticalScrollbar); | 170 frameView.userInputScrollable(VerticalScrollbar); |
| 158 | 171 |
| 159 MainThreadScrollingReasons reasons = 0; | 172 auto ancestorReasons = |
| 160 if (!frameView.frame().settings()->getThreadedScrollingEnabled()) | 173 context.current.scroll->mainThreadScrollingReasons(); |
| 161 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; | 174 auto reasons = mainThreadScrollingReasons(frameView, ancestorReasons); |
| 162 if (frameView.hasBackgroundAttachmentFixedObjects()) { | 175 |
| 163 reasons |= | |
| 164 MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; | |
| 165 } | |
| 166 context.forceSubtreeUpdate |= updateScroll( | 176 context.forceSubtreeUpdate |= updateScroll( |
| 167 frameView, context.current.scroll, frameView.scrollTranslation(), | 177 frameView, context.current.scroll, frameView.scrollTranslation(), |
| 168 scrollClip, scrollBounds, userScrollableHorizontal, | 178 scrollClip, scrollBounds, userScrollableHorizontal, |
| 169 userScrollableVertical, reasons); | 179 userScrollableVertical, reasons); |
| 170 } else { | 180 } else { |
| 171 if (frameView.scrollTranslation() || frameView.scroll()) { | 181 if (frameView.scrollTranslation() || frameView.scroll()) { |
| 172 // Ensure pre-existing properties are cleared if there is no scrolling. | 182 // Ensure pre-existing properties are cleared if there is no scrolling. |
| 173 frameView.setScrollTranslation(nullptr); | 183 frameView.setScrollTranslation(nullptr); |
| 174 frameView.setScroll(nullptr); | 184 frameView.setScroll(nullptr); |
| 175 | 185 |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 if (properties && properties->svgLocalToBorderBoxTransform()) { | 737 if (properties && properties->svgLocalToBorderBoxTransform()) { |
| 728 context.current.transform = properties->svgLocalToBorderBoxTransform(); | 738 context.current.transform = properties->svgLocalToBorderBoxTransform(); |
| 729 context.current.shouldFlattenInheritedTransform = false; | 739 context.current.shouldFlattenInheritedTransform = false; |
| 730 context.current.renderingContextId = 0; | 740 context.current.renderingContextId = 0; |
| 731 } | 741 } |
| 732 // The paint offset is included in |transformToBorderBox| so SVG does not need | 742 // The paint offset is included in |transformToBorderBox| so SVG does not need |
| 733 // to handle paint offset internally. | 743 // to handle paint offset internally. |
| 734 context.current.paintOffset = LayoutPoint(); | 744 context.current.paintOffset = LayoutPoint(); |
| 735 } | 745 } |
| 736 | 746 |
| 737 MainThreadScrollingReasons mainScrollingReasons(const LayoutObject& object) { | 747 MainThreadScrollingReasons mainThreadScrollingReasons( |
| 738 MainThreadScrollingReasons reasons = 0; | 748 const LayoutObject& object, |
| 739 if (!object.document().settings()->getThreadedScrollingEnabled()) | 749 MainThreadScrollingReasons ancestorReasons) { |
| 740 reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; | 750 // The current main thread scrolling reasons implementation only changes |
| 741 // Checking for descendants in the layout tree has two downsides: | 751 // reasons at frame boundaries, so we can early-out when not at a LayoutView. |
| 742 // 1) There can be more descendants in layout order than in paint order (e.g., | 752 // TODO(pdr): Need to find a solution to the style-related main thread |
| 743 // fixed position objects). | 753 // scrolling reasons such as opacity and transform which violate this. |
| 744 // 2) Iterating overall all background attachment fixed objects for every | 754 if (!object.isLayoutView()) |
| 745 // scroll node can be slow, though there will be none in the common case. | 755 return ancestorReasons; |
| 746 const FrameView& frameView = *object.frameView(); | 756 return mainThreadScrollingReasons(*object.frameView(), ancestorReasons); |
| 747 if (frameView.hasBackgroundAttachmentFixedDescendants(object)) | |
| 748 reasons |= MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; | |
| 749 return reasons; | |
| 750 } | 757 } |
| 751 | 758 |
| 752 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( | 759 void PaintPropertyTreeBuilder::updateScrollAndScrollTranslation( |
| 753 const LayoutObject& object, | 760 const LayoutObject& object, |
| 754 PaintPropertyTreeBuilderContext& context) { | 761 PaintPropertyTreeBuilderContext& context) { |
| 755 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { | 762 if (object.needsPaintPropertyUpdate() || context.forceSubtreeUpdate) { |
| 756 bool needsScrollProperties = false; | 763 bool needsScrollProperties = false; |
| 757 if (object.hasOverflowClip()) { | 764 if (object.hasOverflowClip()) { |
| 758 auto mainThreadScrollingReasons = mainScrollingReasons(object); | 765 auto ancestorReasons = |
| 766 context.current.scroll->mainThreadScrollingReasons(); |
| 767 auto reasons = mainThreadScrollingReasons(object, ancestorReasons); |
| 768 bool scrollNodeNeededForMainThreadReasons = ancestorReasons != reasons; |
| 769 |
| 759 const LayoutBox& box = toLayoutBox(object); | 770 const LayoutBox& box = toLayoutBox(object); |
| 760 const auto* scrollableArea = box.getScrollableArea(); | 771 const auto* scrollableArea = box.getScrollableArea(); |
| 761 IntSize scrollOffset = box.scrolledContentOffset(); | 772 IntSize scrollOffset = box.scrolledContentOffset(); |
| 762 if (mainThreadScrollingReasons || !scrollOffset.isZero() || | 773 if (scrollNodeNeededForMainThreadReasons || !scrollOffset.isZero() || |
| 763 scrollableArea->scrollsOverflow()) { | 774 scrollableArea->scrollsOverflow()) { |
| 764 needsScrollProperties = true; | 775 needsScrollProperties = true; |
| 765 auto& properties = | 776 auto& properties = |
| 766 object.getMutableForPainting().ensurePaintProperties(); | 777 object.getMutableForPainting().ensurePaintProperties(); |
| 767 TransformationMatrix matrix = TransformationMatrix().translate( | 778 TransformationMatrix matrix = TransformationMatrix().translate( |
| 768 -scrollOffset.width(), -scrollOffset.height()); | 779 -scrollOffset.width(), -scrollOffset.height()); |
| 769 context.forceSubtreeUpdate |= properties.updateScrollTranslation( | 780 context.forceSubtreeUpdate |= properties.updateScrollTranslation( |
| 770 context.current.transform, matrix, FloatPoint3D(), | 781 context.current.transform, matrix, FloatPoint3D(), |
| 771 context.current.shouldFlattenInheritedTransform, | 782 context.current.shouldFlattenInheritedTransform, |
| 772 context.current.renderingContextId); | 783 context.current.renderingContextId); |
| 773 | 784 |
| 774 IntSize scrollClip = scrollableArea->visibleContentRect().size(); | 785 IntSize scrollClip = scrollableArea->visibleContentRect().size(); |
| 775 IntSize scrollBounds = scrollableArea->contentsSize(); | 786 IntSize scrollBounds = scrollableArea->contentsSize(); |
| 776 bool userScrollableHorizontal = | 787 bool userScrollableHorizontal = |
| 777 scrollableArea->userInputScrollable(HorizontalScrollbar); | 788 scrollableArea->userInputScrollable(HorizontalScrollbar); |
| 778 bool userScrollableVertical = | 789 bool userScrollableVertical = |
| 779 scrollableArea->userInputScrollable(VerticalScrollbar); | 790 scrollableArea->userInputScrollable(VerticalScrollbar); |
| 791 |
| 792 // Main thread scrolling reasons depend on their ancestor's reasons |
| 793 // so ensure the entire subtree is updated when reasons change. |
| 794 if (auto* existingScrollNode = properties.scroll()) { |
| 795 if (existingScrollNode->mainThreadScrollingReasons() != reasons) |
| 796 context.forceSubtreeUpdate = true; |
| 797 } |
| 798 |
| 780 context.forceSubtreeUpdate |= properties.updateScroll( | 799 context.forceSubtreeUpdate |= properties.updateScroll( |
| 781 context.current.scroll, properties.scrollTranslation(), scrollClip, | 800 context.current.scroll, properties.scrollTranslation(), scrollClip, |
| 782 scrollBounds, userScrollableHorizontal, userScrollableVertical, | 801 scrollBounds, userScrollableHorizontal, userScrollableVertical, |
| 783 mainThreadScrollingReasons); | 802 reasons); |
| 784 } | 803 } |
| 785 } | 804 } |
| 786 | 805 |
| 787 if (!needsScrollProperties) { | 806 if (!needsScrollProperties) { |
| 788 // Ensure pre-existing properties are cleared. | 807 // Ensure pre-existing properties are cleared. |
| 789 if (auto* properties = object.getMutableForPainting().paintProperties()) { | 808 if (auto* properties = object.getMutableForPainting().paintProperties()) { |
| 790 context.forceSubtreeUpdate |= properties->clearScrollTranslation(); | 809 context.forceSubtreeUpdate |= properties->clearScrollTranslation(); |
| 791 context.forceSubtreeUpdate |= properties->clearScroll(); | 810 context.forceSubtreeUpdate |= properties->clearScroll(); |
| 792 } | 811 } |
| 793 } | 812 } |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 updateOverflowClip(object, context); | 985 updateOverflowClip(object, context); |
| 967 updatePerspective(object, context); | 986 updatePerspective(object, context); |
| 968 updateSvgLocalToBorderBoxTransform(object, context); | 987 updateSvgLocalToBorderBoxTransform(object, context); |
| 969 updateScrollAndScrollTranslation(object, context); | 988 updateScrollAndScrollTranslation(object, context); |
| 970 updateOutOfFlowContext(object, context); | 989 updateOutOfFlowContext(object, context); |
| 971 | 990 |
| 972 context.forceSubtreeUpdate |= object.subtreeNeedsPaintPropertyUpdate(); | 991 context.forceSubtreeUpdate |= object.subtreeNeedsPaintPropertyUpdate(); |
| 973 } | 992 } |
| 974 | 993 |
| 975 } // namespace blink | 994 } // namespace blink |
| OLD | NEW |