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

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

Issue 2630783002: Remove |success| parameter from GeometryMapper's public methods (Closed)
Patch Set: Rebase 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::sourceToDestinationVisualRect( 12 FloatRect GeometryMapper::sourceToDestinationVisualRect(
13 const FloatRect& rect, 13 const FloatRect& rect,
14 const PropertyTreeState& sourceState, 14 const PropertyTreeState& sourceState,
15 const PropertyTreeState& destinationState) {
16 bool success = false;
17 FloatRect result = sourceToDestinationVisualRectInternal(
18 rect, sourceState, destinationState, success);
19 DCHECK(success);
20 return result;
21 }
22
23 FloatRect GeometryMapper::sourceToDestinationVisualRectInternal(
24 const FloatRect& rect,
25 const PropertyTreeState& sourceState,
15 const PropertyTreeState& destinationState, 26 const PropertyTreeState& destinationState,
16 bool& success) { 27 bool& success) {
17 FloatRect result = 28 FloatRect result = localToAncestorVisualRectInternal(
18 localToAncestorVisualRect(rect, sourceState, destinationState, success); 29 rect, sourceState, destinationState, success);
30 // Success if destinationState is an ancestor state.
19 if (success) 31 if (success)
20 return result; 32 return result;
21 return slowSourceToDestinationVisualRect(rect, sourceState, destinationState,
22 success);
23 }
24 33
25 FloatRect GeometryMapper::sourceToDestinationRect( 34 // Otherwise first map to the least common ancestor, then map to destination.
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,
40 const PropertyTreeState& sourceState,
41 const PropertyTreeState& destinationState,
42 bool& success) {
43 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor( 35 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor(
44 sourceState.transform(), destinationState.transform()); 36 sourceState.transform(), destinationState.transform());
45 DCHECK(lcaTransform); 37 DCHECK(lcaTransform);
46 38
47 // Assume that the clip of destinationState is an ancestor of the clip of 39 // Assume that the clip of destinationState is an ancestor of the clip of
48 // sourceState and is under the space of lcaTransform. Otherwise 40 // sourceState and is under the space of lcaTransform. Otherwise
49 // localToAncestorClipRect() will fail. 41 // localToAncestorVisualRect() will fail.
50 PropertyTreeState lcaState = destinationState; 42 PropertyTreeState lcaState = destinationState;
51 lcaState.setTransform(lcaTransform); 43 lcaState.setTransform(lcaTransform);
52 44
53 FloatRect result = 45 FloatRect lcaVisualRect =
54 localToAncestorVisualRect(rect, sourceState, lcaState, success); 46 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success);
55 if (!success) 47 if (!success)
48 return lcaVisualRect;
49 return ancestorToLocalRect(lcaVisualRect, lcaTransform,
50 destinationState.transform());
51 }
52
53 FloatRect GeometryMapper::sourceToDestinationRect(
54 const FloatRect& rect,
55 const TransformPaintPropertyNode* sourceTransformNode,
56 const TransformPaintPropertyNode* destinationTransformNode) {
57 bool success = false;
58 FloatRect result = localToAncestorRectInternal(
59 rect, sourceTransformNode, destinationTransformNode, success);
60 // Success if destinationTransformNode is an ancestor of sourceTransformNode.
61 if (success)
56 return result; 62 return result;
57 63
58 return ancestorToLocalRect(result, lcaTransform, destinationState.transform(), 64 // Otherwise first map to the least common ancestor, then map to destination.
59 success);
60 }
61
62 FloatRect GeometryMapper::slowSourceToDestinationRect(
63 const FloatRect& rect,
64 const TransformPaintPropertyNode* sourceTransformNode,
65 const TransformPaintPropertyNode* destinationTransformNode,
66 bool& success) {
67 const TransformPaintPropertyNode* lcaTransform = 65 const TransformPaintPropertyNode* lcaTransform =
68 leastCommonAncestor(sourceTransformNode, destinationTransformNode); 66 leastCommonAncestor(sourceTransformNode, destinationTransformNode);
69 DCHECK(lcaTransform); 67 DCHECK(lcaTransform);
70 68
71 FloatRect result = 69 FloatRect lcaRect =
72 localToAncestorRect(rect, sourceTransformNode, lcaTransform, success); 70 localToAncestorRect(rect, sourceTransformNode, lcaTransform);
73 DCHECK(success); 71 return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode);
74
75 return ancestorToLocalRect(result, lcaTransform, destinationTransformNode,
76 success);
77 } 72 }
78 73
79 FloatRect GeometryMapper::localToAncestorVisualRect( 74 FloatRect GeometryMapper::localToAncestorVisualRect(
80 const FloatRect& rect, 75 const FloatRect& rect,
81 const PropertyTreeState& localState, 76 const PropertyTreeState& localState,
77 const PropertyTreeState& ancestorState) {
78 bool success = false;
79 FloatRect result = localToAncestorVisualRectInternal(rect, localState,
80 ancestorState, success);
81 DCHECK(success);
82 return result;
83 }
84
85 FloatRect GeometryMapper::localToAncestorVisualRectInternal(
86 const FloatRect& rect,
87 const PropertyTreeState& localState,
82 const PropertyTreeState& ancestorState, 88 const PropertyTreeState& ancestorState,
83 bool& success) { 89 bool& success) {
84 if (localState == ancestorState) { 90 if (localState == ancestorState) {
85 success = true; 91 success = true;
86 return rect; 92 return rect;
87 } 93 }
88 94
89 const auto& transformMatrix = localToAncestorMatrix( 95 const auto& transformMatrix = localToAncestorMatrixInternal(
90 localState.transform(), ancestorState.transform(), success); 96 localState.transform(), ancestorState.transform(), success);
91 if (!success) 97 if (!success)
92 return rect; 98 return rect;
93 99
94 FloatRect mappedRect = transformMatrix.mapRect(rect); 100 FloatRect mappedRect = transformMatrix.mapRect(rect);
95 101
96 const auto clipRect = 102 const auto clipRect =
97 localToAncestorClipRect(localState, ancestorState, success); 103 localToAncestorClipRectInternal(localState, ancestorState, success);
98 104
99 if (success) { 105 if (success) {
100 mappedRect.intersect(clipRect); 106 mappedRect.intersect(clipRect);
101 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 107 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
102 // On SPv1 we may fail when the paint invalidation container creates an 108 // On SPv1 we may fail when the paint invalidation container creates an
103 // overflow clip (in ancestorState) which is not in localState of an 109 // overflow clip (in ancestorState) which is not in localState of an
104 // out-of-flow positioned descendant. See crbug.com/513108 and layout test 110 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
105 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with 111 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
106 // --enable-prefer-compositing-to-lcd-text) for details. 112 // --enable-prefer-compositing-to-lcd-text) for details.
107 // Ignore it for SPv1 for now. 113 // Ignore it for SPv1 for now.
108 success = true; 114 success = true;
109 } 115 }
110 116
111 return mappedRect; 117 return mappedRect;
112 } 118 }
113 119
114 FloatRect GeometryMapper::localToAncestorRect( 120 FloatRect GeometryMapper::localToAncestorRect(
115 const FloatRect& rect, 121 const FloatRect& rect,
116 const TransformPaintPropertyNode* localTransformNode, 122 const TransformPaintPropertyNode* localTransformNode,
123 const TransformPaintPropertyNode* ancestorTransformNode) {
124 bool success = false;
125 FloatRect result = localToAncestorRectInternal(
126 rect, localTransformNode, ancestorTransformNode, success);
127 DCHECK(success);
128 return result;
129 }
130
131 FloatRect GeometryMapper::localToAncestorRectInternal(
132 const FloatRect& rect,
133 const TransformPaintPropertyNode* localTransformNode,
117 const TransformPaintPropertyNode* ancestorTransformNode, 134 const TransformPaintPropertyNode* ancestorTransformNode,
118 bool& success) { 135 bool& success) {
119 if (localTransformNode == ancestorTransformNode) { 136 if (localTransformNode == ancestorTransformNode) {
120 success = true; 137 success = true;
121 return rect; 138 return rect;
122 } 139 }
123 140
124 const auto& transformMatrix = 141 const auto& transformMatrix = localToAncestorMatrixInternal(
125 localToAncestorMatrix(localTransformNode, ancestorTransformNode, success); 142 localTransformNode, ancestorTransformNode, success);
126 if (!success) 143 if (!success)
127 return rect; 144 return rect;
128 return transformMatrix.mapRect(rect); 145 return transformMatrix.mapRect(rect);
129 } 146 }
130 147
131 FloatRect GeometryMapper::ancestorToLocalRect( 148 FloatRect GeometryMapper::ancestorToLocalRect(
132 const FloatRect& rect, 149 const FloatRect& rect,
133 const TransformPaintPropertyNode* ancestorTransformNode, 150 const TransformPaintPropertyNode* ancestorTransformNode,
134 const TransformPaintPropertyNode* localTransformNode, 151 const TransformPaintPropertyNode* localTransformNode) {
135 bool& success) { 152 if (localTransformNode == ancestorTransformNode)
136 if (localTransformNode == ancestorTransformNode) {
137 success = true;
138 return rect; 153 return rect;
139 }
140 154
141 const auto& transformMatrix = 155 const auto& transformMatrix =
142 localToAncestorMatrix(localTransformNode, ancestorTransformNode, success); 156 localToAncestorMatrix(localTransformNode, ancestorTransformNode);
143 if (!success) 157 DCHECK(transformMatrix.isInvertible());
144 return rect;
145
146 if (!transformMatrix.isInvertible()) {
147 success = false;
148 return rect;
149 }
150 success = true;
151 158
152 // TODO(chrishtr): Cache the inverse? 159 // TODO(chrishtr): Cache the inverse?
153 return transformMatrix.inverse().mapRect(rect); 160 return transformMatrix.inverse().mapRect(rect);
154 } 161 }
155 162
156 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor( 163 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(
157 const TransformPaintPropertyNode* ancestorTransformNode) { 164 const TransformPaintPropertyNode* ancestorTransformNode) {
158 auto addResult = m_data.add(ancestorTransformNode, nullptr); 165 auto addResult = m_data.add(ancestorTransformNode, nullptr);
159 if (addResult.isNewEntry) 166 if (addResult.isNewEntry)
160 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 167 addResult.storedValue->value = PrecomputedDataForAncestor::create();
161 return *addResult.storedValue->value; 168 return *addResult.storedValue->value;
162 } 169 }
163 170
164 FloatRect GeometryMapper::localToAncestorClipRect( 171 FloatRect GeometryMapper::localToAncestorClipRect(
165 const PropertyTreeState& localState, 172 const PropertyTreeState& localState,
173 const PropertyTreeState& ancestorState) {
174 bool success = false;
175 FloatRect result =
176 localToAncestorClipRectInternal(localState, ancestorState, success);
177 DCHECK(success);
178 return result;
179 }
180
181 FloatRect GeometryMapper::localToAncestorClipRectInternal(
182 const PropertyTreeState& localState,
166 const PropertyTreeState& ancestorState, 183 const PropertyTreeState& ancestorState,
167 bool& success) { 184 bool& success) {
168 FloatRect clip(LayoutRect::infiniteIntRect()); 185 FloatRect clip(LayoutRect::infiniteIntRect());
169 if (localState.clip() == ancestorState.clip()) { 186 if (localState.clip() == ancestorState.clip()) {
170 success = true; 187 success = true;
171 return clip; 188 return clip;
172 } 189 }
173 190
174 PrecomputedDataForAncestor& precomputedData = 191 PrecomputedDataForAncestor& precomputedData =
175 getPrecomputedDataForAncestor(ancestorState.transform()); 192 getPrecomputedDataForAncestor(ancestorState.transform());
(...skipping 14 matching lines...) Expand all
190 if (!clipNode) { 207 if (!clipNode) {
191 success = false; 208 success = false;
192 return clip; 209 return clip;
193 } 210 }
194 211
195 // Iterate down from the top intermediate node found in the previous loop, 212 // Iterate down from the top intermediate node found in the previous loop,
196 // computing and memoizing clip rects as we go. 213 // computing and memoizing clip rects as we go.
197 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 214 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
198 ++it) { 215 ++it) {
199 success = false; 216 success = false;
200 const TransformationMatrix& transformMatrix = localToAncestorMatrix( 217 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal(
201 (*it)->localTransformSpace(), ancestorState.transform(), success); 218 (*it)->localTransformSpace(), ancestorState.transform(), success);
202 if (!success) 219 if (!success)
203 return clip; 220 return clip;
204 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 221 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
205 clip.intersect(mappedRect); 222 clip.intersect(mappedRect);
206 precomputedData.toAncestorClipRects.set(*it, clip); 223 precomputedData.toAncestorClipRects.set(*it, clip);
207 } 224 }
208 225
209 success = true; 226 success = true;
210 return precomputedData.toAncestorClipRects.find(localState.clip())->value; 227 return precomputedData.toAncestorClipRects.find(localState.clip())->value;
211 } 228 }
212 229
213 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 230 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
214 const TransformPaintPropertyNode* localTransformNode, 231 const TransformPaintPropertyNode* localTransformNode,
232 const TransformPaintPropertyNode* ancestorTransformNode) {
233 bool success = false;
234 const auto& result = localToAncestorMatrixInternal(
235 localTransformNode, ancestorTransformNode, success);
236 DCHECK(success);
237 return result;
238 }
239
240 const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal(
241 const TransformPaintPropertyNode* localTransformNode,
215 const TransformPaintPropertyNode* ancestorTransformNode, 242 const TransformPaintPropertyNode* ancestorTransformNode,
216 bool& success) { 243 bool& success) {
217 if (localTransformNode == ancestorTransformNode) { 244 if (localTransformNode == ancestorTransformNode) {
218 success = true; 245 success = true;
219 return m_identity; 246 return m_identity;
220 } 247 }
221 248
222 PrecomputedDataForAncestor& precomputedData = 249 PrecomputedDataForAncestor& precomputedData =
223 getPrecomputedDataForAncestor(ancestorTransformNode); 250 getPrecomputedDataForAncestor(ancestorTransformNode);
224 251
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 317
291 // Walk up until we find the ancestor. 318 // Walk up until we find the ancestor.
292 while (a != b) { 319 while (a != b) {
293 a = a->parent(); 320 a = a->parent();
294 b = b->parent(); 321 b = b->parent();
295 } 322 }
296 return a; 323 return a;
297 } 324 }
298 325
299 } // namespace blink 326 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698