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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp

Issue 2745563004: Reduce copying of local data structures in GeometryMapper and PaintLayerClipper. (Closed)
Patch Set: none Created 3 years, 9 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
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698