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

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

Issue 2738113003: Revert of Improve performance of GeometryMapper cache. (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 {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 return rect; 207 return rect;
208 208
209 const auto& transformMatrix = 209 const auto& transformMatrix =
210 localToAncestorMatrix(localTransformNode, ancestorTransformNode); 210 localToAncestorMatrix(localTransformNode, ancestorTransformNode);
211 DCHECK(transformMatrix.isInvertible()); 211 DCHECK(transformMatrix.isInvertible());
212 212
213 // TODO(chrishtr): Cache the inverse? 213 // TODO(chrishtr): Cache the inverse?
214 return transformMatrix.inverse().mapRect(rect); 214 return transformMatrix.inverse().mapRect(rect);
215 } 215 }
216 216
217 GeometryMapper::TransformCache& GeometryMapper::getTransformCache(
218 const TransformPaintPropertyNode* ancestor) {
219 auto addResult = m_transformCache.insert(ancestor, nullptr);
220 if (addResult.isNewEntry)
221 addResult.storedValue->value = WTF::wrapUnique(new TransformCache);
222 return *addResult.storedValue->value;
223 }
224
225 GeometryMapper::ClipCache& GeometryMapper::getClipCache(
226 const ClipPaintPropertyNode* ancestorClip,
227 const TransformPaintPropertyNode* ancestorTransform) {
228 auto addResultTransform = m_clipCache.insert(ancestorClip, nullptr);
229 if (addResultTransform.isNewEntry) {
230 addResultTransform.storedValue->value =
231 WTF::wrapUnique(new TransformToClip);
232 }
233
234 auto addResultClip =
235 addResultTransform.storedValue->value->insert(ancestorTransform, nullptr);
236 if (addResultClip.isNewEntry)
237 addResultClip.storedValue->value = WTF::wrapUnique(new ClipCache);
238
239 return *addResultClip.storedValue->value;
240 }
241
217 FloatClipRect GeometryMapper::localToAncestorClipRect( 242 FloatClipRect GeometryMapper::localToAncestorClipRect(
218 const PropertyTreeState& localState, 243 const PropertyTreeState& localState,
219 const PropertyTreeState& ancestorState) { 244 const PropertyTreeState& ancestorState) {
220 bool success = false; 245 bool success = false;
221 FloatClipRect result = 246 FloatClipRect result =
222 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(), 247 localToAncestorClipRectInternal(localState.clip(), ancestorState.clip(),
223 ancestorState.transform(), success); 248 ancestorState.transform(), success);
224 249
225 DCHECK(success); 250 DCHECK(success);
226 251
(...skipping 15 matching lines...) Expand all
242 const PropertyTreeState& sourceState, 267 const PropertyTreeState& sourceState,
243 const PropertyTreeState& destinationState, 268 const PropertyTreeState& destinationState,
244 bool& success) { 269 bool& success) {
245 FloatClipRect result = localToAncestorClipRectInternal( 270 FloatClipRect result = localToAncestorClipRectInternal(
246 sourceState.clip(), destinationState.clip(), destinationState.transform(), 271 sourceState.clip(), destinationState.clip(), destinationState.transform(),
247 success); 272 success);
248 // Success if destinationState is an ancestor state. 273 // Success if destinationState is an ancestor state.
249 if (success) 274 if (success)
250 return result; 275 return result;
251 276
252 // Otherwise first map to the lowest common ancestor, then map to 277 // Otherwise first map to the lowest common ancestor, then map to destination.
253 // destination.
254 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( 278 const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor(
255 sourceState.transform(), destinationState.transform()); 279 sourceState.transform(), destinationState.transform());
256 DCHECK(lcaTransform); 280 DCHECK(lcaTransform);
257 281
258 // Assume that the clip of destinationState is an ancestor of the clip of 282 // Assume that the clip of destinationState is an ancestor of the clip of
259 // sourceState and is under the space of lcaTransform. Otherwise 283 // sourceState and is under the space of lcaTransform. Otherwise
260 // localToAncestorClipRectInternal() will fail. 284 // localToAncestorClipRectInternal() will fail.
261 PropertyTreeState lcaState = destinationState; 285 PropertyTreeState lcaState = destinationState;
262 lcaState.setTransform(lcaTransform); 286 lcaState.setTransform(lcaTransform);
263 287
264 result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(), 288 result = localToAncestorClipRectInternal(sourceState.clip(), lcaState.clip(),
265 lcaState.transform(), success); 289 lcaState.transform(), success);
266 if (!success) { 290 if (!success) {
267 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { 291 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) {
268 // On SPv1 we may fail when the paint invalidation container creates an 292 // On SPv1 we may fail when the paint invalidation container creates an
269 // overflow clip (in ancestorState) which is not in localState of an 293 // overflow clip (in ancestorState) which is not in localState of an
270 // out-of-flow positioned descendant. See crbug.com/513108 and layout 294 // out-of-flow positioned descendant. See crbug.com/513108 and layout test
271 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run 295 // compositing/overflow/handle-non-ancestor-clip-parent.html (run with
272 // with --enable-prefer-compositing-to-lcd-text) for details. 296 // --enable-prefer-compositing-to-lcd-text) for details.
273 // Ignore it for SPv1 for now. 297 // Ignore it for SPv1 for now.
274 success = true; 298 success = true;
275 } 299 }
276 return result; 300 return result;
277 } 301 }
278 if (!result.isInfinite()) { 302 if (!result.isInfinite()) {
279 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform, 303 FloatRect final = ancestorToLocalRect(result.rect(), lcaTransform,
280 destinationState.transform()); 304 destinationState.transform());
281 result.setRect(final); 305 result.setRect(final);
282 } 306 }
283 return result; 307 return result;
284 } 308 }
285 309
286 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( 310 FloatClipRect GeometryMapper::localToAncestorClipRectInternal(
287 const ClipPaintPropertyNode* descendant, 311 const ClipPaintPropertyNode* descendant,
288 const ClipPaintPropertyNode* ancestorClip, 312 const ClipPaintPropertyNode* ancestorClip,
289 const TransformPaintPropertyNode* ancestorTransform, 313 const TransformPaintPropertyNode* ancestorTransform,
290 bool& success) { 314 bool& success) {
291 FloatClipRect clip; 315 FloatClipRect clip;
292 if (descendant == ancestorClip) { 316 if (descendant == ancestorClip) {
293 success = true; 317 success = true;
294 return m_infiniteClip; 318 // Return an infinite clip.
319 return clip;
295 } 320 }
296 321
322 ClipCache& clipCache = getClipCache(ancestorClip, ancestorTransform);
297 const ClipPaintPropertyNode* clipNode = descendant; 323 const ClipPaintPropertyNode* clipNode = descendant;
298 Vector<const ClipPaintPropertyNode*> intermediateNodes; 324 Vector<const ClipPaintPropertyNode*> intermediateNodes;
299 325
300 GeometryMapperClipCache::ClipAndTransform clipAndTransform(ancestorClip,
301 ancestorTransform);
302 // Iterate over the path from localState.clip to ancestorState.clip. Stop if 326 // Iterate over the path from localState.clip to ancestorState.clip. Stop if
303 // we've found a memoized (precomputed) clip for any particular node. 327 // we've found a memoized (precomputed) clip for any particular node.
304 while (clipNode && clipNode != ancestorClip) { 328 while (clipNode && clipNode != ancestorClip) {
305 if (const FloatClipRect* cachedClip = 329 auto it = clipCache.find(clipNode);
306 clipNode->getClipCache().getCachedClip(clipAndTransform)) { 330 if (it != clipCache.end()) {
307 clip = *cachedClip; 331 clip = it->value;
308 break; 332 break;
309 } 333 }
310
311 intermediateNodes.push_back(clipNode); 334 intermediateNodes.push_back(clipNode);
312 clipNode = clipNode->parent(); 335 clipNode = clipNode->parent();
313 } 336 }
314 if (!clipNode) { 337 if (!clipNode) {
315 success = false; 338 success = false;
316 return m_infiniteClip; 339 return clip;
317 } 340 }
318 341
319 // Iterate down from the top intermediate node found in the previous loop, 342 // Iterate down from the top intermediate node found in the previous loop,
320 // computing and memoizing clip rects as we go. 343 // computing and memoizing clip rects as we go.
321 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 344 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
322 ++it) { 345 ++it) {
323 success = false; 346 success = false;
324 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( 347 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal(
325 (*it)->localTransformSpace(), ancestorTransform, success); 348 (*it)->localTransformSpace(), ancestorTransform, success);
326 if (!success) 349 if (!success)
327 return m_infiniteClip; 350 return clip;
328 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); 351 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect());
329 clip.intersect(mappedRect); 352 clip.intersect(mappedRect);
330 if ((*it)->clipRect().isRounded()) 353 if ((*it)->clipRect().isRounded())
331 clip.setHasRadius(); 354 clip.setHasRadius();
332 (*it)->getClipCache().setCachedClip(clipAndTransform, clip); 355 clipCache.set(*it, clip);
333 } 356 }
334 357
335 success = true; 358 success = true;
336 359 return clipCache.find(descendant)->value;
337 const FloatClipRect* cachedClip =
338 descendant->getClipCache().getCachedClip(clipAndTransform);
339 DCHECK(cachedClip);
340 return *cachedClip;
341 } 360 }
342 361
343 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 362 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
344 const TransformPaintPropertyNode* localTransformNode, 363 const TransformPaintPropertyNode* localTransformNode,
345 const TransformPaintPropertyNode* ancestorTransformNode) { 364 const TransformPaintPropertyNode* ancestorTransformNode) {
346 bool success = false; 365 bool success = false;
347 const auto& result = localToAncestorMatrixInternal( 366 const auto& result = localToAncestorMatrixInternal(
348 localTransformNode, ancestorTransformNode, success); 367 localTransformNode, ancestorTransformNode, success);
349 DCHECK(success); 368 DCHECK(success);
350 return result; 369 return result;
351 } 370 }
352 371
353 const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( 372 const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal(
354 const TransformPaintPropertyNode* localTransformNode, 373 const TransformPaintPropertyNode* localTransformNode,
355 const TransformPaintPropertyNode* ancestorTransformNode, 374 const TransformPaintPropertyNode* ancestorTransformNode,
356 bool& success) { 375 bool& success) {
357 if (localTransformNode == ancestorTransformNode) { 376 if (localTransformNode == ancestorTransformNode) {
358 success = true; 377 success = true;
359 return m_identity; 378 return m_identity;
360 } 379 }
361 380
381 TransformCache& transformCache = getTransformCache(ancestorTransformNode);
382
362 const TransformPaintPropertyNode* transformNode = localTransformNode; 383 const TransformPaintPropertyNode* transformNode = localTransformNode;
363 Vector<const TransformPaintPropertyNode*> intermediateNodes; 384 Vector<const TransformPaintPropertyNode*> intermediateNodes;
364 TransformationMatrix transformMatrix; 385 TransformationMatrix transformMatrix;
365 386
366 // Iterate over the path from localTransformNode to ancestorState.transform. 387 // Iterate over the path from localTransformNode to ancestorState.transform.
367 // Stop if we've found a memoized (precomputed) transform for any particular 388 // Stop if we've found a memoized (precomputed) transform for any particular
368 // node. 389 // node.
369 while (transformNode && transformNode != ancestorTransformNode) { 390 while (transformNode && transformNode != ancestorTransformNode) {
370 if (const TransformationMatrix* cachedMatrix = 391 auto it = transformCache.find(transformNode);
371 transformNode->getTransformCache().getCachedTransform( 392 if (it != transformCache.end()) {
372 ancestorTransformNode)) { 393 transformMatrix = it->value;
373 transformMatrix = *cachedMatrix;
374 break; 394 break;
375 } 395 }
376
377 intermediateNodes.push_back(transformNode); 396 intermediateNodes.push_back(transformNode);
378 transformNode = transformNode->parent(); 397 transformNode = transformNode->parent();
379 } 398 }
380 if (!transformNode) { 399 if (!transformNode) {
381 success = false; 400 success = false;
382 return m_identity; 401 return m_identity;
383 } 402 }
384 403
385 // Iterate down from the top intermediate node found in the previous loop, 404 // Iterate down from the top intermediate node found in the previous loop,
386 // computing and memoizing transforms as we go. 405 // computing and memoizing transforms as we go.
387 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); 406 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend();
388 it++) { 407 it++) {
389 TransformationMatrix localTransformMatrix = (*it)->matrix(); 408 TransformationMatrix localTransformMatrix = (*it)->matrix();
390 localTransformMatrix.applyTransformOrigin((*it)->origin()); 409 localTransformMatrix.applyTransformOrigin((*it)->origin());
391 transformMatrix = transformMatrix * localTransformMatrix; 410 transformMatrix = transformMatrix * localTransformMatrix;
392 (*it)->getTransformCache().setCachedTransform(ancestorTransformNode, 411 transformCache.set(*it, transformMatrix);
393 transformMatrix);
394 } 412 }
395 success = true; 413 success = true;
396 const TransformationMatrix* cachedMatrix = 414 return transformCache.find(localTransformNode)->value;
397 localTransformNode->getTransformCache().getCachedTransform(
398 ancestorTransformNode);
399 DCHECK(cachedMatrix);
400 return *cachedMatrix;
401 } 415 }
402 416
403 void GeometryMapper::clearCache() { 417 void GeometryMapper::clearCache() {
404 GeometryMapperTransformCache::clearCache(); 418 m_transformCache.clear();
405 GeometryMapperClipCache::clearCache(); 419 m_clipCache.clear();
406 } 420 }
407 421
408 namespace { 422 namespace {
409 423
410 template <typename NodeType> 424 template <typename NodeType>
411 unsigned nodeDepth(const NodeType* node) { 425 unsigned nodeDepth(const NodeType* node) {
412 unsigned depth = 0; 426 unsigned depth = 0;
413 while (node) { 427 while (node) {
414 depth++; 428 depth++;
415 node = node->parent(); 429 node = node->parent();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 const TransformPaintPropertyNode*, 470 const TransformPaintPropertyNode*,
457 const TransformPaintPropertyNode*); 471 const TransformPaintPropertyNode*);
458 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 472 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
459 const ClipPaintPropertyNode*, 473 const ClipPaintPropertyNode*,
460 const ClipPaintPropertyNode*); 474 const ClipPaintPropertyNode*);
461 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( 475 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor(
462 const ScrollPaintPropertyNode*, 476 const ScrollPaintPropertyNode*,
463 const ScrollPaintPropertyNode*); 477 const ScrollPaintPropertyNode*);
464 478
465 } // namespace blink 479 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698