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

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

Issue 2741103005: Reland of duce copying of local data structures in GeometryMapper and PaintLayerClipper. (Closed)
Patch Set: 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 void GeometryMapper::sourceToDestinationVisualRect(
13 const FloatRect& rect,
14 const PropertyTreeState& sourceState, 13 const PropertyTreeState& sourceState,
15 const PropertyTreeState& destinationState) { 14 const PropertyTreeState& destinationState,
15 FloatRect& rect) {
16 bool success = false; 16 bool success = false;
17 FloatClipRect result = sourceToDestinationVisualRectInternal( 17 sourceToDestinationVisualRectInternal(sourceState, destinationState, rect,
18 rect, sourceState, destinationState, success); 18 success);
19 DCHECK(success); 19 DCHECK(success);
20 return result;
21 } 20 }
22 21
23 FloatClipRect GeometryMapper::sourceToDestinationVisualRectInternal( 22 void GeometryMapper::sourceToDestinationVisualRectInternal(
24 const FloatRect& rect,
25 const PropertyTreeState& sourceState, 23 const PropertyTreeState& sourceState,
26 const PropertyTreeState& destinationState, 24 const PropertyTreeState& destinationState,
25 FloatRect& mappingRect,
27 bool& success) { 26 bool& success) {
28 FloatClipRect result = localToAncestorVisualRectInternal( 27 localToAncestorVisualRectInternal(sourceState, destinationState, mappingRect,
29 rect, sourceState, destinationState, success); 28 success);
30 // Success if destinationState is an ancestor state. 29 // Success if destinationState is an ancestor state.
31 if (success) 30 if (success)
32 return result; 31 return;
33 32
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 localToAncestorVisualRectInternal(sourceState, lcaState, mappingRect,
46 localToAncestorVisualRectInternal(rect, sourceState, lcaState, success); 45 success);
47 if (!success) 46 if (!success)
48 return result; 47 return;
49 if (!result.isInfinite()) { 48
50 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, 49 ancestorToLocalRect(lcaTransform, destinationState.transform(), mappingRect);
51 destinationState.transform());
52 result.setRect(final);
53 }
54 return result;
55 } 50 }
56 51
57 FloatRect GeometryMapper::sourceToDestinationRect( 52 void GeometryMapper::sourceToDestinationRect(
58 const FloatRect& rect,
59 const TransformPaintPropertyNode* sourceTransformNode, 53 const TransformPaintPropertyNode* sourceTransformNode,
60 const TransformPaintPropertyNode* destinationTransformNode) { 54 const TransformPaintPropertyNode* destinationTransformNode,
55 FloatRect& mappingRect) {
61 bool success = false; 56 bool success = false;
62 FloatRect result = localToAncestorRectInternal( 57 localToAncestorRectInternal(sourceTransformNode, destinationTransformNode,
63 rect, sourceTransformNode, destinationTransformNode, success); 58 mappingRect, success);
64 // Success if destinationTransformNode is an ancestor of sourceTransformNode. 59 // Success if destinationTransformNode is an ancestor of sourceTransformNode.
65 if (success) 60 if (success)
66 return result; 61 return;
67 62
68 // Otherwise first map to the least common ancestor, then map to destination. 63 // Otherwise first map to the least common ancestor, then map to destination.
69 const TransformPaintPropertyNode* lcaTransform = 64 const TransformPaintPropertyNode* lcaTransform =
70 lowestCommonAncestor(sourceTransformNode, destinationTransformNode); 65 lowestCommonAncestor(sourceTransformNode, destinationTransformNode);
71 DCHECK(lcaTransform); 66 DCHECK(lcaTransform);
72 67
73 FloatRect lcaRect = 68 localToAncestorRect(sourceTransformNode, lcaTransform, mappingRect);
74 localToAncestorRect(rect, sourceTransformNode, lcaTransform); 69 ancestorToLocalRect(lcaTransform, destinationTransformNode, mappingRect);
75 return ancestorToLocalRect(lcaRect, lcaTransform, destinationTransformNode);
76 } 70 }
77 71
78 FloatClipRect GeometryMapper::localToAncestorVisualRect( 72 void GeometryMapper::localToAncestorVisualRect(
79 const FloatRect& rect,
80 const PropertyTreeState& localState, 73 const PropertyTreeState& localState,
81 const PropertyTreeState& ancestorState) { 74 const PropertyTreeState& ancestorState,
75 FloatRect& mappingRect) {
82 bool success = false; 76 bool success = false;
83 FloatClipRect result = localToAncestorVisualRectInternal( 77 localToAncestorVisualRectInternal(localState, ancestorState, mappingRect,
84 rect, localState, ancestorState, success); 78 success);
85 DCHECK(success); 79 DCHECK(success);
86 return result;
87 } 80 }
88 81
89 FloatClipRect GeometryMapper::localToAncestorVisualRectInternal( 82 void GeometryMapper::localToAncestorVisualRectInternal(
90 const FloatRect& rect,
91 const PropertyTreeState& localState, 83 const PropertyTreeState& localState,
92 const PropertyTreeState& ancestorState, 84 const PropertyTreeState& ancestorState,
85 FloatRect& rectToMap,
93 bool& success) { 86 bool& success) {
94 if (localState == ancestorState) { 87 if (localState == ancestorState) {
95 success = true; 88 success = true;
96 return rect; 89 return;
97 } 90 }
98 91
99 if (localState.effect() != ancestorState.effect()) { 92 if (localState.effect() != ancestorState.effect()) {
100 return slowLocalToAncestorVisualRectWithEffects(rect, localState, 93 slowLocalToAncestorVisualRectWithEffects(localState, ancestorState,
101 ancestorState, success); 94 rectToMap, success);
95 return;
102 } 96 }
103 97
104 const auto& transformMatrix = localToAncestorMatrixInternal( 98 const auto& transformMatrix = localToAncestorMatrixInternal(
105 localState.transform(), ancestorState.transform(), success); 99 localState.transform(), ancestorState.transform(), success);
106 if (!success) 100 if (!success) {
107 return rect; 101 return;
102 }
108 103
109 FloatRect mappedRect = transformMatrix.mapRect(rect); 104 FloatRect mappedRect = transformMatrix.mapRect(rectToMap);
110 105
111 FloatClipRect clipRect = 106 const FloatClipRect& clipRect =
112 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), 107 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(),
113 ancestorState.transform(), success); 108 ancestorState.transform(), success);
114 109
115 if (success) { 110 if (success) {
116 clipRect.intersect(mappedRect); 111 rectToMap = clipRect.rect();
112 rectToMap.intersect(mappedRect);
117 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 113 } else if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
118 // On SPv1 we may fail when the paint invalidation container creates an 114 // On SPv1 we may fail when the paint invalidation container creates an
119 // overflow clip (in ancestorState) which is not in localState of an 115 // overflow clip (in ancestorState) which is not in localState of an
120 // out-of-flow positioned descendant. See crbug.com/513108 and layout test 116 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
121 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with 117 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
122 // --enable-prefer-compositing-to-lcd-text) for details. 118 // --enable-prefer-compositing-to-lcd-text) for details.
123 // Ignore it for SPv1 for now. 119 // Ignore it for SPv1 for now.
124 success = true; 120 success = true;
125 } 121 }
126
127 return clipRect;
128 } 122 }
129 123
130 FloatClipRect GeometryMapper::slowLocalToAncestorVisualRectWithEffects( 124 void GeometryMapper::slowLocalToAncestorVisualRectWithEffects(
131 const FloatRect& rect,
132 const PropertyTreeState& localState, 125 const PropertyTreeState& localState,
133 const PropertyTreeState& ancestorState, 126 const PropertyTreeState& ancestorState,
127 FloatRect& mappingRect,
134 bool& success) { 128 bool& success) {
135 PropertyTreeState lastTransformAndClipState(localState.transform(), 129 PropertyTreeState lastTransformAndClipState(localState.transform(),
136 localState.clip(), nullptr); 130 localState.clip(), nullptr);
137 FloatClipRect result(rect);
138 131
139 for (const auto* effect = localState.effect(); 132 for (const auto* effect = localState.effect();
140 effect && effect != ancestorState.effect(); effect = effect->parent()) { 133 effect && effect != ancestorState.effect(); effect = effect->parent()) {
141 if (!effect->hasFilterThatMovesPixels()) 134 if (!effect->hasFilterThatMovesPixels())
142 continue; 135 continue;
143 136
144 PropertyTreeState transformAndClipState(effect->localTransformSpace(), 137 PropertyTreeState transformAndClipState(effect->localTransformSpace(),
145 effect->outputClip(), nullptr); 138 effect->outputClip(), nullptr);
146 bool hasRadius = result.hasRadius(); 139 sourceToDestinationVisualRectInternal(
147 result = sourceToDestinationVisualRectInternal( 140 lastTransformAndClipState, transformAndClipState, mappingRect, success);
148 result.rect(), lastTransformAndClipState, transformAndClipState, 141 if (!success)
149 success); 142 return;
150 hasRadius |= result.hasRadius();
151 if (!success) {
152 if (hasRadius)
153 result.setHasRadius();
154 return result;
155 }
156 143
157 result = effect->mapRect(result.rect()); 144 mappingRect = effect->mapRect(mappingRect);
158 if (hasRadius)
159 result.setHasRadius();
160 lastTransformAndClipState = transformAndClipState; 145 lastTransformAndClipState = transformAndClipState;
161 } 146 }
162 147
163 PropertyTreeState finalTransformAndClipState(ancestorState.transform(), 148 PropertyTreeState finalTransformAndClipState(ancestorState.transform(),
164 ancestorState.clip(), nullptr); 149 ancestorState.clip(), nullptr);
165 bool hasRadius = result.hasRadius(); 150 sourceToDestinationVisualRectInternal(lastTransformAndClipState,
166 result = sourceToDestinationVisualRectInternal( 151 finalTransformAndClipState, mappingRect,
167 result.rect(), lastTransformAndClipState, finalTransformAndClipState, 152 success);
168 success);
169 if (hasRadius || result.hasRadius())
170 result.setHasRadius();
171 return result;
172 } 153 }
173 154
174 FloatRect GeometryMapper::localToAncestorRect( 155 void GeometryMapper::localToAncestorRect(
175 const FloatRect& rect,
176 const TransformPaintPropertyNode* localTransformNode, 156 const TransformPaintPropertyNode* localTransformNode,
177 const TransformPaintPropertyNode* ancestorTransformNode) { 157 const TransformPaintPropertyNode* ancestorTransformNode,
158 FloatRect& mappingRect) {
178 bool success = false; 159 bool success = false;
179 FloatRect result = localToAncestorRectInternal( 160 localToAncestorRectInternal(localTransformNode, ancestorTransformNode,
180 rect, localTransformNode, ancestorTransformNode, success); 161 mappingRect, success);
181 DCHECK(success); 162 DCHECK(success);
182 return result;
183 } 163 }
184 164
185 FloatRect GeometryMapper::localToAncestorRectInternal( 165 void GeometryMapper::localToAncestorRectInternal(
186 const FloatRect& rect,
187 const TransformPaintPropertyNode* localTransformNode, 166 const TransformPaintPropertyNode* localTransformNode,
188 const TransformPaintPropertyNode* ancestorTransformNode, 167 const TransformPaintPropertyNode* ancestorTransformNode,
168 FloatRect& mappingRect,
189 bool& success) { 169 bool& success) {
190 if (localTransformNode == ancestorTransformNode) { 170 if (localTransformNode == ancestorTransformNode) {
191 success = true; 171 success = true;
192 return rect; 172 return;
193 } 173 }
194 174
195 const auto& transformMatrix = localToAncestorMatrixInternal( 175 const auto& transformMatrix = localToAncestorMatrixInternal(
196 localTransformNode, ancestorTransformNode, success); 176 localTransformNode, ancestorTransformNode, success);
197 if (!success) 177 if (!success)
198 return rect; 178 return;
199 return transformMatrix.mapRect(rect); 179 mappingRect = transformMatrix.mapRect(mappingRect);
200 } 180 }
201 181
202 FloatRect GeometryMapper::ancestorToLocalRect( 182 void GeometryMapper::ancestorToLocalRect(
203 const FloatRect& rect,
204 const TransformPaintPropertyNode* ancestorTransformNode, 183 const TransformPaintPropertyNode* ancestorTransformNode,
205 const TransformPaintPropertyNode* localTransformNode) { 184 const TransformPaintPropertyNode* localTransformNode,
185 FloatRect& rect) {
206 if (localTransformNode == ancestorTransformNode) 186 if (localTransformNode == ancestorTransformNode)
207 return rect; 187 return;
208 188
209 const auto& transformMatrix = 189 const auto& transformMatrix =
210 localToAncestorMatrix(localTransformNode, ancestorTransformNode); 190 localToAncestorMatrix(localTransformNode, ancestorTransformNode);
211 DCHECK(transformMatrix.isInvertible()); 191 DCHECK(transformMatrix.isInvertible());
212 192
213 // TODO(chrishtr): Cache the inverse? 193 // TODO(chrishtr): Cache the inverse?
214 return transformMatrix.inverse().mapRect(rect); 194 rect = transformMatrix.inverse().mapRect(rect);
215 } 195 }
216 196
217 FloatClipRect GeometryMapper::localToAncestorClipRect( 197 FloatClipRect GeometryMapper::localToAncestorClipRect(
218 const PropertyTreeState& localState, 198 const PropertyTreeState& localState,
219 const PropertyTreeState& ancestorState) { 199 const PropertyTreeState& ancestorState) {
220 bool success = false; 200 bool success = false;
221 FloatClipRect result = 201 FloatClipRect result =
222 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), 202 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(),
223 ancestorState.transform(), success); 203 ancestorState.transform(), success);
224 204
225 DCHECK(success); 205 DCHECK(success);
226 206
227 return result; 207 return result;
228 } 208 }
229 209
230 FloatClipRect GeometryMapper::sourceToDestinationClipRect( 210 const FloatClipRect& GeometryMapper::sourceToDestinationClipRect(
231 const PropertyTreeState& sourceState, 211 const PropertyTreeState& sourceState,
232 const PropertyTreeState& destinationState) { 212 const PropertyTreeState& destinationState) {
233 bool success = false; 213 bool success = false;
234 FloatClipRect result = sourceToDestinationClipRectInternal( 214 const FloatClipRect& result = sourceToDestinationClipRectInternal(
235 sourceState, destinationState, success); 215 sourceState, destinationState, success);
236 DCHECK(success); 216 DCHECK(success);
237 217
238 return result; 218 return result;
239 } 219 }
240 220
241 FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( 221 const FloatClipRect& GeometryMapper::sourceToDestinationClipRectInternal(
242 const PropertyTreeState& sourceState, 222 const PropertyTreeState& sourceState,
243 const PropertyTreeState& destinationState, 223 const PropertyTreeState& destinationState,
244 bool& success) { 224 bool& success) {
245 FloatClipRect result = localToAncestorClipRectInternal( 225 const FloatClipRect& result = localToAncestorClipRectInternal(
246 sourceState.clip(), destinationState.clip(), destinationState.transform(), 226 sourceState.clip(), destinationState.clip(), destinationState.transform(),
247 success); 227 success);
248 // Success if destinationState is an ancestor state. 228 // Success if destinationState is an ancestor state.
249 if (success) 229 if (success)
250 return result; 230 return result;
251 231
252 // Otherwise first map to the lowest common ancestor, then map to 232 // Otherwise first map to the lowest common ancestor, then map to
253 // destination. 233 // destination.
254 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( 234 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor(
255 sourceState.transform(), destinationState.transform()); 235 sourceState.transform(), destinationState.transform());
256 DCHECK(lcaTransform); 236 DCHECK(lcaTransform);
257 237
258 // Assume that the clip of destinationState is an ancestor of the clip of 238 // Assume that the clip of destinationState is an ancestor of the clip of
259 // sourceState and is under the space of lcaTransform. Otherwise 239 // sourceState and is under the space of lcaTransform. Otherwise
260 // localToAncestorClipRectInternal() will fail. 240 // localToAncestorClipRectInternal() will fail.
261 PropertyTreeState lcaState = destinationState; 241 PropertyTreeState lcaState = destinationState;
262 lcaState.setTransform(lcaTransform); 242 lcaState.setTransform(lcaTransform);
263 243
264 result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(), 244 const FloatClipRect& result2 = localToAncestorClipRectInternal(
265 lcaState.transform(), success); 245 sourceState.clip(), lcaState.clip(), lcaState.transform(), success);
266 if (!success) { 246 if (!success) {
267 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 247 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
268 // On SPv1 we may fail when the paint invalidation container creates an 248 // On SPv1 we may fail when the paint invalidation container creates an
269 // overflow clip (in ancestorState) which is not in localState of an 249 // overflow clip (in ancestorState) which is not in localState of an
270 // out-of-flow positioned descendant. See crbug.com/513108 and layout 250 // out-of-flow positioned descendant. See crbug.com/513108 and layout
271 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run 251 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run
272 // with --enable-prefer-compositing-to-lcd-text) for details. 252 // with --enable-prefer-compositing-to-lcd-text) for details.
273 // Ignore it for SPv1 for now. 253 // Ignore it for SPv1 for now.
274 success = true; 254 success = true;
275 } 255 }
276 return result; 256 return result2;
277 } 257 }
278 if (!result.isInfinite()) { 258 if (!result2.isInfinite()) {
279 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, 259 FloatRect rect = result2.rect();
280 destinationState.transform()); 260 ancestorToLocalRect(lcaTransform, destinationState.transform(), rect);
281 result.setRect(final); 261 m_tempRect.setRect(rect);
262 if (result2.hasRadius())
263 m_tempRect.setHasRadius();
264 return m_tempRect;
282 } 265 }
283 return result; 266 return result2;
284 } 267 }
285 268
286 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( 269 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal(
287 const ClipPaintPropertyNode* descendant, 270 const ClipPaintPropertyNode* descendant,
288 const ClipPaintPropertyNode* ancestorClip, 271 const ClipPaintPropertyNode* ancestorClip,
289 const TransformPaintPropertyNode* ancestorTransform, 272 const TransformPaintPropertyNode* ancestorTransform,
290 bool& success) { 273 bool& success) {
291 FloatClipRect clip; 274 FloatClipRect clip;
292 if (descendant == ancestorClip) { 275 if (descendant == ancestorClip) {
293 success = true; 276 success = true;
(...skipping 28 matching lines...) Expand all
322 ++it) { 305 ++it) {
323 success = false; 306 success = false;
324 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( 307 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal(
325 (*it)->localTransformSpace(), ancestorTransform, success); 308 (*it)->localTransformSpace(), ancestorTransform, success);
326 if (!success) 309 if (!success)
327 return m_infiniteClip; 310 return m_infiniteClip;
328 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 311 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
329 clip.intersect(mappedRect); 312 clip.intersect(mappedRect);
330 if ((*it)->clipRect().isRounded()) 313 if ((*it)->clipRect().isRounded())
331 clip.setHasRadius(); 314 clip.setHasRadius();
315
332 (*it)->getClipCache().setCachedClip(clipAndTransform, clip); 316 (*it)->getClipCache().setCachedClip(clipAndTransform, clip);
333 } 317 }
334 318
335 success = true; 319 success = true;
336 320
337 const FloatClipRect* cachedClip = 321 const FloatClipRect* cachedClip =
338 descendant->getClipCache().getCachedClip(clipAndTransform); 322 descendant->getClipCache().getCachedClip(clipAndTransform);
339 DCHECK(cachedClip); 323 DCHECK(cachedClip);
324 CHECK(clip.hasRadius() == cachedClip->hasRadius());
340 return *cachedClip; 325 return *cachedClip;
341 } 326 }
342 327
343 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 328 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
344 const TransformPaintPropertyNode* localTransformNode, 329 const TransformPaintPropertyNode* localTransformNode,
345 const TransformPaintPropertyNode* ancestorTransformNode) { 330 const TransformPaintPropertyNode* ancestorTransformNode) {
346 bool success = false; 331 bool success = false;
347 const auto& result = localToAncestorMatrixInternal( 332 const auto& result = localToAncestorMatrixInternal(
348 localTransformNode, ancestorTransformNode, success); 333 localTransformNode, ancestorTransformNode, success);
349 DCHECK(success); 334 DCHECK(success);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 const TransformPaintPropertyNode*, 441 const TransformPaintPropertyNode*,
457 const TransformPaintPropertyNode*); 442 const TransformPaintPropertyNode*);
458 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 443 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
459 const ClipPaintPropertyNode*, 444 const ClipPaintPropertyNode*,
460 const ClipPaintPropertyNode*); 445 const ClipPaintPropertyNode*);
461 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 446 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
462 const ScrollPaintPropertyNode*, 447 const ScrollPaintPropertyNode*,
463 const ScrollPaintPropertyNode*); 448 const ScrollPaintPropertyNode*);
464 449
465 } // namespace blink 450 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698