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

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

Issue 2623823002: Rename and change parameter type of some GeometryMapper methods (Closed)
Patch Set: Swap local and ancestor parameters in ancestorToLocalRect(). 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
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 FloatRect GeometryMapper::mapToVisualRectInDestinationSpace( 12 FloatRect GeometryMapper::sourceToDestinationVisualRect(
13 const FloatRect& rect,
14 const PropertyTreeState& sourceState,
15 const PropertyTreeState& destinationState,
16 bool& success) {
17 FloatRect result = localToVisualRectInAncestorSpace(
18 rect, sourceState, destinationState, success);
19 if (success)
20 return result;
21 return slowMapToVisualRectInDestinationSpace(rect, sourceState,
22 destinationState, success);
23 }
24
25 FloatRect GeometryMapper::mapRectToDestinationSpace(
26 const FloatRect& rect, 13 const FloatRect& rect,
27 const PropertyTreeState& sourceState, 14 const PropertyTreeState& sourceState,
28 const PropertyTreeState& destinationState, 15 const PropertyTreeState& destinationState,
29 bool& success) { 16 bool& success) {
30 FloatRect result = 17 FloatRect result =
31 localToAncestorRect(rect, sourceState, destinationState, success); 18 localToAncestorVisualRect(rect, sourceState, destinationState, success);
32 if (success) 19 if (success)
33 return result; 20 return result;
34 return slowMapRectToDestinationSpace(rect, sourceState, destinationState, 21 return slowSourceToDestinationVisualRect(rect, sourceState, destinationState,
35 success); 22 success);
36 } 23 }
37 24
38 FloatRect GeometryMapper::slowMapToVisualRectInDestinationSpace( 25 FloatRect GeometryMapper::sourceToDestinationRect(
26 const FloatRect& rect,
27 const TransformPaintPropertyNode* sourceTransformNode,
28 const TransformPaintPropertyNode* destinationTransformNode,
29 bool& success) {
30 FloatRect result = localToAncestorRect(rect, sourceTransformNode,
31 destinationTransformNode, success);
32 if (success)
33 return result;
34 return slowSourceToDestinationRect(rect, sourceTransformNode,
35 destinationTransformNode, success);
36 }
37
38 FloatRect GeometryMapper::slowSourceToDestinationVisualRect(
39 const FloatRect& rect, 39 const FloatRect& rect,
40 const PropertyTreeState& sourceState, 40 const PropertyTreeState& sourceState,
41 const PropertyTreeState& destinationState, 41 const PropertyTreeState& destinationState,
42 bool& success) { 42 bool& success) {
43 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor( 43 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor(
44 sourceState.transform(), destinationState.transform()); 44 sourceState.transform(), destinationState.transform());
45 DCHECK(lcaTransform); 45 DCHECK(lcaTransform);
46 46
47 // Assume that the clip of destinationState is an ancestor of the clip of 47 // Assume that the clip of destinationState is an ancestor of the clip of
48 // sourceState and is under the space of lcaTransform. Otherwise 48 // sourceState and is under the space of lcaTransform. Otherwise
49 // localToAncestorClipRect() will fail. 49 // localToAncestorClipRect() will fail.
50 PropertyTreeState lcaState = destinationState; 50 PropertyTreeState lcaState = destinationState;
51 lcaState.setTransform(lcaTransform); 51 lcaState.setTransform(lcaTransform);
52 52
53 const auto clipRect = localToAncestorClipRect(sourceState, lcaState, success); 53 FloatRect result =
54 localToAncestorVisualRect(rect, sourceState, lcaState, success);
54 if (!success) 55 if (!success)
55 return rect; 56 return result;
56 57
57 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); 58 return ancestorToLocalRect(result, lcaTransform, destinationState.transform(),
chrishtr 2017/01/11 23:23:09 Why remove this?
Xianzhu 2017/01/11 23:54:43 Line 53-59 now becomes a call to localToAncestorVi
58 DCHECK(success); 59 success);
59 result.intersect(clipRect);
60
61 return ancestorToLocalRect(result, destinationState, lcaState, success);
62 } 60 }
63 61
64 FloatRect GeometryMapper::slowMapRectToDestinationSpace( 62 FloatRect GeometryMapper::slowSourceToDestinationRect(
65 const FloatRect& rect, 63 const FloatRect& rect,
66 const PropertyTreeState& sourceState, 64 const TransformPaintPropertyNode* sourceTransformNode,
67 const PropertyTreeState& destinationState, 65 const TransformPaintPropertyNode* destinationTransformNode,
68 bool& success) { 66 bool& success) {
69 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor( 67 const TransformPaintPropertyNode* lcaTransform =
70 sourceState.transform(), destinationState.transform()); 68 leastCommonAncestor(sourceTransformNode, destinationTransformNode);
71 DCHECK(lcaTransform); 69 DCHECK(lcaTransform);
72 PropertyTreeState lcaState = sourceState;
73 lcaState.setTransform(lcaTransform);
74 70
75 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); 71 FloatRect result =
72 localToAncestorRect(rect, sourceTransformNode, lcaTransform, success);
76 DCHECK(success); 73 DCHECK(success);
77 74
78 return ancestorToLocalRect(result, destinationState, lcaState, success); 75 return ancestorToLocalRect(result, lcaTransform, destinationTransformNode,
76 success);
79 } 77 }
80 78
81 FloatRect GeometryMapper::localToVisualRectInAncestorSpace( 79 FloatRect GeometryMapper::localToAncestorVisualRect(
82 const FloatRect& rect, 80 const FloatRect& rect,
83 const PropertyTreeState& localState, 81 const PropertyTreeState& localState,
84 const PropertyTreeState& ancestorState, 82 const PropertyTreeState& ancestorState,
85 bool& success) { 83 bool& success) {
86 if (localState == ancestorState) { 84 if (localState == ancestorState) {
87 success = true; 85 success = true;
88 return rect; 86 return rect;
89 } 87 }
90 88
91 const auto& transformMatrix = 89 const auto& transformMatrix = localToAncestorMatrix(
92 localToAncestorMatrix(localState.transform(), ancestorState, success); 90 localState.transform(), ancestorState.transform(), success);
93 if (!success) 91 if (!success)
94 return rect; 92 return rect;
95 93
96 FloatRect mappedRect = transformMatrix.mapRect(rect); 94 FloatRect mappedRect = transformMatrix.mapRect(rect);
97 95
98 const auto clipRect = 96 const auto clipRect =
99 localToAncestorClipRect(localState, ancestorState, success); 97 localToAncestorClipRect(localState, ancestorState, success);
100 98
101 if (success) { 99 if (success) {
102 mappedRect.intersect(clipRect); 100 mappedRect.intersect(clipRect);
103 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 101 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
104 // On SPv1 we may fail when the paint invalidation container creates an 102 // On SPv1 we may fail when the paint invalidation container creates an
105 // overflow clip (in ancestorState) which is not in localState of an 103 // overflow clip (in ancestorState) which is not in localState of an
106 // out-of-flow positioned descendant. See crbug.com/513108 and layout test 104 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
107 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with 105 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
108 // --enable-prefer-compositing-to-lcd-text) for details. 106 // --enable-prefer-compositing-to-lcd-text) for details.
109 // Ignore it for SPv1 for now. 107 // Ignore it for SPv1 for now.
110 success = true; 108 success = true;
111 } else {
chrishtr 2017/01/11 23:23:09 Why remove this?
Xianzhu 2017/01/11 23:54:43 Now slowSourceToDestinationVisualRect (previously
chrishtr 2017/01/12 18:07:12 The DCHECK is to ensure that it's actually an ance
Xianzhu 2017/01/12 18:39:17 No DCHECK(success) here is mainly a requirement of
112 DCHECK(success);
113 } 109 }
114 110
115 return mappedRect; 111 return mappedRect;
116 } 112 }
117 113
118 FloatRect GeometryMapper::localToAncestorRect( 114 FloatRect GeometryMapper::localToAncestorRect(
119 const FloatRect& rect, 115 const FloatRect& rect,
120 const PropertyTreeState& localState, 116 const TransformPaintPropertyNode* localTransformNode,
121 const PropertyTreeState& ancestorState, 117 const TransformPaintPropertyNode* ancestorTransformNode,
122 bool& success) { 118 bool& success) {
123 if (localState.transform() == ancestorState.transform()) { 119 if (localTransformNode == ancestorTransformNode) {
124 success = true; 120 success = true;
125 return rect; 121 return rect;
126 } 122 }
127 123
128 const auto& transformMatrix = 124 const auto& transformMatrix =
129 localToAncestorMatrix(localState.transform(), ancestorState, success); 125 localToAncestorMatrix(localTransformNode, ancestorTransformNode, success);
130 if (!success) 126 if (!success)
131 return rect; 127 return rect;
132 return transformMatrix.mapRect(rect); 128 return transformMatrix.mapRect(rect);
133 } 129 }
134 130
135 FloatRect GeometryMapper::ancestorToLocalRect( 131 FloatRect GeometryMapper::ancestorToLocalRect(
136 const FloatRect& rect, 132 const FloatRect& rect,
137 const PropertyTreeState& localState, 133 const TransformPaintPropertyNode* ancestorTransformNode,
138 const PropertyTreeState& ancestorState, 134 const TransformPaintPropertyNode* localTransformNode,
139 bool& success) { 135 bool& success) {
140 if (localState.transform() == ancestorState.transform()) { 136 if (localTransformNode == ancestorTransformNode) {
141 success = true; 137 success = true;
142 return rect; 138 return rect;
143 } 139 }
144 140
145 const auto& transformMatrix = 141 const auto& transformMatrix =
146 localToAncestorMatrix(localState.transform(), ancestorState, success); 142 localToAncestorMatrix(localTransformNode, ancestorTransformNode, success);
147 if (!success) 143 if (!success)
148 return rect; 144 return rect;
149 145
150 if (!transformMatrix.isInvertible()) { 146 if (!transformMatrix.isInvertible()) {
151 success = false; 147 success = false;
152 return rect; 148 return rect;
153 } 149 }
154 success = true; 150 success = true;
155 151
156 // TODO(chrishtr): Cache the inverse? 152 // TODO(chrishtr): Cache the inverse?
157 return transformMatrix.inverse().mapRect(rect); 153 return transformMatrix.inverse().mapRect(rect);
158 } 154 }
159 155
160 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor( 156 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(
161 const PropertyTreeState& ancestorState) { 157 const TransformPaintPropertyNode* ancestorTransformNode) {
162 auto addResult = m_data.add(ancestorState.transform(), nullptr); 158 auto addResult = m_data.add(ancestorTransformNode, nullptr);
163 if (addResult.isNewEntry) 159 if (addResult.isNewEntry)
164 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 160 addResult.storedValue->value = PrecomputedDataForAncestor::create();
165 return *addResult.storedValue->value; 161 return *addResult.storedValue->value;
166 } 162 }
167 163
168 FloatRect GeometryMapper::localToAncestorClipRect( 164 FloatRect GeometryMapper::localToAncestorClipRect(
169 const PropertyTreeState& localState, 165 const PropertyTreeState& localState,
170 const PropertyTreeState& ancestorState, 166 const PropertyTreeState& ancestorState,
171 bool& success) { 167 bool& success) {
172 FloatRect clip(LayoutRect::infiniteIntRect()); 168 FloatRect clip(LayoutRect::infiniteIntRect());
173 if (localState.clip() == ancestorState.clip()) { 169 if (localState.clip() == ancestorState.clip()) {
174 success = true; 170 success = true;
175 return clip; 171 return clip;
176 } 172 }
177 173
178 PrecomputedDataForAncestor& precomputedData = 174 PrecomputedDataForAncestor& precomputedData =
179 getPrecomputedDataForAncestor(ancestorState); 175 getPrecomputedDataForAncestor(ancestorState.transform());
180 const ClipPaintPropertyNode* clipNode = localState.clip(); 176 const ClipPaintPropertyNode* clipNode = localState.clip();
181 Vector<const ClipPaintPropertyNode*> intermediateNodes; 177 Vector<const ClipPaintPropertyNode*> intermediateNodes;
182 178
183 bool found = false;
184 // Iterate over the path from localState.clip to ancestorState.clip. Stop if 179 // Iterate over the path from localState.clip to ancestorState.clip. Stop if
185 // we've found a memoized (precomputed) clip for any particular node. 180 // we've found a memoized (precomputed) clip for any particular node.
186 while (clipNode) { 181 while (clipNode && clipNode != ancestorState.clip()) {
187 auto it = precomputedData.toAncestorClipRects.find(clipNode); 182 auto it = precomputedData.toAncestorClipRects.find(clipNode);
188 if (it != precomputedData.toAncestorClipRects.end()) { 183 if (it != precomputedData.toAncestorClipRects.end()) {
189 clip = it->value; 184 clip = it->value;
190 found = true;
191 break; 185 break;
192 } 186 }
193 intermediateNodes.push_back(clipNode); 187 intermediateNodes.push_back(clipNode);
194
195 if (clipNode == ancestorState.clip())
196 break;
197
198 clipNode = clipNode->parent(); 188 clipNode = clipNode->parent();
199 } 189 }
200 if (clipNode != ancestorState.clip() && !found) { 190 if (!clipNode) {
chrishtr 2017/01/11 23:23:09 What about if clipNode == ancestorState.clip()?
Xianzhu 2017/01/11 23:54:43 In the case we'll execute the loop below, the same
201 success = false; 191 success = false;
202 return clip; 192 return clip;
203 } 193 }
204 194
205 // Iterate down from the top intermediate node found in the previous loop, 195 // Iterate down from the top intermediate node found in the previous loop,
206 // computing and memoizing clip rects as we go. 196 // computing and memoizing clip rects as we go.
207 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 197 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
208 ++it) { 198 ++it) {
209 if ((*it) != ancestorState.clip()) { 199 success = false;
210 success = false; 200 const TransformationMatrix& transformMatrix = localToAncestorMatrix(
211 const TransformationMatrix& transformMatrix = localToAncestorMatrix( 201 (*it)->localTransformSpace(), ancestorState.transform(), success);
212 (*it)->localTransformSpace(), ancestorState, success); 202 if (!success)
213 if (!success) 203 return clip;
214 return clip; 204 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
215 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 205 clip.intersect(mappedRect);
216 clip.intersect(mappedRect);
217 }
218
219 precomputedData.toAncestorClipRects.set(*it, clip); 206 precomputedData.toAncestorClipRects.set(*it, clip);
220 } 207 }
221 208
222 success = true; 209 success = true;
223 return precomputedData.toAncestorClipRects.find(localState.clip())->value; 210 return precomputedData.toAncestorClipRects.find(localState.clip())->value;
224 } 211 }
225 212
226 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 213 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
227 const TransformPaintPropertyNode* localTransformNode, 214 const TransformPaintPropertyNode* localTransformNode,
228 const PropertyTreeState& ancestorState, 215 const TransformPaintPropertyNode* ancestorTransformNode,
229 bool& success) { 216 bool& success) {
230 if (localTransformNode == ancestorState.transform()) { 217 if (localTransformNode == ancestorTransformNode) {
231 success = true; 218 success = true;
232 return m_identity; 219 return m_identity;
233 } 220 }
234 221
235 PrecomputedDataForAncestor& precomputedData = 222 PrecomputedDataForAncestor& precomputedData =
236 getPrecomputedDataForAncestor(ancestorState); 223 getPrecomputedDataForAncestor(ancestorTransformNode);
237 224
238 const TransformPaintPropertyNode* transformNode = localTransformNode; 225 const TransformPaintPropertyNode* transformNode = localTransformNode;
239 Vector<const TransformPaintPropertyNode*> intermediateNodes; 226 Vector<const TransformPaintPropertyNode*> intermediateNodes;
240 TransformationMatrix transformMatrix; 227 TransformationMatrix transformMatrix;
241 228
242 // Iterate over the path from localTransformNode to ancestorState.transform. 229 // Iterate over the path from localTransformNode to ancestorState.transform.
243 // Stop if we've found a memoized (precomputed) transform for any particular 230 // Stop if we've found a memoized (precomputed) transform for any particular
244 // node. 231 // node.
245 while (transformNode) { 232 while (transformNode && transformNode != ancestorTransformNode) {
246 auto it = precomputedData.toAncestorTransforms.find(transformNode); 233 auto it = precomputedData.toAncestorTransforms.find(transformNode);
247 if (it != precomputedData.toAncestorTransforms.end()) { 234 if (it != precomputedData.toAncestorTransforms.end()) {
248 transformMatrix = it->value; 235 transformMatrix = it->value;
249 break; 236 break;
250 } 237 }
251
252 if (transformNode == ancestorState.transform())
253 break;
254
255 intermediateNodes.push_back(transformNode); 238 intermediateNodes.push_back(transformNode);
256 transformNode = transformNode->parent(); 239 transformNode = transformNode->parent();
257 } 240 }
258 if (!transformNode) { 241 if (!transformNode) {
259 success = false; 242 success = false;
260 return m_identity; 243 return m_identity;
261 } 244 }
262 245
263 // Iterate down from the top intermediate node found in the previous loop, 246 // Iterate down from the top intermediate node found in the previous loop,
264 // computing and memoizing transforms as we go. 247 // computing and memoizing transforms as we go.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 290
308 // Walk up until we find the ancestor. 291 // Walk up until we find the ancestor.
309 while (a != b) { 292 while (a != b) {
310 a = a->parent(); 293 a = a->parent();
311 b = b->parent(); 294 b = b->parent();
312 } 295 }
313 return a; 296 return a;
314 } 297 }
315 298
316 } // namespace blink 299 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698