OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/PaintInvalidator.h" | 5 #include "core/paint/PaintInvalidator.h" |
6 | 6 |
7 #include "core/editing/FrameSelection.h" | 7 #include "core/editing/FrameSelection.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" |
11 #include "core/layout/LayoutBlockFlow.h" | 11 #include "core/layout/LayoutBlockFlow.h" |
12 #include "core/layout/LayoutObject.h" | 12 #include "core/layout/LayoutObject.h" |
13 #include "core/layout/LayoutTable.h" | 13 #include "core/layout/LayoutTable.h" |
14 #include "core/layout/LayoutView.h" | 14 #include "core/layout/LayoutView.h" |
15 #include "core/layout/svg/SVGLayoutSupport.h" | 15 #include "core/layout/svg/SVGLayoutSupport.h" |
16 #include "core/paint/ObjectPaintProperties.h" | 16 #include "core/paint/ObjectPaintProperties.h" |
17 #include "core/paint/PaintLayer.h" | 17 #include "core/paint/PaintLayer.h" |
18 #include "core/paint/PaintLayerScrollableArea.h" | 18 #include "core/paint/PaintLayerScrollableArea.h" |
19 #include "core/paint/PaintPropertyTreeBuilder.h" | 19 #include "core/paint/PaintPropertyTreeBuilder.h" |
20 | 20 |
21 namespace blink { | 21 namespace blink { |
22 | 22 |
23 template <typename Rect> | |
23 static LayoutRect slowMapToVisualRectInAncestorSpace( | 24 static LayoutRect slowMapToVisualRectInAncestorSpace( |
24 const LayoutObject& object, | 25 const LayoutObject& object, |
25 const LayoutBoxModelObject& ancestor, | 26 const LayoutBoxModelObject& ancestor, |
26 const FloatRect& rect) { | 27 const Rect& rect) { |
27 if (object.isSVGChild()) { | 28 if (object.isSVGChild()) { |
28 LayoutRect result; | 29 LayoutRect result; |
29 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, rect, | 30 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, |
30 result); | 31 FloatRect(rect), result); |
31 return result; | 32 return result; |
32 } | 33 } |
33 | 34 |
34 LayoutRect result(rect); | 35 LayoutRect result(rect); |
35 if (object.isLayoutView()) | 36 if (object.isLayoutView()) |
36 toLayoutView(object).mapToVisualRectInAncestorSpace( | 37 toLayoutView(object).mapToVisualRectInAncestorSpace( |
37 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); | 38 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); |
38 else | 39 else |
39 object.mapToVisualRectInAncestorSpace(&ancestor, result); | 40 object.mapToVisualRectInAncestorSpace(&ancestor, result); |
40 return result; | 41 return result; |
41 } | 42 } |
42 | 43 |
43 // TODO(wangxianzhu): Combine this into | 44 // TODO(wangxianzhu): Combine this into |
44 // PaintInvalidator::mapLocalRectToBacking() when removing | 45 // PaintInvalidator::mapLocalRectToBacking() when removing |
45 // PaintInvalidationState. | 46 // PaintInvalidationState. |
47 template <typename Rect, typename Point> | |
pdr.
2017/01/18 17:57:00
Can you add the following comment here:
// This fu
Xianzhu
2017/01/18 18:21:06
Done.
| |
46 static LayoutRect mapLocalRectToPaintInvalidationBacking( | 48 static LayoutRect mapLocalRectToPaintInvalidationBacking( |
47 GeometryMapper& geometryMapper, | 49 GeometryMapper& geometryMapper, |
48 const LayoutObject& object, | 50 const LayoutObject& object, |
49 const FloatRect& localRect, | 51 const Rect& localRect, |
50 const PaintInvalidatorContext& context) { | 52 const PaintInvalidatorContext& context) { |
51 bool isSVGChild = object.isSVGChild(); | 53 bool isSVGChild = object.isSVGChild(); |
52 | 54 |
53 // TODO(wkorman): The flip below is required because visual rects are | 55 // TODO(wkorman): The flip below is required because visual rects are |
54 // currently in "physical coordinates with flipped block-flow direction" | 56 // currently in "physical coordinates with flipped block-flow direction" |
55 // (see LayoutBoxModelObject.h) but we need them to be in physical | 57 // (see LayoutBoxModelObject.h) but we need them to be in physical |
56 // coordinates. | 58 // coordinates. |
57 FloatRect rect = localRect; | 59 Rect rect = localRect; |
58 // Writing-mode flipping doesn't apply to non-root SVG. | 60 // Writing-mode flipping doesn't apply to non-root SVG. |
59 if (!isSVGChild) { | 61 if (!isSVGChild) { |
60 if (object.isBox()) { | 62 if (object.isBox()) { |
61 toLayoutBox(object).flipForWritingMode(rect); | 63 toLayoutBox(object).flipForWritingMode(rect); |
62 } else if (!(context.forcedSubtreeInvalidationFlags & | 64 } else if (!(context.forcedSubtreeInvalidationFlags & |
63 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { | 65 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { |
64 // For SPv2 and the GeometryMapper path, we also need to convert the rect | 66 // For SPv2 and the GeometryMapper path, we also need to convert the rect |
65 // for non-boxes into physical coordinates before applying paint offset. | 67 // for non-boxes into physical coordinates before applying paint offset. |
66 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires | 68 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires |
67 // physical coordinates for boxes, but "physical coordinates with flipped | 69 // physical coordinates for boxes, but "physical coordinates with flipped |
68 // block-flow direction" for non-boxes for which we don't need to flip.) | 70 // block-flow direction" for non-boxes for which we don't need to flip.) |
69 // TODO(wangxianzhu): Avoid containingBlock(). | 71 // TODO(wangxianzhu): Avoid containingBlock(). |
70 object.containingBlock()->flipForWritingMode(rect); | 72 object.containingBlock()->flipForWritingMode(rect); |
71 } | 73 } |
72 } | 74 } |
73 | 75 |
74 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 76 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
75 // In SPv2, visual rects are in the space of their local transform node. | 77 // In SPv2, visual rects are in the space of their local transform node. |
76 // For SVG, the input rect is in local SVG coordinates in which paint | 78 // For SVG, the input rect is in local SVG coordinates in which paint |
77 // offset doesn't apply. | 79 // offset doesn't apply. |
78 if (!isSVGChild) | 80 if (!isSVGChild) |
79 rect.moveBy(FloatPoint(object.paintOffset())); | 81 rect.moveBy(Point(object.paintOffset())); |
80 // Use enclosingIntRect to ensure the final visual rect will cover the | 82 // Use enclosingIntRect to ensure the final visual rect will cover the |
81 // rect in source coordinates no matter if the painting will use pixel | 83 // rect in source coordinates no matter if the painting will use pixel |
82 // snapping. | 84 // snapping. |
83 return LayoutRect(enclosingIntRect(rect)); | 85 return LayoutRect(enclosingIntRect(rect)); |
84 } | 86 } |
85 | 87 |
86 LayoutRect result; | 88 LayoutRect result; |
87 if (context.forcedSubtreeInvalidationFlags & | 89 if (context.forcedSubtreeInvalidationFlags & |
88 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { | 90 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
89 result = slowMapToVisualRectInAncestorSpace( | 91 result = slowMapToVisualRectInAncestorSpace( |
90 object, *context.paintInvalidationContainer, rect); | 92 object, *context.paintInvalidationContainer, rect); |
91 } else if (object == context.paintInvalidationContainer) { | 93 } else if (object == context.paintInvalidationContainer) { |
92 result = LayoutRect(rect); | 94 result = LayoutRect(rect); |
93 } else { | 95 } else { |
94 // For non-root SVG, the input rect is in local SVG coordinates in which | 96 // For non-root SVG, the input rect is in local SVG coordinates in which |
95 // paint offset doesn't apply. | 97 // paint offset doesn't apply. |
96 if (!isSVGChild) { | 98 if (!isSVGChild) { |
97 rect.moveBy(FloatPoint(object.paintOffset())); | 99 rect.moveBy(Point(object.paintOffset())); |
98 // Use enclosingIntRect to ensure the final visual rect will cover the | 100 // Use enclosingIntRect to ensure the final visual rect will cover the |
99 // rect in source coordinates no matter if the painting will use pixel | 101 // rect in source coordinates no matter if the painting will use pixel |
100 // snapping. | 102 // snapping. |
101 rect = enclosingIntRect(rect); | 103 rect = Rect(enclosingIntRect(rect)); |
102 } | 104 } |
103 | 105 |
104 const auto* containerContentsProperties = | 106 const auto* containerContentsProperties = |
105 context.paintInvalidationContainer->paintProperties() | 107 context.paintInvalidationContainer->paintProperties() |
106 ->contentsProperties(); | 108 ->contentsProperties(); |
107 if (context.treeBuilderContext.current.transform == | 109 if (context.treeBuilderContext.current.transform == |
108 containerContentsProperties->transform() && | 110 containerContentsProperties->transform() && |
109 context.treeBuilderContext.current.clip == | 111 context.treeBuilderContext.current.clip == |
110 containerContentsProperties->clip()) { | 112 containerContentsProperties->clip()) { |
111 result = LayoutRect(rect); | 113 result = LayoutRect(rect); |
112 } else { | 114 } else { |
113 PropertyTreeState currentTreeState( | 115 PropertyTreeState currentTreeState( |
114 context.treeBuilderContext.current.transform, | 116 context.treeBuilderContext.current.transform, |
115 context.treeBuilderContext.current.clip, nullptr, nullptr); | 117 context.treeBuilderContext.current.clip, nullptr, nullptr); |
116 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( | 118 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( |
117 rect, currentTreeState, *containerContentsProperties)); | 119 FloatRect(rect), currentTreeState, *containerContentsProperties)); |
118 } | 120 } |
119 | 121 |
120 // Convert the result to the container's contents space. | 122 // Convert the result to the container's contents space. |
121 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | 123 result.moveBy(-context.paintInvalidationContainer->paintOffset()); |
122 } | 124 } |
123 | 125 |
124 object.adjustVisualRectForRasterEffects(result); | 126 object.adjustVisualRectForRasterEffects(result); |
125 | 127 |
126 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 128 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
127 *context.paintInvalidationContainer, result); | 129 *context.paintInvalidationContainer, result); |
128 | 130 |
129 return result; | 131 return result; |
130 } | 132 } |
131 | 133 |
132 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( | 134 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( |
133 const LayoutObject& object, | 135 const LayoutObject& object, |
134 LayoutRect& rect) const { | 136 LayoutRect& rect) const { |
135 GeometryMapper geometryMapper; | 137 GeometryMapper geometryMapper; |
136 rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, | 138 rect = blink::mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( |
137 FloatRect(rect), *this); | 139 geometryMapper, object, rect, *this); |
138 } | 140 } |
139 | 141 |
140 LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( | 142 inline LayoutRect PaintInvalidator::computeVisualRectInBacking( |
pdr.
2017/01/18 17:57:00
Could you split the inline changes into a separate
Xianzhu
2017/01/18 18:21:06
Done.
| |
141 const LayoutObject& object, | 143 const LayoutObject& object, |
142 const FloatRect& localRect, | |
143 const PaintInvalidatorContext& context) { | 144 const PaintInvalidatorContext& context) { |
144 return blink::mapLocalRectToPaintInvalidationBacking(m_geometryMapper, object, | 145 if (object.isSVGChild()) { |
145 localRect, context); | 146 FloatRect localRect = SVGLayoutSupport::localVisualRect(object); |
147 return mapLocalRectToPaintInvalidationBacking<FloatRect, FloatPoint>( | |
148 m_geometryMapper, object, localRect, context); | |
149 } | |
150 return mapLocalRectToPaintInvalidationBacking<LayoutRect, LayoutPoint>( | |
151 m_geometryMapper, object, object.localVisualRect(), context); | |
146 } | 152 } |
147 | 153 |
148 LayoutRect PaintInvalidator::computeVisualRectInBacking( | 154 inline LayoutPoint PaintInvalidator::computeLocationInBacking( |
149 const LayoutObject& object, | |
150 const PaintInvalidatorContext& context) { | |
151 FloatRect localRect; | |
152 if (object.isSVGChild()) | |
153 localRect = SVGLayoutSupport::localVisualRect(object); | |
154 else | |
155 localRect = FloatRect(object.localVisualRect()); | |
156 | |
157 return mapLocalRectToPaintInvalidationBacking(object, localRect, context); | |
158 } | |
159 | |
160 LayoutPoint PaintInvalidator::computeLocationInBacking( | |
161 const LayoutObject& object, | 155 const LayoutObject& object, |
162 const PaintInvalidatorContext& context) { | 156 const PaintInvalidatorContext& context) { |
163 // Use visual rect location for LayoutTexts because it suffices to check | 157 // Use visual rect location for LayoutTexts because it suffices to check |
164 // visual rect change for layout caused invalidation. | 158 // visual rect change for layout caused invalidation. |
165 if (object.isText()) | 159 if (object.isText()) |
166 return context.newVisualRect.location(); | 160 return context.newVisualRect.location(); |
167 | 161 |
168 LayoutPoint point; | 162 LayoutPoint point; |
169 if (object != context.paintInvalidationContainer) { | 163 if (object != context.paintInvalidationContainer) { |
170 point.moveBy(object.paintOffset()); | 164 point.moveBy(object.paintOffset()); |
(...skipping 18 matching lines...) Expand all Loading... | |
189 if (context.paintInvalidationContainer->layer()->groupedMapping()) { | 183 if (context.paintInvalidationContainer->layer()->groupedMapping()) { |
190 FloatPoint floatPoint(point); | 184 FloatPoint floatPoint(point); |
191 PaintLayer::mapPointInPaintInvalidationContainerToBacking( | 185 PaintLayer::mapPointInPaintInvalidationContainerToBacking( |
192 *context.paintInvalidationContainer, floatPoint); | 186 *context.paintInvalidationContainer, floatPoint); |
193 point = LayoutPoint(floatPoint); | 187 point = LayoutPoint(floatPoint); |
194 } | 188 } |
195 | 189 |
196 return point; | 190 return point; |
197 } | 191 } |
198 | 192 |
199 void PaintInvalidator::updatePaintingLayer(const LayoutObject& object, | 193 inline void PaintInvalidator::updatePaintingLayer( |
200 PaintInvalidatorContext& context) { | 194 const LayoutObject& object, |
195 PaintInvalidatorContext& context) { | |
201 if (object.hasLayer() && | 196 if (object.hasLayer() && |
202 toLayoutBoxModelObject(object).hasSelfPaintingLayer()) { | 197 toLayoutBoxModelObject(object).hasSelfPaintingLayer()) { |
203 context.paintingLayer = toLayoutBoxModelObject(object).layer(); | 198 context.paintingLayer = toLayoutBoxModelObject(object).layer(); |
204 } else if (object.isColumnSpanAll() || | 199 } else if (object.isColumnSpanAll() || |
205 (object.isFloating() && !object.parent()->isLayoutBlock())) { | 200 (object.isFloating() && !object.parent()->isLayoutBlock())) { |
206 // See LayoutObject::paintingLayer() for the special-cases of floating under | 201 // See LayoutObject::paintingLayer() for the special-cases of floating under |
207 // inline and multicolumn. | 202 // inline and multicolumn. |
208 context.paintingLayer = object.paintingLayer(); | 203 context.paintingLayer = object.paintingLayer(); |
209 } | 204 } |
210 | 205 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 m_treeBuilderContext.current = m_savedContext; | 255 m_treeBuilderContext.current = m_savedContext; |
261 } | 256 } |
262 | 257 |
263 private: | 258 private: |
264 PaintPropertyTreeBuilderContext& m_treeBuilderContext; | 259 PaintPropertyTreeBuilderContext& m_treeBuilderContext; |
265 PaintPropertyTreeBuilderContext::ContainingBlockContext m_savedContext; | 260 PaintPropertyTreeBuilderContext::ContainingBlockContext m_savedContext; |
266 }; | 261 }; |
267 | 262 |
268 } // namespace | 263 } // namespace |
269 | 264 |
270 void PaintInvalidator::updateContext(const LayoutObject& object, | 265 inline void PaintInvalidator::updateContext(const LayoutObject& object, |
271 PaintInvalidatorContext& context) { | 266 PaintInvalidatorContext& context) { |
272 Optional<ScopedUndoFrameViewContentClipAndScroll> | 267 Optional<ScopedUndoFrameViewContentClipAndScroll> |
273 undoFrameViewContentClipAndScroll; | 268 undoFrameViewContentClipAndScroll; |
274 | 269 |
275 if (object.isPaintInvalidationContainer()) { | 270 if (object.isPaintInvalidationContainer()) { |
276 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); | 271 context.paintInvalidationContainer = toLayoutBoxModelObject(&object); |
277 if (object.styleRef().isStackingContext()) | 272 if (object.styleRef().isStackingContext()) |
278 context.paintInvalidationContainerForStackedContents = | 273 context.paintInvalidationContainerForStackedContents = |
279 toLayoutBoxModelObject(&object); | 274 toLayoutBoxModelObject(&object); |
280 } else if (object.isLayoutView()) { | 275 } else if (object.isLayoutView()) { |
281 // paintInvalidationContainerForStackedContents is only for stacked | 276 // paintInvalidationContainerForStackedContents is only for stacked |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 447 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
453 } | 448 } |
454 | 449 |
455 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 450 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
456 for (auto target : m_pendingDelayedPaintInvalidations) | 451 for (auto target : m_pendingDelayedPaintInvalidations) |
457 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 452 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
458 PaintInvalidationDelayedFull); | 453 PaintInvalidationDelayedFull); |
459 } | 454 } |
460 | 455 |
461 } // namespace blink | 456 } // namespace blink |
OLD | NEW |