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

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

Issue 2390443002: Unify GeometryPropertyTreeState and PropertyTreeState (Closed)
Patch Set: rebase x2 Created 4 years, 2 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/geometry/LayoutRect.h" 7 #include "platform/geometry/LayoutRect.h"
8 #include "platform/graphics/paint/ClipPaintPropertyNode.h"
9 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
10 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
11 8
12 namespace blink { 9 namespace blink {
13 10
14 FloatRect GeometryMapper::mapToVisualRectInDestinationSpace( 11 FloatRect GeometryMapper::mapToVisualRectInDestinationSpace(
15 const FloatRect& rect, 12 const FloatRect& rect,
16 const GeometryPropertyTreeState& sourceState, 13 const PropertyTreeState& sourceState,
17 const GeometryPropertyTreeState& destinationState, 14 const PropertyTreeState& destinationState,
18 bool& success) { 15 bool& success) {
19 FloatRect result = localToVisualRectInAncestorSpace( 16 FloatRect result = localToVisualRectInAncestorSpace(
20 rect, sourceState, destinationState, success); 17 rect, sourceState, destinationState, success);
21 if (success) 18 if (success)
22 return result; 19 return result;
23 return slowMapToVisualRectInDestinationSpace(rect, sourceState, 20 return slowMapToVisualRectInDestinationSpace(rect, sourceState,
24 destinationState, success); 21 destinationState, success);
25 } 22 }
26 23
27 FloatRect GeometryMapper::mapRectToDestinationSpace( 24 FloatRect GeometryMapper::mapRectToDestinationSpace(
28 const FloatRect& rect, 25 const FloatRect& rect,
29 const GeometryPropertyTreeState& sourceState, 26 const PropertyTreeState& sourceState,
30 const GeometryPropertyTreeState& destinationState, 27 const PropertyTreeState& destinationState,
31 bool& success) { 28 bool& success) {
32 FloatRect result = 29 FloatRect result =
33 localToAncestorRect(rect, sourceState, destinationState, success); 30 localToAncestorRect(rect, sourceState, destinationState, success);
34 if (success) 31 if (success)
35 return result; 32 return result;
36 return slowMapRectToDestinationSpace(rect, sourceState, destinationState, 33 return slowMapRectToDestinationSpace(rect, sourceState, destinationState,
37 success); 34 success);
38 } 35 }
39 36
40 FloatRect GeometryMapper::slowMapToVisualRectInDestinationSpace( 37 FloatRect GeometryMapper::slowMapToVisualRectInDestinationSpace(
41 const FloatRect& rect, 38 const FloatRect& rect,
42 const GeometryPropertyTreeState& sourceState, 39 const PropertyTreeState& sourceState,
43 const GeometryPropertyTreeState& destinationState, 40 const PropertyTreeState& destinationState,
44 bool& success) { 41 bool& success) {
45 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor( 42 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor(
46 sourceState.transform.get(), destinationState.transform.get()); 43 sourceState.transform(), destinationState.transform());
47 DCHECK(lcaTransform); 44 DCHECK(lcaTransform);
48 45
49 // Assume that the clip of destinationState is an ancestor of the clip of sour ceState 46 // Assume that the clip of destinationState is an ancestor of the clip of sour ceState
50 // and is under the space of lcaTransform. Otherwise localToAncestorClipRect() will fail. 47 // and is under the space of lcaTransform. Otherwise localToAncestorClipRect() will fail.
51 GeometryPropertyTreeState lcaState = destinationState; 48 PropertyTreeState lcaState = destinationState;
52 lcaState.transform = lcaTransform; 49 lcaState.setTransform(lcaTransform);
53 50
54 const auto clipRect = localToAncestorClipRect(sourceState, lcaState, success); 51 const auto clipRect = localToAncestorClipRect(sourceState, lcaState, success);
55 if (!success) 52 if (!success)
56 return rect; 53 return rect;
57 54
58 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); 55 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success);
59 DCHECK(success); 56 DCHECK(success);
60 result.intersect(clipRect); 57 result.intersect(clipRect);
61 58
62 const TransformationMatrix& destinationToLca = localToAncestorMatrix( 59 const TransformationMatrix& destinationToLca =
63 destinationState.transform.get(), lcaState, success); 60 localToAncestorMatrix(destinationState.transform(), lcaState, success);
64 DCHECK(success); 61 DCHECK(success);
65 if (destinationToLca.isInvertible()) { 62 if (destinationToLca.isInvertible()) {
66 success = true; 63 success = true;
67 return destinationToLca.inverse().mapRect(result); 64 return destinationToLca.inverse().mapRect(result);
68 } 65 }
69 success = false; 66 success = false;
70 return rect; 67 return rect;
71 } 68 }
72 69
73 FloatRect GeometryMapper::slowMapRectToDestinationSpace( 70 FloatRect GeometryMapper::slowMapRectToDestinationSpace(
74 const FloatRect& rect, 71 const FloatRect& rect,
75 const GeometryPropertyTreeState& sourceState, 72 const PropertyTreeState& sourceState,
76 const GeometryPropertyTreeState& destinationState, 73 const PropertyTreeState& destinationState,
77 bool& success) { 74 bool& success) {
78 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor( 75 const TransformPaintPropertyNode* lcaTransform = leastCommonAncestor(
79 sourceState.transform.get(), destinationState.transform.get()); 76 sourceState.transform(), destinationState.transform());
80 DCHECK(lcaTransform); 77 DCHECK(lcaTransform);
81 GeometryPropertyTreeState lcaState = sourceState; 78 PropertyTreeState lcaState = sourceState;
82 lcaState.transform = lcaTransform; 79 lcaState.setTransform(lcaTransform);
83 80
84 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); 81 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success);
85 DCHECK(success); 82 DCHECK(success);
86 83
87 const TransformationMatrix& destinationToLca = localToAncestorMatrix( 84 const TransformationMatrix& destinationToLca =
88 destinationState.transform.get(), lcaState, success); 85 localToAncestorMatrix(destinationState.transform(), lcaState, success);
89 DCHECK(success); 86 DCHECK(success);
90 if (destinationToLca.isInvertible()) { 87 if (destinationToLca.isInvertible()) {
91 success = true; 88 success = true;
92 return destinationToLca.inverse().mapRect(result); 89 return destinationToLca.inverse().mapRect(result);
93 } 90 }
94 success = false; 91 success = false;
95 return rect; 92 return rect;
96 } 93 }
97 94
98 FloatRect GeometryMapper::localToVisualRectInAncestorSpace( 95 FloatRect GeometryMapper::localToVisualRectInAncestorSpace(
99 const FloatRect& rect, 96 const FloatRect& rect,
100 const GeometryPropertyTreeState& localState, 97 const PropertyTreeState& localState,
101 const GeometryPropertyTreeState& ancestorState, 98 const PropertyTreeState& ancestorState,
102 bool& success) { 99 bool& success) {
103 const auto& transformMatrix = 100 const auto& transformMatrix =
104 localToAncestorMatrix(localState.transform.get(), ancestorState, success); 101 localToAncestorMatrix(localState.transform(), ancestorState, success);
105 if (!success) 102 if (!success)
106 return rect; 103 return rect;
107 104
108 FloatRect mappedRect = transformMatrix.mapRect(rect); 105 FloatRect mappedRect = transformMatrix.mapRect(rect);
109 106
110 const auto clipRect = 107 const auto clipRect =
111 localToAncestorClipRect(localState, ancestorState, success); 108 localToAncestorClipRect(localState, ancestorState, success);
112 DCHECK(success); 109 DCHECK(success);
113 110
114 mappedRect.intersect(clipRect); 111 mappedRect.intersect(clipRect);
115 return mappedRect; 112 return mappedRect;
116 } 113 }
117 114
118 FloatRect GeometryMapper::localToAncestorRect( 115 FloatRect GeometryMapper::localToAncestorRect(
119 const FloatRect& rect, 116 const FloatRect& rect,
120 const GeometryPropertyTreeState& localState, 117 const PropertyTreeState& localState,
121 const GeometryPropertyTreeState& ancestorState, 118 const PropertyTreeState& ancestorState,
122 bool& success) { 119 bool& success) {
123 const auto& transformMatrix = 120 const auto& transformMatrix =
124 localToAncestorMatrix(localState.transform.get(), ancestorState, success); 121 localToAncestorMatrix(localState.transform(), ancestorState, success);
125 if (!success) 122 if (!success)
126 return rect; 123 return rect;
127 return transformMatrix.mapRect(rect); 124 return transformMatrix.mapRect(rect);
128 } 125 }
129 126
130 FloatRect GeometryMapper::ancestorToLocalRect( 127 FloatRect GeometryMapper::ancestorToLocalRect(
131 const FloatRect& rect, 128 const FloatRect& rect,
132 const GeometryPropertyTreeState& localState, 129 const PropertyTreeState& localState,
133 const GeometryPropertyTreeState& ancestorState, 130 const PropertyTreeState& ancestorState,
134 bool& success) { 131 bool& success) {
135 const auto& transformMatrix = 132 const auto& transformMatrix =
136 localToAncestorMatrix(localState.transform.get(), ancestorState, success); 133 localToAncestorMatrix(localState.transform(), ancestorState, success);
137 if (!success) 134 if (!success)
138 return rect; 135 return rect;
139 136
140 if (!transformMatrix.isInvertible()) { 137 if (!transformMatrix.isInvertible()) {
141 success = false; 138 success = false;
142 return rect; 139 return rect;
143 } 140 }
144 success = true; 141 success = true;
145 142
146 // TODO(chrishtr): Cache the inverse? 143 // TODO(chrishtr): Cache the inverse?
147 return transformMatrix.inverse().mapRect(rect); 144 return transformMatrix.inverse().mapRect(rect);
148 } 145 }
149 146
150 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor( 147 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(
151 const GeometryPropertyTreeState& ancestorState) { 148 const PropertyTreeState& ancestorState) {
152 auto addResult = m_data.add(ancestorState.transform.get(), nullptr); 149 auto addResult = m_data.add(ancestorState.transform(), nullptr);
153 if (addResult.isNewEntry) 150 if (addResult.isNewEntry)
154 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 151 addResult.storedValue->value = PrecomputedDataForAncestor::create();
155 return *addResult.storedValue->value; 152 return *addResult.storedValue->value;
156 } 153 }
157 154
158 FloatRect GeometryMapper::localToAncestorClipRect( 155 FloatRect GeometryMapper::localToAncestorClipRect(
159 const GeometryPropertyTreeState& localState, 156 const PropertyTreeState& localState,
160 const GeometryPropertyTreeState& ancestorState, 157 const PropertyTreeState& ancestorState,
161 bool& success) { 158 bool& success) {
162 PrecomputedDataForAncestor& precomputedData = 159 PrecomputedDataForAncestor& precomputedData =
163 getPrecomputedDataForAncestor(ancestorState); 160 getPrecomputedDataForAncestor(ancestorState);
164 const ClipPaintPropertyNode* clipNode = localState.clip.get(); 161 const ClipPaintPropertyNode* clipNode = localState.clip();
165 Vector<const ClipPaintPropertyNode*> intermediateNodes; 162 Vector<const ClipPaintPropertyNode*> intermediateNodes;
166 FloatRect clip(LayoutRect::infiniteIntRect()); 163 FloatRect clip(LayoutRect::infiniteIntRect());
167 164
168 bool found = false; 165 bool found = false;
169 // Iterate over the path from localState.clip to ancestorState.clip. Stop if w e've found a memoized (precomputed) clip 166 // Iterate over the path from localState.clip to ancestorState.clip. Stop if w e've found a memoized (precomputed) clip
170 // for any particular node. 167 // for any particular node.
171 while (clipNode) { 168 while (clipNode) {
172 auto it = precomputedData.toAncestorClipRects.find(clipNode); 169 auto it = precomputedData.toAncestorClipRects.find(clipNode);
173 if (it != precomputedData.toAncestorClipRects.end()) { 170 if (it != precomputedData.toAncestorClipRects.end()) {
174 clip = it->value; 171 clip = it->value;
175 found = true; 172 found = true;
176 break; 173 break;
177 } 174 }
178 intermediateNodes.append(clipNode); 175 intermediateNodes.append(clipNode);
179 176
180 if (clipNode == ancestorState.clip) 177 if (clipNode == ancestorState.clip())
181 break; 178 break;
182 179
183 clipNode = clipNode->parent(); 180 clipNode = clipNode->parent();
184 } 181 }
185 if (clipNode != ancestorState.clip && !found) { 182 if (clipNode != ancestorState.clip() && !found) {
186 success = false; 183 success = false;
187 return clip; 184 return clip;
188 } 185 }
189 186
190 // Iterate down from the top intermediate node found in the previous loop, com puting and memoizing clip rects as we go. 187 // Iterate down from the top intermediate node found in the previous loop, com puting and memoizing clip rects as we go.
191 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 188 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
192 ++it) { 189 ++it) {
193 if ((*it) != ancestorState.clip) { 190 if ((*it) != ancestorState.clip()) {
194 success = false; 191 success = false;
195 const TransformationMatrix& transformMatrix = localToAncestorMatrix( 192 const TransformationMatrix& transformMatrix = localToAncestorMatrix(
196 (*it)->localTransformSpace(), ancestorState, success); 193 (*it)->localTransformSpace(), ancestorState, success);
197 if (!success) 194 if (!success)
198 return clip; 195 return clip;
199 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 196 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
200 clip.intersect(mappedRect); 197 clip.intersect(mappedRect);
201 } 198 }
202 199
203 precomputedData.toAncestorClipRects.set(*it, clip); 200 precomputedData.toAncestorClipRects.set(*it, clip);
204 } 201 }
205 202
206 success = true; 203 success = true;
207 return precomputedData.toAncestorClipRects.find(localState.clip.get())->value; 204 return precomputedData.toAncestorClipRects.find(localState.clip())->value;
208 } 205 }
209 206
210 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 207 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
211 const TransformPaintPropertyNode* localTransformNode, 208 const TransformPaintPropertyNode* localTransformNode,
212 const GeometryPropertyTreeState& ancestorState, 209 const PropertyTreeState& ancestorState,
213 bool& success) { 210 bool& success) {
214 PrecomputedDataForAncestor& precomputedData = 211 PrecomputedDataForAncestor& precomputedData =
215 getPrecomputedDataForAncestor(ancestorState); 212 getPrecomputedDataForAncestor(ancestorState);
216 213
217 const TransformPaintPropertyNode* transformNode = localTransformNode; 214 const TransformPaintPropertyNode* transformNode = localTransformNode;
218 Vector<const TransformPaintPropertyNode*> intermediateNodes; 215 Vector<const TransformPaintPropertyNode*> intermediateNodes;
219 TransformationMatrix transformMatrix; 216 TransformationMatrix transformMatrix;
220 217
221 bool found = false; 218 bool found = false;
222 // Iterate over the path from localTransformNode to ancestorState.transform. S top if we've found a memoized (precomputed) transform 219 // Iterate over the path from localTransformNode to ancestorState.transform. S top if we've found a memoized (precomputed) transform
223 // for any particular node. 220 // for any particular node.
224 while (transformNode) { 221 while (transformNode) {
225 auto it = precomputedData.toAncestorTransforms.find(transformNode); 222 auto it = precomputedData.toAncestorTransforms.find(transformNode);
226 if (it != precomputedData.toAncestorTransforms.end()) { 223 if (it != precomputedData.toAncestorTransforms.end()) {
227 transformMatrix = it->value; 224 transformMatrix = it->value;
228 found = true; 225 found = true;
229 break; 226 break;
230 } 227 }
231 228
232 intermediateNodes.append(transformNode); 229 intermediateNodes.append(transformNode);
233 230
234 if (transformNode == ancestorState.transform) 231 if (transformNode == ancestorState.transform())
235 break; 232 break;
236 233
237 transformNode = transformNode->parent(); 234 transformNode = transformNode->parent();
238 } 235 }
239 if (!found && transformNode != ancestorState.transform) { 236 if (!found && transformNode != ancestorState.transform()) {
240 success = false; 237 success = false;
241 return m_identity; 238 return m_identity;
242 } 239 }
243 240
244 // Iterate down from the top intermediate node found in the previous loop, com puting and memoizing transforms as we go. 241 // Iterate down from the top intermediate node found in the previous loop, com puting and memoizing transforms as we go.
245 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 242 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
246 it++) { 243 it++) {
247 if ((*it) != ancestorState.transform) { 244 if ((*it) != ancestorState.transform()) {
248 TransformationMatrix localTransformMatrix = (*it)->matrix(); 245 TransformationMatrix localTransformMatrix = (*it)->matrix();
249 localTransformMatrix.applyTransformOrigin((*it)->origin()); 246 localTransformMatrix.applyTransformOrigin((*it)->origin());
250 transformMatrix = transformMatrix * localTransformMatrix; 247 transformMatrix = transformMatrix * localTransformMatrix;
251 } 248 }
252 249
253 precomputedData.toAncestorTransforms.set(*it, transformMatrix); 250 precomputedData.toAncestorTransforms.set(*it, transformMatrix);
254 } 251 }
255 success = true; 252 success = true;
256 return precomputedData.toAncestorTransforms.find(localTransformNode)->value; 253 return precomputedData.toAncestorTransforms.find(localTransformNode)->value;
257 } 254 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 287
291 // Walk up until we find the ancestor. 288 // Walk up until we find the ancestor.
292 while (a != b) { 289 while (a != b) {
293 a = a->parent(); 290 a = a->parent();
294 b = b->parent(); 291 b = b->parent();
295 } 292 }
296 return a; 293 return a;
297 } 294 }
298 295
299 } // namespace blink 296 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698