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 static LayoutRect slowMapToVisualRectInAncestorSpace( | 23 static LayoutRect slowMapToVisualRectInAncestorSpace( |
24 const LayoutObject& object, | 24 const LayoutObject& object, |
25 const LayoutBoxModelObject& ancestor, | 25 const LayoutBoxModelObject& ancestor, |
26 const FloatRect& rect) { | 26 const LayoutRect& rect) { |
27 if (object.isSVGChild()) { | 27 if (object.isSVGChild()) { |
28 LayoutRect result; | 28 LayoutRect result; |
29 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, rect, | 29 SVGLayoutSupport::mapToVisualRectInAncestorSpace(object, &ancestor, |
30 result); | 30 FloatRect(rect), result); |
31 return result; | 31 return result; |
32 } | 32 } |
33 | 33 |
34 LayoutRect result(rect); | 34 LayoutRect result(rect); |
pdr.
2017/01/18 02:31:19
(Just curious, not needed for this patch)
Do these
Xianzhu
2017/01/18 06:23:02
Tested and found that "LayoutRect&" is better than
| |
35 if (object.isLayoutView()) | 35 if (object.isLayoutView()) |
36 toLayoutView(object).mapToVisualRectInAncestorSpace( | 36 toLayoutView(object).mapToVisualRectInAncestorSpace( |
37 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); | 37 &ancestor, result, InputIsInFrameCoordinates, DefaultVisualRectFlags); |
38 else | 38 else |
39 object.mapToVisualRectInAncestorSpace(&ancestor, result); | 39 object.mapToVisualRectInAncestorSpace(&ancestor, result); |
40 return result; | 40 return result; |
41 } | 41 } |
42 | 42 |
43 template <typename Rect> | |
44 static LayoutRect mapLocalRectToPaintInvalidationContainerUsingPaintProperties( | |
pdr.
2017/01/18 02:31:18
Nit: does "UsingPaintProperties" add information?
| |
45 GeometryMapper& geometryMapper, | |
46 const Rect& localRect, | |
47 const PaintInvalidatorContext& context) { | |
48 const auto* containerContentsProperties = | |
49 context.paintInvalidationContainer->paintProperties() | |
50 ->contentsProperties(); | |
51 LayoutRect result; | |
52 if (context.treeBuilderContext.current.transform == | |
53 containerContentsProperties->transform() && | |
54 context.treeBuilderContext.current.clip == | |
55 containerContentsProperties->clip()) { | |
56 result = LayoutRect(localRect); | |
57 } else { | |
58 PropertyTreeState currentTreeState( | |
59 context.treeBuilderContext.current.transform, | |
60 context.treeBuilderContext.current.clip, nullptr, nullptr); | |
61 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( | |
62 FloatRect(localRect), currentTreeState, *containerContentsProperties)); | |
63 } | |
64 | |
65 // Convert the result into the container's contents space. | |
66 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | |
67 return result; | |
68 } | |
69 | |
43 // TODO(wangxianzhu): Combine this into | 70 // TODO(wangxianzhu): Combine this into |
44 // PaintInvalidator::mapLocalRectToBacking() when removing | 71 // PaintInvalidator::mapLocalRectToBacking() when removing |
45 // PaintInvalidationState. | 72 // PaintInvalidationState. |
46 static LayoutRect mapLocalRectToPaintInvalidationBacking( | 73 static LayoutRect mapLocalRectToPaintInvalidationBacking( |
47 GeometryMapper& geometryMapper, | 74 GeometryMapper& geometryMapper, |
48 const LayoutObject& object, | 75 const LayoutObject& object, |
49 const FloatRect& localRect, | 76 const LayoutRect& localRect, |
50 const PaintInvalidatorContext& context) { | 77 const PaintInvalidatorContext& context) { |
78 // SVG children may use this path when mapping selection rects. | |
51 bool isSVGChild = object.isSVGChild(); | 79 bool isSVGChild = object.isSVGChild(); |
52 | 80 |
53 // TODO(wkorman): The flip below is required because visual rects are | 81 // TODO(wkorman): The flip below is required because visual rects are |
54 // currently in "physical coordinates with flipped block-flow direction" | 82 // currently in "physical coordinates with flipped block-flow direction" |
55 // (see LayoutBoxModelObject.h) but we need them to be in physical | 83 // (see LayoutBoxModelObject.h) but we need them to be in physical |
56 // coordinates. | 84 // coordinates. |
57 FloatRect rect = localRect; | 85 LayoutRect rect = localRect; |
58 // Writing-mode flipping doesn't apply to non-root SVG. | 86 // Writing-mode flipping doesn't apply to non-root SVG. |
59 if (!isSVGChild) { | 87 if (!isSVGChild) { |
60 if (object.isBox()) { | 88 if (object.isBox()) { |
61 toLayoutBox(object).flipForWritingMode(rect); | 89 toLayoutBox(object).flipForWritingMode(rect); |
62 } else if (!(context.forcedSubtreeInvalidationFlags & | 90 } else if (!(context.forcedSubtreeInvalidationFlags & |
63 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { | 91 PaintInvalidatorContext::ForcedSubtreeSlowPathRect)) { |
64 // For SPv2 and the GeometryMapper path, we also need to convert the rect | 92 // For SPv2 and the GeometryMapper path, we also need to convert the rect |
65 // for non-boxes into physical coordinates before applying paint offset. | 93 // for non-boxes into physical coordinates before applying paint offset. |
66 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires | 94 // (Otherwise we'll call mapToVisualrectInAncestorSpace() which requires |
67 // physical coordinates for boxes, but "physical coordinates with flipped | 95 // physical coordinates for boxes, but "physical coordinates with flipped |
68 // block-flow direction" for non-boxes for which we don't need to flip.) | 96 // block-flow direction" for non-boxes for which we don't need to flip.) |
69 // TODO(wangxianzhu): Avoid containingBlock(). | 97 // TODO(wangxianzhu): Avoid containingBlock(). |
70 object.containingBlock()->flipForWritingMode(rect); | 98 object.containingBlock()->flipForWritingMode(rect); |
71 } | 99 } |
72 } | 100 } |
73 | 101 |
74 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 102 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
75 // In SPv2, visual rects are in the space of their local transform node. | 103 // 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 | 104 // For SVG, the input rect is in local SVG coordinates in which paint |
77 // offset doesn't apply. | 105 // offset doesn't apply. |
78 if (!isSVGChild) | 106 if (!isSVGChild) |
79 rect.moveBy(FloatPoint(object.paintOffset())); | 107 rect.moveBy(object.paintOffset()); |
80 // Use enclosingIntRect to ensure the final visual rect will cover the | 108 // Use enclosingIntRect to ensure the final visual rect will cover the |
81 // rect in source coordinates no matter if the painting will use pixel | 109 // rect in source coordinates no matter if the painting will use pixel |
82 // snapping. | 110 // snapping. |
83 return LayoutRect(enclosingIntRect(rect)); | 111 return LayoutRect(enclosingIntRect(rect)); |
84 } | 112 } |
85 | 113 |
86 LayoutRect result; | 114 LayoutRect result; |
87 if (context.forcedSubtreeInvalidationFlags & | 115 if (context.forcedSubtreeInvalidationFlags & |
88 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { | 116 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { |
89 result = slowMapToVisualRectInAncestorSpace( | 117 result = slowMapToVisualRectInAncestorSpace( |
90 object, *context.paintInvalidationContainer, rect); | 118 object, *context.paintInvalidationContainer, rect); |
91 } else if (object == context.paintInvalidationContainer) { | 119 } else if (object == context.paintInvalidationContainer) { |
92 result = LayoutRect(rect); | 120 result = LayoutRect(rect); |
93 } else { | 121 } else { |
94 // For non-root SVG, the input rect is in local SVG coordinates in which | 122 // For non-root SVG, the input rect is in local SVG coordinates in which |
95 // paint offset doesn't apply. | 123 // paint offset doesn't apply. |
96 if (!isSVGChild) { | 124 if (!isSVGChild) { |
97 rect.moveBy(FloatPoint(object.paintOffset())); | 125 rect.moveBy(object.paintOffset()); |
98 // Use enclosingIntRect to ensure the final visual rect will cover the | 126 // Use enclosingIntRect to ensure the final visual rect will cover the |
99 // rect in source coordinates no matter if the painting will use pixel | 127 // rect in source coordinates no matter if the painting will use pixel |
100 // snapping. | 128 // snapping. |
101 rect = enclosingIntRect(rect); | 129 rect = LayoutRect(enclosingIntRect(rect)); |
102 } | 130 } |
103 | 131 |
104 const auto* containerContentsProperties = | 132 result = mapLocalRectToPaintInvalidationContainerUsingPaintProperties( |
105 context.paintInvalidationContainer->paintProperties() | 133 geometryMapper, rect, context); |
106 ->contentsProperties(); | |
107 if (context.treeBuilderContext.current.transform == | |
108 containerContentsProperties->transform() && | |
109 context.treeBuilderContext.current.clip == | |
110 containerContentsProperties->clip()) { | |
111 result = LayoutRect(rect); | |
112 } else { | |
113 PropertyTreeState currentTreeState( | |
114 context.treeBuilderContext.current.transform, | |
115 context.treeBuilderContext.current.clip, nullptr, nullptr); | |
116 result = LayoutRect(geometryMapper.sourceToDestinationVisualRect( | |
117 rect, currentTreeState, *containerContentsProperties)); | |
118 } | |
119 | |
120 // Convert the result to the container's contents space. | |
121 result.moveBy(-context.paintInvalidationContainer->paintOffset()); | |
122 } | 134 } |
123 | 135 |
124 object.adjustVisualRectForRasterEffects(result); | 136 object.adjustVisualRectForRasterEffects(result); |
137 | |
138 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | |
139 *context.paintInvalidationContainer, result); | |
140 return result; | |
141 } | |
142 | |
143 // TODO(wangxianzhu): Combine this into | |
144 // PaintInvalidator::mapLocalRectToBacking() when removing | |
145 // PaintInvalidationState. | |
146 static LayoutRect mapSVGLocalRectToPaintInvalidationBacking( | |
pdr.
2017/01/18 02:31:19
I like the perf benefit here, but I don't like how
Xianzhu
2017/01/18 06:23:02
Good idea. Done.
| |
147 GeometryMapper& geometryMapper, | |
148 const LayoutObject& object, | |
149 const FloatRect& localRect, | |
150 const PaintInvalidatorContext& context) { | |
151 DCHECK(object.isSVGChild()); | |
152 | |
153 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | |
154 // In SPv2, visual rects are in the space of their local transform node. | |
155 // Use enclosingIntRect to ensure the final visual rect will cover the | |
156 // rect in source coordinates no matter if the painting will use pixel | |
157 // snapping. | |
158 return LayoutRect(enclosingIntRect(localRect)); | |
159 } | |
160 | |
161 LayoutRect result; | |
162 if (context.forcedSubtreeInvalidationFlags & | |
163 PaintInvalidatorContext::ForcedSubtreeSlowPathRect) { | |
164 SVGLayoutSupport::mapToVisualRectInAncestorSpace( | |
165 object, context.paintInvalidationContainer, localRect, result); | |
166 } else if (object == context.paintInvalidationContainer) { | |
167 result = LayoutRect(localRect); | |
168 } else { | |
169 result = mapLocalRectToPaintInvalidationContainerUsingPaintProperties( | |
170 geometryMapper, localRect, context); | |
171 } | |
172 | |
173 object.adjustVisualRectForRasterEffects(result); | |
125 | 174 |
126 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 175 PaintLayer::mapRectInPaintInvalidationContainerToBacking( |
127 *context.paintInvalidationContainer, result); | 176 *context.paintInvalidationContainer, result); |
128 | 177 |
129 return result; | 178 return result; |
130 } | 179 } |
131 | 180 |
132 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( | 181 void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking( |
133 const LayoutObject& object, | 182 const LayoutObject& object, |
134 LayoutRect& rect) const { | 183 LayoutRect& rect) const { |
135 GeometryMapper geometryMapper; | 184 GeometryMapper geometryMapper; |
136 rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, | 185 rect = blink::mapLocalRectToPaintInvalidationBacking(geometryMapper, object, |
137 FloatRect(rect), *this); | 186 rect, *this); |
138 } | |
139 | |
140 LayoutRect PaintInvalidator::mapLocalRectToPaintInvalidationBacking( | |
141 const LayoutObject& object, | |
142 const FloatRect& localRect, | |
143 const PaintInvalidatorContext& context) { | |
144 return blink::mapLocalRectToPaintInvalidationBacking(m_geometryMapper, object, | |
145 localRect, context); | |
146 } | 187 } |
147 | 188 |
148 LayoutRect PaintInvalidator::computeVisualRectInBacking( | 189 LayoutRect PaintInvalidator::computeVisualRectInBacking( |
149 const LayoutObject& object, | 190 const LayoutObject& object, |
150 const PaintInvalidatorContext& context) { | 191 const PaintInvalidatorContext& context) { |
151 FloatRect localRect; | 192 if (object.isSVGChild()) { |
152 if (object.isSVGChild()) | 193 return mapSVGLocalRectToPaintInvalidationBacking( |
153 localRect = SVGLayoutSupport::localVisualRect(object); | 194 m_geometryMapper, object, SVGLayoutSupport::localVisualRect(object), |
154 else | 195 context); |
155 localRect = FloatRect(object.localVisualRect()); | 196 } |
156 | 197 return mapLocalRectToPaintInvalidationBacking( |
157 return mapLocalRectToPaintInvalidationBacking(object, localRect, context); | 198 m_geometryMapper, object, object.localVisualRect(), context); |
158 } | 199 } |
159 | 200 |
160 LayoutPoint PaintInvalidator::computeLocationInBacking( | 201 LayoutPoint PaintInvalidator::computeLocationInBacking( |
161 const LayoutObject& object, | 202 const LayoutObject& object, |
162 const PaintInvalidatorContext& context) { | 203 const PaintInvalidatorContext& context) { |
163 // Use visual rect location for LayoutTexts because it suffices to check | 204 // Use visual rect location for LayoutTexts because it suffices to check |
164 // visual rect change for layout caused invalidation. | 205 // visual rect change for layout caused invalidation. |
165 if (object.isText()) | 206 if (object.isText()) |
166 return context.newVisualRect.location(); | 207 return context.newVisualRect.location(); |
167 | 208 |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; | 493 PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; |
453 } | 494 } |
454 | 495 |
455 void PaintInvalidator::processPendingDelayedPaintInvalidations() { | 496 void PaintInvalidator::processPendingDelayedPaintInvalidations() { |
456 for (auto target : m_pendingDelayedPaintInvalidations) | 497 for (auto target : m_pendingDelayedPaintInvalidations) |
457 target->getMutableForPainting().setShouldDoFullPaintInvalidation( | 498 target->getMutableForPainting().setShouldDoFullPaintInvalidation( |
458 PaintInvalidationDelayedFull); | 499 PaintInvalidationDelayedFull); |
459 } | 500 } |
460 | 501 |
461 } // namespace blink | 502 } // namespace blink |
OLD | NEW |