| OLD | NEW |
| 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 const TransformationMatrix& GeometryMapper::identityMatrix() { |
| 13 DEFINE_STATIC_LOCAL(TransformationMatrix, identity, (TransformationMatrix())); |
| 14 return identity; |
| 15 } |
| 16 |
| 17 const FloatClipRect& GeometryMapper::infiniteClip() { |
| 18 DEFINE_STATIC_LOCAL(FloatClipRect, infinite, (FloatClipRect())); |
| 19 return infinite; |
| 20 } |
| 21 |
| 22 FloatClipRect& GeometryMapper::tempRect() { |
| 23 DEFINE_STATIC_LOCAL(FloatClipRect, temp, (FloatClipRect())); |
| 24 return temp; |
| 25 } |
| 26 |
| 12 void GeometryMapper::sourceToDestinationVisualRect( | 27 void GeometryMapper::sourceToDestinationVisualRect( |
| 13 const PropertyTreeState& sourceState, | 28 const PropertyTreeState& sourceState, |
| 14 const PropertyTreeState& destinationState, | 29 const PropertyTreeState& destinationState, |
| 15 FloatRect& rect) { | 30 FloatRect& rect) { |
| 16 bool success = false; | 31 bool success = false; |
| 17 sourceToDestinationVisualRectInternal(sourceState, destinationState, rect, | 32 sourceToDestinationVisualRectInternal(sourceState, destinationState, rect, |
| 18 success); | 33 success); |
| 19 DCHECK(success); | 34 DCHECK(success); |
| 20 } | 35 } |
| 21 | 36 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run | 266 // test compositing/overflow/handle-non-ancestor-clip-parent.html (run |
| 252 // with --enable-prefer-compositing-to-lcd-text) for details. | 267 // with --enable-prefer-compositing-to-lcd-text) for details. |
| 253 // Ignore it for SPv1 for now. | 268 // Ignore it for SPv1 for now. |
| 254 success = true; | 269 success = true; |
| 255 } | 270 } |
| 256 return result2; | 271 return result2; |
| 257 } | 272 } |
| 258 if (!result2.isInfinite()) { | 273 if (!result2.isInfinite()) { |
| 259 FloatRect rect = result2.rect(); | 274 FloatRect rect = result2.rect(); |
| 260 ancestorToLocalRect(lcaTransform, destinationState.transform(), rect); | 275 ancestorToLocalRect(lcaTransform, destinationState.transform(), rect); |
| 261 m_tempRect.setRect(rect); | 276 FloatClipRect& temp = tempRect(); |
| 277 temp.setRect(rect); |
| 262 if (result2.hasRadius()) | 278 if (result2.hasRadius()) |
| 263 m_tempRect.setHasRadius(); | 279 temp.setHasRadius(); |
| 264 return m_tempRect; | 280 return temp; |
| 265 } | 281 } |
| 266 return result2; | 282 return result2; |
| 267 } | 283 } |
| 268 | 284 |
| 269 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( | 285 const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( |
| 270 const ClipPaintPropertyNode* descendant, | 286 const ClipPaintPropertyNode* descendant, |
| 271 const ClipPaintPropertyNode* ancestorClip, | 287 const ClipPaintPropertyNode* ancestorClip, |
| 272 const TransformPaintPropertyNode* ancestorTransform, | 288 const TransformPaintPropertyNode* ancestorTransform, |
| 273 bool& success) { | 289 bool& success) { |
| 274 FloatClipRect clip; | 290 FloatClipRect clip; |
| 275 if (descendant == ancestorClip) { | 291 if (descendant == ancestorClip) { |
| 276 success = true; | 292 success = true; |
| 277 return m_infiniteClip; | 293 return infiniteClip(); |
| 278 } | 294 } |
| 279 | 295 |
| 280 const ClipPaintPropertyNode* clipNode = descendant; | 296 const ClipPaintPropertyNode* clipNode = descendant; |
| 281 Vector<const ClipPaintPropertyNode*> intermediateNodes; | 297 Vector<const ClipPaintPropertyNode*> intermediateNodes; |
| 282 | 298 |
| 283 GeometryMapperClipCache::ClipAndTransform clipAndTransform(ancestorClip, | 299 GeometryMapperClipCache::ClipAndTransform clipAndTransform(ancestorClip, |
| 284 ancestorTransform); | 300 ancestorTransform); |
| 285 // Iterate over the path from localState.clip to ancestorState.clip. Stop if | 301 // Iterate over the path from localState.clip to ancestorState.clip. Stop if |
| 286 // we've found a memoized (precomputed) clip for any particular node. | 302 // we've found a memoized (precomputed) clip for any particular node. |
| 287 while (clipNode && clipNode != ancestorClip) { | 303 while (clipNode && clipNode != ancestorClip) { |
| 288 if (const FloatClipRect* cachedClip = | 304 if (const FloatClipRect* cachedClip = |
| 289 clipNode->getClipCache().getCachedClip(clipAndTransform)) { | 305 clipNode->getClipCache().getCachedClip(clipAndTransform)) { |
| 290 clip = *cachedClip; | 306 clip = *cachedClip; |
| 291 break; | 307 break; |
| 292 } | 308 } |
| 293 | 309 |
| 294 intermediateNodes.push_back(clipNode); | 310 intermediateNodes.push_back(clipNode); |
| 295 clipNode = clipNode->parent(); | 311 clipNode = clipNode->parent(); |
| 296 } | 312 } |
| 297 if (!clipNode) { | 313 if (!clipNode) { |
| 298 success = false; | 314 success = false; |
| 299 return m_infiniteClip; | 315 return infiniteClip(); |
| 300 } | 316 } |
| 301 | 317 |
| 302 // Iterate down from the top intermediate node found in the previous loop, | 318 // Iterate down from the top intermediate node found in the previous loop, |
| 303 // computing and memoizing clip rects as we go. | 319 // computing and memoizing clip rects as we go. |
| 304 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); | 320 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); |
| 305 ++it) { | 321 ++it) { |
| 306 success = false; | 322 success = false; |
| 307 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( | 323 const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( |
| 308 (*it)->localTransformSpace(), ancestorTransform, success); | 324 (*it)->localTransformSpace(), ancestorTransform, success); |
| 309 if (!success) | 325 if (!success) |
| 310 return m_infiniteClip; | 326 return infiniteClip(); |
| 311 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); | 327 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); |
| 312 clip.intersect(mappedRect); | 328 clip.intersect(mappedRect); |
| 313 if ((*it)->clipRect().isRounded()) | 329 if ((*it)->clipRect().isRounded()) |
| 314 clip.setHasRadius(); | 330 clip.setHasRadius(); |
| 315 | 331 |
| 316 (*it)->getClipCache().setCachedClip(clipAndTransform, clip); | 332 (*it)->getClipCache().setCachedClip(clipAndTransform, clip); |
| 317 } | 333 } |
| 318 | 334 |
| 319 success = true; | 335 success = true; |
| 320 | 336 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 334 DCHECK(success); | 350 DCHECK(success); |
| 335 return result; | 351 return result; |
| 336 } | 352 } |
| 337 | 353 |
| 338 const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( | 354 const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( |
| 339 const TransformPaintPropertyNode* localTransformNode, | 355 const TransformPaintPropertyNode* localTransformNode, |
| 340 const TransformPaintPropertyNode* ancestorTransformNode, | 356 const TransformPaintPropertyNode* ancestorTransformNode, |
| 341 bool& success) { | 357 bool& success) { |
| 342 if (localTransformNode == ancestorTransformNode) { | 358 if (localTransformNode == ancestorTransformNode) { |
| 343 success = true; | 359 success = true; |
| 344 return m_identity; | 360 return identityMatrix(); |
| 345 } | 361 } |
| 346 | 362 |
| 347 const TransformPaintPropertyNode* transformNode = localTransformNode; | 363 const TransformPaintPropertyNode* transformNode = localTransformNode; |
| 348 Vector<const TransformPaintPropertyNode*> intermediateNodes; | 364 Vector<const TransformPaintPropertyNode*> intermediateNodes; |
| 349 TransformationMatrix transformMatrix; | 365 TransformationMatrix transformMatrix; |
| 350 | 366 |
| 351 // Iterate over the path from localTransformNode to ancestorState.transform. | 367 // Iterate over the path from localTransformNode to ancestorState.transform. |
| 352 // Stop if we've found a memoized (precomputed) transform for any particular | 368 // Stop if we've found a memoized (precomputed) transform for any particular |
| 353 // node. | 369 // node. |
| 354 while (transformNode && transformNode != ancestorTransformNode) { | 370 while (transformNode && transformNode != ancestorTransformNode) { |
| 355 if (const TransformationMatrix* cachedMatrix = | 371 if (const TransformationMatrix* cachedMatrix = |
| 356 transformNode->getTransformCache().getCachedTransform( | 372 transformNode->getTransformCache().getCachedTransform( |
| 357 ancestorTransformNode)) { | 373 ancestorTransformNode)) { |
| 358 transformMatrix = *cachedMatrix; | 374 transformMatrix = *cachedMatrix; |
| 359 break; | 375 break; |
| 360 } | 376 } |
| 361 | 377 |
| 362 intermediateNodes.push_back(transformNode); | 378 intermediateNodes.push_back(transformNode); |
| 363 transformNode = transformNode->parent(); | 379 transformNode = transformNode->parent(); |
| 364 } | 380 } |
| 365 if (!transformNode) { | 381 if (!transformNode) { |
| 366 success = false; | 382 success = false; |
| 367 return m_identity; | 383 return identityMatrix(); |
| 368 } | 384 } |
| 369 | 385 |
| 370 // Iterate down from the top intermediate node found in the previous loop, | 386 // Iterate down from the top intermediate node found in the previous loop, |
| 371 // computing and memoizing transforms as we go. | 387 // computing and memoizing transforms as we go. |
| 372 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); | 388 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); |
| 373 it++) { | 389 it++) { |
| 374 TransformationMatrix localTransformMatrix = (*it)->matrix(); | 390 TransformationMatrix localTransformMatrix = (*it)->matrix(); |
| 375 localTransformMatrix.applyTransformOrigin((*it)->origin()); | 391 localTransformMatrix.applyTransformOrigin((*it)->origin()); |
| 376 | 392 |
| 377 // Flattening Lemma: flatten(A * flatten(B)) = flatten(flatten(A) * B). | 393 // Flattening Lemma: flatten(A * flatten(B)) = flatten(flatten(A) * B). |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 const TransformPaintPropertyNode*, | 465 const TransformPaintPropertyNode*, |
| 450 const TransformPaintPropertyNode*); | 466 const TransformPaintPropertyNode*); |
| 451 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( | 467 template const ClipPaintPropertyNode* GeometryMapper::lowestCommonAncestor( |
| 452 const ClipPaintPropertyNode*, | 468 const ClipPaintPropertyNode*, |
| 453 const ClipPaintPropertyNode*); | 469 const ClipPaintPropertyNode*); |
| 454 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( | 470 template const ScrollPaintPropertyNode* GeometryMapper::lowestCommonAncestor( |
| 455 const ScrollPaintPropertyNode*, | 471 const ScrollPaintPropertyNode*, |
| 456 const ScrollPaintPropertyNode*); | 472 const ScrollPaintPropertyNode*); |
| 457 | 473 |
| 458 } // namespace blink | 474 } // namespace blink |
| OLD | NEW |