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 "platform/graphics/paint/GeometryMapper.h" | 5 #include "platform/graphics/paint/GeometryMapper.h" |
6 | 6 |
7 #include "platform/RuntimeEnabledFeatures.h" | 7 #include "platform/RuntimeEnabledFeatures.h" |
8 #include "platform/geometry/LayoutRect.h" | 8 #include "platform/geometry/LayoutRect.h" |
9 | 9 |
10 namespace blink { | 10 namespace blink { |
11 | 11 |
12 FloatClipRect GeometryMapper::sourceToDestinationVisualRect( | 12 const FloatClipRect& GeometryMapper::sourceToDestinationVisualRect( |
13 const FloatRect& rect, | 13 const FloatRect& rect, |
14 const PropertyTreeState& sourceState, | 14 const PropertyTreeState& sourceState, |
15 const PropertyTreeState& destinationState) { | 15 const PropertyTreeState& destinationState) { |
16 bool success = false; | 16 bool success = false; |
17 FloatClipRect result = sourceToDestinationVisualRectInternal( | 17 const FloatClipRect& result = sourceToDestinationVisualRectInternal( |
18 rect, sourceState, destinationState, success); | 18 rect, sourceState, destinationState, success); |
19 DCHECK(success); | 19 DCHECK(success); |
20 return result; | 20 return result; |
21 } | 21 } |
22 | 22 |
23 FloatClipRect GeometryMapper::sourceToDestinationVisualRectInternal( | 23 const FloatClipRect& GeometryMapper::sourceToDestinationVisualRectInternal( |
24 const FloatRect& rect, | 24 const FloatRect& rect, |
25 const PropertyTreeState& sourceState, | 25 const PropertyTreeState& sourceState, |
26 const PropertyTreeState& destinationState, | 26 const PropertyTreeState& destinationState, |
27 bool& success) { | 27 bool& success) { |
28 FloatClipRect result = localToAncestorVisualRectInternal( | 28 const FloatClipRect& result = localToAncestorVisualRectInternal( |
29 rect, sourceState, destinationState, success); | 29 rect, sourceState, destinationState, success); |
30 // Success if destinationState is an ancestor state. | 30 // Success if destinationState is an ancestor state. |
31 if (success) | 31 if (success) |
32 return result; | 32 return result; |
33 | |
Xianzhu
2017/03/10 00:06:49
Nit: Keep the blank line.
chrishtr
2017/03/10 01:45:29
Done.
| |
34 // Otherwise first map to the lowest common ancestor, then map to destination. | 33 // Otherwise first map to the lowest common ancestor, then map to destination. |
35 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( | 34 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( |
36 sourceState.transform(), destinationState.transform()); | 35 sourceState.transform(), destinationState.transform()); |
37 DCHECK(lcaTransform); | 36 DCHECK(lcaTransform); |
38 | 37 |
39 // Assume that the clip of destinationState is an ancestor of the clip of | 38 // Assume that the clip of destinationState is an ancestor of the clip of |
40 // sourceState and is under the space of lcaTransform. Otherwise | 39 // sourceState and is under the space of lcaTransform. Otherwise |
41 // localToAncestorVisualRect() will fail. | 40 // localToAncestorVisualRect() will fail. |
42 PropertyTreeState lcaState = destinationState; | 41 PropertyTreeState lcaState = destinationState; |
43 lcaState.setTransform(lcaTransform); | 42 lcaState.setTransform(lcaTransform); |
44 | 43 |
45 result = | 44 const FloatClipRect& result2 = |
46 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success); | 45 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success); |
47 if (!success) | 46 if (!success) |
48 return result; | 47 return result2; |
49 if (!result.isInfinite()) { | 48 if (!result2.isInfinite()) { |
50 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, | 49 FloatRect rect = result2.rect(); |
51 destinationState.transform()); | 50 ancestorToLocalRect(lcaTransform, destinationState.transform(), rect); |
52 result.setRect(final); | 51 m_tempRect.setRect(rect); |
52 if (result2.hasRadius()) | |
53 m_tempRect.setHasRadius(); | |
54 return m_tempRect; | |
53 } | 55 } |
54 return result; | 56 return result2; |
55 } | 57 } |
56 | 58 |
57 FloatRect GeometryMapper::sourceToDestinationRect( | 59 void GeometryMapper::sourceToDestinationRect( |
58 const FloatRect& rect, | |
59 const TransformPaintPropertyNode* sourceTransformNode, | 60 const TransformPaintPropertyNode* sourceTransformNode, |
60 const TransformPaintPropertyNode* destinationTransformNode) { | 61 const TransformPaintPropertyNode* destinationTransformNode, |
62 FloatRect& rect) { | |
61 bool success = false; | 63 bool success = false; |
62 FloatRect result = localToAncestorRectInternal( | 64 localToAncestorRectInternal(sourceTransformNode, destinationTransformNode, |
63 rect, sourceTransformNode, destinationTransformNode, success); | 65 rect, success); |
64 // Success if destinationTransformNode is an ancestor of sourceTransformNode. | 66 // Success if destinationTransformNode is an ancestor of sourceTransformNode. |
65 if (success) | 67 if (success) |
66 return result; | 68 return; |
67 | 69 |
68 // Otherwise first map to the least common ancestor, then map to destination. | 70 // Otherwise first map to the least common ancestor, then map to destination. |
69 const TransformPaintPropertyNode* lcaTransform = | 71 const TransformPaintPropertyNode* lcaTransform = |
70 lowestCommonAncestor(sourceTransformNode, destinationTransformNode); | 72 lowestCommonAncestor(sourceTransformNode, destinationTransformNode); |
71 DCHECK(lcaTransform); | 73 DCHECK(lcaTransform); |
72 | 74 |
73 FloatRect lcaRect = | 75 localToAncestorRect(sourceTransformNode, lcaTransform, rect); |
74 localToAncestorRect(rect, sourceTransformNode, lcaTransform); | 76 ancestorToLocalRect(lcaTransform, destinationTransformNode, rect); |
75 return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode); | |
76 } | 77 } |
77 | 78 |
78 FloatClipRect GeometryMapper::localToAncestorVisualRect( | 79 const FloatClipRect& GeometryMapper::localToAncestorVisualRect( |
79 const FloatRect& rect, | 80 const FloatRect& rect, |
80 const PropertyTreeState& localState, | 81 const PropertyTreeState& localState, |
81 const PropertyTreeState& ancestorState) { | 82 const PropertyTreeState& ancestorState) { |
82 bool success = false; | 83 bool success = false; |
83 FloatClipRect result = localToAncestorVisualRectInternal( | 84 const FloatClipRect& result = localToAncestorVisualRectInternal( |
84 rect, localState, ancestorState, success); | 85 rect, localState, ancestorState, success); |
85 DCHECK(success); | 86 DCHECK(success); |
86 return result; | 87 return result; |
87 } | 88 } |
88 | 89 |
89 FloatClipRect GeometryMapper::localToAncestorVisualRectInternal( | 90 const FloatClipRect& GeometryMapper::localToAncestorVisualRectInternal( |
Xianzhu
2017/03/10 00:06:49
It seems that we always return a temporary rect fr
chrishtr
2017/03/10 01:45:29
Done. Good idea, it made the code a lot simpler, l
| |
90 const FloatRect& rect, | 91 const FloatRect& rect, |
91 const PropertyTreeState& localState, | 92 const PropertyTreeState& localState, |
92 const PropertyTreeState& ancestorState, | 93 const PropertyTreeState& ancestorState, |
93 bool& success) { | 94 bool& success) { |
94 if (localState == ancestorState) { | 95 if (localState == ancestorState) { |
95 success = true; | 96 success = true; |
96 return rect; | 97 m_tempRect = rect; |
98 return m_tempRect; | |
97 } | 99 } |
98 | 100 |
99 if (localState.effect() != ancestorState.effect()) { | 101 if (localState.effect() != ancestorState.effect()) { |
100 return slowLocalToAncestorVisualRectWithEffects(rect, localState, | 102 m_tempRect = slowLocalToAncestorVisualRectWithEffects( |
101 ancestorState, success); | 103 rect, localState, ancestorState, success); |
104 return m_tempRect; | |
102 } | 105 } |
103 | 106 |
104 const auto& transformMatrix = localToAncestorMatrixInternal( | 107 const auto& transformMatrix = localToAncestorMatrixInternal( |
105 localState.transform(), ancestorState.transform(), success); | 108 localState.transform(), ancestorState.transform(), success); |
106 if (!success) | 109 if (!success) { |
107 return rect; | 110 m_tempRect = rect; |
111 return m_tempRect; | |
112 } | |
108 | 113 |
109 FloatRect mappedRect = transformMatrix.mapRect(rect); | 114 FloatRect mappedRect = transformMatrix.mapRect(rect); |
110 | 115 |
111 FloatClipRect clipRect = | 116 const FloatClipRect& clipRect = |
112 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), | 117 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), |
113 ancestorState.transform(), success); | 118 ancestorState.transform(), success); |
114 | 119 |
115 if (success) { | 120 if (success) { |
116 clipRect.intersect(mappedRect); | 121 m_tempRect = clipRect; |
122 m_tempRect.intersect(mappedRect); | |
123 return m_tempRect; | |
117 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 124 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
118 // On SPv1 we may fail when the paint invalidation container creates an | 125 // On SPv1 we may fail when the paint invalidation container creates an |
119 // overflow clip (in ancestorState) which is not in localState of an | 126 // overflow clip (in ancestorState) which is not in localState of an |
120 // out-of-flow positioned descendant. See crbug.com/513108 and layout test | 127 // out-of-flow positioned descendant. See crbug.com/513108 and layout test |
121 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with | 128 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with |
122 // --enable-prefer-compositing-to-lcd-text) for details. | 129 // --enable-prefer-compositing-to-lcd-text) for details. |
123 // Ignore it for SPv1 for now. | 130 // Ignore it for SPv1 for now. |
124 success = true; | 131 success = true; |
125 } | 132 } |
126 | 133 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 ancestorState.clip(), nullptr); | 171 ancestorState.clip(), nullptr); |
165 bool hasRadius = result.hasRadius(); | 172 bool hasRadius = result.hasRadius(); |
166 result = sourceToDestinationVisualRectInternal( | 173 result = sourceToDestinationVisualRectInternal( |
167 result.rect(), lastTransformAndClipState, finalTransformAndClipState, | 174 result.rect(), lastTransformAndClipState, finalTransformAndClipState, |
168 success); | 175 success); |
169 if (hasRadius || result.hasRadius()) | 176 if (hasRadius || result.hasRadius()) |
170 result.setHasRadius(); | 177 result.setHasRadius(); |
171 return result; | 178 return result; |
172 } | 179 } |
173 | 180 |
174 FloatRect GeometryMapper::localToAncestorRect( | 181 void GeometryMapper::localToAncestorRect( |
175 const FloatRect& rect, | |
176 const TransformPaintPropertyNode* localTransformNode, | 182 const TransformPaintPropertyNode* localTransformNode, |
177 const TransformPaintPropertyNode* ancestorTransformNode) { | 183 const TransformPaintPropertyNode* ancestorTransformNode, |
184 FloatRect& rect) { | |
178 bool success = false; | 185 bool success = false; |
179 FloatRect result = localToAncestorRectInternal( | 186 localToAncestorRectInternal(localTransformNode, ancestorTransformNode, rect, |
180 rect, localTransformNode, ancestorTransformNode, success); | 187 success); |
181 DCHECK(success); | 188 DCHECK(success); |
182 return result; | |
183 } | 189 } |
184 | 190 |
185 FloatRect GeometryMapper::localToAncestorRectInternal( | 191 void GeometryMapper::localToAncestorRectInternal( |
186 const FloatRect& rect, | |
187 const TransformPaintPropertyNode* localTransformNode, | 192 const TransformPaintPropertyNode* localTransformNode, |
188 const TransformPaintPropertyNode* ancestorTransformNode, | 193 const TransformPaintPropertyNode* ancestorTransformNode, |
194 FloatRect& rect, | |
189 bool& success) { | 195 bool& success) { |
190 if (localTransformNode == ancestorTransformNode) { | 196 if (localTransformNode == ancestorTransformNode) { |
191 success = true; | 197 success = true; |
192 return rect; | 198 return; |
193 } | 199 } |
194 | 200 |
195 const auto& transformMatrix = localToAncestorMatrixInternal( | 201 const auto& transformMatrix = localToAncestorMatrixInternal( |
196 localTransformNode, ancestorTransformNode, success); | 202 localTransformNode, ancestorTransformNode, success); |
197 if (!success) | 203 if (!success) |
198 return rect; | 204 return; |
199 return transformMatrix.mapRect(rect); | 205 rect = transformMatrix.mapRect(rect); |
200 } | 206 } |
201 | 207 |
202 FloatRect GeometryMapper::ancestorToLocalRect( | 208 void GeometryMapper::ancestorToLocalRect( |
203 const FloatRect& rect, | |
204 const TransformPaintPropertyNode* ancestorTransformNode, | 209 const TransformPaintPropertyNode* ancestorTransformNode, |
205 const TransformPaintPropertyNode* localTransformNode) { | 210 const TransformPaintPropertyNode* localTransformNode, |
211 FloatRect& rect) { | |
206 if (localTransformNode == ancestorTransformNode) | 212 if (localTransformNode == ancestorTransformNode) |
207 return rect; | 213 return; |
208 | 214 |
209 const auto& transformMatrix = | 215 const auto& transformMatrix = |
210 localToAncestorMatrix(localTransformNode, ancestorTransformNode); | 216 localToAncestorMatrix(localTransformNode, ancestorTransformNode); |
211 DCHECK(transformMatrix.isInvertible()); | 217 DCHECK(transformMatrix.isInvertible()); |
212 | 218 |
213 // TODO(chrishtr): Cache the inverse? | 219 // TODO(chrishtr): Cache the inverse? |
214 return transformMatrix.inverse().mapRect(rect); | 220 rect = transformMatrix.inverse().mapRect(rect); |
215 } | 221 } |
216 | 222 |
217 FloatClipRect GeometryMapper::localToAncestorClipRect( | 223 FloatClipRect GeometryMapper::localToAncestorClipRect( |
218 const PropertyTreeState& localState, | 224 const PropertyTreeState& localState, |
219 const PropertyTreeState& ancestorState) { | 225 const PropertyTreeState& ancestorState) { |
220 bool success = false; | 226 bool success = false; |
221 FloatClipRect result = | 227 FloatClipRect result = |
222 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), | 228 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), |
223 ancestorState.transform(), success); | 229 ancestorState.transform(), success); |
224 | 230 |
225 DCHECK(success); | 231 DCHECK(success); |
226 | 232 |
227 return result; | 233 return result; |
228 } | 234 } |
229 | 235 |
230 FloatClipRect GeometryMapper::sourceToDestinationClipRect( | 236 const FloatClipRect& GeometryMapper::sourceToDestinationClipRect( |
231 const PropertyTreeState& sourceState, | 237 const PropertyTreeState& sourceState, |
232 const PropertyTreeState& destinationState) { | 238 const PropertyTreeState& destinationState) { |
233 bool success = false; | 239 bool success = false; |
234 FloatClipRect result = sourceToDestinationClipRectInternal( | 240 const FloatClipRect& result = sourceToDestinationClipRectInternal( |
235 sourceState, destinationState, success); | 241 sourceState, destinationState, success); |
236 DCHECK(success); | 242 DCHECK(success); |
237 | 243 |
238 return result; | 244 return result; |
239 } | 245 } |
240 | 246 |
241 FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( | 247 const FloatClipRect& GeometryMapper::sourceToDestinationClipRectInternal( |
242 const PropertyTreeState& sourceState, | 248 const PropertyTreeState& sourceState, |
243 const PropertyTreeState& destinationState, | 249 const PropertyTreeState& destinationState, |
244 bool& success) { | 250 bool& success) { |
245 FloatClipRect result = localToAncestorClipRectInternal( | 251 const FloatClipRect& result = localToAncestorClipRectInternal( |
246 sourceState.clip(), destinationState.clip(), destinationState.transform(), | 252 sourceState.clip(), destinationState.clip(), destinationState.transform(), |
247 success); | 253 success); |
248 // Success if destinationState is an ancestor state. | 254 // Success if destinationState is an ancestor state. |
249 if (success) | 255 if (success) |
250 return result; | 256 return result; |
251 | 257 |
252 // Otherwise first map to the lowest common ancestor, then map to | 258 // Otherwise first map to the lowest common ancestor, then map to |
253 // destination. | 259 // destination. |
254 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( | 260 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( |
255 sourceState.transform(), destinationState.transform()); | 261 sourceState.transform(), destinationState.transform()); |
256 DCHECK(lcaTransform); | 262 DCHECK(lcaTransform); |
257 | 263 |
258 // Assume that the clip of destinationState is an ancestor of the clip of | 264 // Assume that the clip of destinationState is an ancestor of the clip of |
259 // sourceState and is under the space of lcaTransform. Otherwise | 265 // sourceState and is under the space of lcaTransform. Otherwise |
260 // localToAncestorClipRectInternal() will fail. | 266 // localToAncestorClipRectInternal() will fail. |
261 PropertyTreeState lcaState = destinationState; | 267 PropertyTreeState lcaState = destinationState; |
262 lcaState.setTransform(lcaTransform); | 268 lcaState.setTransform(lcaTransform); |
263 | 269 |
264 result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(), | 270 const FloatClipRect& result2 = localToAncestorClipRectInternal( |
265 lcaState.transform(), success); | 271 sourceState.clip(), lcaState.clip(), lcaState.transform(), success); |
266 if (!success) { | 272 if (!success) { |
267 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 273 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
268 // On SPv1 we may fail when the paint invalidation container creates an | 274 // On SPv1 we may fail when the paint invalidation container creates an |
269 // overflow clip (in ancestorState) which is not in localState of an | 275 // overflow clip (in ancestorState) which is not in localState of an |
270 // out-of-flow positioned descendant. See crbug.com/513108 and layout | 276 // out-of-flow positioned descendant. See crbug.com/513108 and layout |
271 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run | 277 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run |
272 // with --enable-prefer-compositing-to-lcd-text) for details. | 278 // with --enable-prefer-compositing-to-lcd-text) for details. |
273 // Ignore it for SPv1 for now. | 279 // Ignore it for SPv1 for now. |
274 success = true; | 280 success = true; |
275 } | 281 } |
276 return result; | 282 return result2; |
277 } | 283 } |
278 if (!result.isInfinite()) { | 284 if (!result2.isInfinite()) { |
279 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, | 285 FloatRect rect = result2.rect(); |
280 destinationState.transform()); | 286 ancestorToLocalRect(lcaTransform, destinationState.transform(), rect); |
281 result.setRect(final); | 287 m_tempRect.setRect(rect); |
288 if (result2.hasRadius()) | |
289 m_tempRect.setHasRadius(); | |
290 return m_tempRect; | |
282 } | 291 } |
283 return result; | 292 return result2; |
284 } | 293 } |
285 | 294 |
286 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( | 295 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( |
287 const ClipPaintPropertyNode* descendant, | 296 const ClipPaintPropertyNode* descendant, |
288 const ClipPaintPropertyNode* ancestorClip, | 297 const ClipPaintPropertyNode* ancestorClip, |
289 const TransformPaintPropertyNode* ancestorTransform, | 298 const TransformPaintPropertyNode* ancestorTransform, |
290 bool& success) { | 299 bool& success) { |
291 FloatClipRect clip; | 300 FloatClipRect clip; |
292 if (descendant == ancestorClip) { | 301 if (descendant == ancestorClip) { |
293 success = true; | 302 success = true; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 const TransformPaintPropertyNode*, | 465 const TransformPaintPropertyNode*, |
457 const TransformPaintPropertyNode*); | 466 const TransformPaintPropertyNode*); |
458 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( | 467 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( |
459 const ClipPaintPropertyNode*, | 468 const ClipPaintPropertyNode*, |
460 const ClipPaintPropertyNode*); | 469 const ClipPaintPropertyNode*); |
461 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( | 470 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( |
462 const ScrollPaintPropertyNode*, | 471 const ScrollPaintPropertyNode*, |
463 const ScrollPaintPropertyNode*); | 472 const ScrollPaintPropertyNode*); |
464 | 473 |
465 } // namespace blink | 474 } // namespace blink |
OLD | NEW |