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

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilder.cpp

Issue 2619393002: Rewrite how paint properties are built with bg:fixed main thread scrolling (Closed)
Patch Set: Created 3 years, 11 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 | « no previous file | third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698