Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| index 00d8f6f89aefaff65351bbac09b79cef93242cba..b23c8b801d51ed054f9411acc3c49eda80875812 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| @@ -214,29 +214,79 @@ FloatRect GeometryMapper::ancestorToLocalRect( |
| return transformMatrix.inverse().mapRect(rect); |
| } |
| -GeometryMapper::TransformCache& GeometryMapper::getTransformCache( |
| - const TransformPaintPropertyNode* ancestor) { |
| - auto addResult = m_transformCache.insert(ancestor, nullptr); |
| +Vector<GeometryMapper::ClipCacheEntry>* GeometryMapper::getClipCacheEntries( |
| + const ClipPaintPropertyNode* descendantClip) { |
| + auto addResult = m_clipCache.insert(descendantClip, nullptr); |
| if (addResult.isNewEntry) |
| - addResult.storedValue->value = WTF::wrapUnique(new TransformCache); |
| - return *addResult.storedValue->value; |
| + addResult.storedValue->value = WTF::wrapUnique(new Vector<ClipCacheEntry>); |
| + |
| + return addResult.storedValue->value.get(); |
| } |
| -GeometryMapper::ClipCache& GeometryMapper::getClipCache( |
| - const ClipPaintPropertyNode* ancestorClip, |
| - const TransformPaintPropertyNode* ancestorTransform) { |
| - auto addResultTransform = m_clipCache.insert(ancestorClip, nullptr); |
| - if (addResultTransform.isNewEntry) { |
| - addResultTransform.storedValue->value = |
| - WTF::wrapUnique(new TransformToClip); |
| +const FloatClipRect* GeometryMapper::getClip( |
| + const ClipPaintPropertyNode* descendantClip, |
| + const ClipAndTransform& clipAndTransform) { |
| + auto* clipCacheEntries = getClipCacheEntries(descendantClip); |
| + |
| + for (const auto& entry : *clipCacheEntries) { |
| + if (entry.clipAndTransform == clipAndTransform) { |
| + return &entry.clipRect; |
| + } |
| } |
| + return nullptr; |
| +} |
| - auto addResultClip = |
| - addResultTransform.storedValue->value->insert(ancestorTransform, nullptr); |
| - if (addResultClip.isNewEntry) |
| - addResultClip.storedValue->value = WTF::wrapUnique(new ClipCache); |
| +void GeometryMapper::setClip(const ClipPaintPropertyNode* descendantClip, |
| + const ClipAndTransform& clipAndTransform, |
| + const FloatClipRect& clip) { |
| + auto* clipCacheEntries = getClipCacheEntries(descendantClip); |
| +#if DCHECK_IS_ON |
| + for (const auto& entry : clipCachEntries) { |
| + if (entry.clipAndTransform == clipAndTransform) |
| + DCHECK(false); // There should be no existing entry. |
| + } |
| +#endif |
| + clipCacheEntries->push_back(ClipCacheEntry(clipAndTransform, clip)); |
| +} |
| + |
| +Vector<GeometryMapper::TransformCacheEntry>* |
| +GeometryMapper::getTransformCacheEntries( |
| + const TransformPaintPropertyNode* descendantTransform) { |
| + auto addResult = m_transformCache.insert(descendantTransform, nullptr); |
| + if (addResult.isNewEntry) { |
| + addResult.storedValue->value = |
| + WTF::wrapUnique(new Vector<TransformCacheEntry>); |
| + } |
| - return *addResultClip.storedValue->value; |
| + return addResult.storedValue->value.get(); |
| +} |
| + |
| +const TransformationMatrix* GeometryMapper::getTransform( |
| + const TransformPaintPropertyNode* descendantTransform, |
| + const TransformPaintPropertyNode* ancestorTransform) { |
| + auto* clipCacheEntries = getTransformCacheEntries(descendantTransform); |
| + |
| + for (const auto& entry : *clipCacheEntries) { |
| + if (entry.ancestorNode == ancestorTransform) { |
| + return &entry.toAncestor; |
| + } |
| + } |
| + return nullptr; |
| +} |
| + |
| +void GeometryMapper::setTransform( |
| + const TransformPaintPropertyNode* descendantTransform, |
| + const TransformPaintPropertyNode* ancestorTransform, |
| + const TransformationMatrix& toAncestor) { |
| + auto* transformCacheEntries = getTransformCacheEntries(descendantTransform); |
| +#if DCHECK_IS_ON |
| + for (const auto& entry : transformCacheEntries) { |
| + if (entry.ancestorNode == ancestorTransform) |
| + DCHECK(false); // There should be no existing entry. |
| + } |
| +#endif |
| + transformCacheEntries->push_back( |
| + TransformCacheEntry(ancestorTransform, toAncestor)); |
| } |
| FloatClipRect GeometryMapper::localToAncestorClipRect( |
| @@ -274,7 +324,8 @@ FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( |
| if (success) |
| return result; |
| - // Otherwise first map to the lowest common ancestor, then map to destination. |
| + // Otherwise first map to the lowest common ancestor, then map to |
| + // destination. |
| const TransformPaintPropertyNode* lcaTransform = lowestCommonAncestor( |
| sourceState.transform(), destinationState.transform()); |
| DCHECK(lcaTransform); |
| @@ -291,8 +342,9 @@ FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( |
| if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| // On SPv1 we may fail when the paint invalidation container creates an |
| // overflow clip (in ancestorState) which is not in localState of an |
| - // out-of-flow positioned descendant. See crbug.com/513108 and layout test |
| - // compositing/overflow/handle-non-ancestor-clip-parent.html (run with |
| + // out-of-flow positioned descendant. See crbug.com/513108 and layout |
| + // test compositing/overflow/handle-non-ancestor-clip-parent.html (run |
| + // with |
| // --enable-prefer-compositing-to-lcd-text) for details. |
|
Xianzhu
2017/03/07 16:58:46
Nit: join the above two lines.
chrishtr
2017/03/07 19:09:01
Done.
|
| // Ignore it for SPv1 for now. |
| success = true; |
| @@ -307,7 +359,7 @@ FloatClipRect GeometryMapper::sourceToDestinationClipRectInternal( |
| return result; |
| } |
| -FloatClipRect GeometryMapper::localToAncestorClipRectInternal( |
| +const FloatClipRect& GeometryMapper::localToAncestorClipRectInternal( |
| const ClipPaintPropertyNode* descendant, |
| const ClipPaintPropertyNode* ancestorClip, |
| const TransformPaintPropertyNode* ancestorTransform, |
| @@ -315,28 +367,28 @@ FloatClipRect GeometryMapper::localToAncestorClipRectInternal( |
| FloatClipRect clip; |
| if (descendant == ancestorClip) { |
| success = true; |
| - // Return an infinite clip. |
| - return clip; |
| + return m_infiniteClip; |
| } |
| - ClipCache& clipCache = getClipCache(ancestorClip, ancestorTransform); |
| const ClipPaintPropertyNode* clipNode = descendant; |
| Vector<const ClipPaintPropertyNode*> intermediateNodes; |
| + ClipAndTransform clipAndTransform(ancestorClip, ancestorTransform); |
| + |
| // Iterate over the path from localState.clip to ancestorState.clip. Stop if |
| // we've found a memoized (precomputed) clip for any particular node. |
| while (clipNode && clipNode != ancestorClip) { |
| - auto it = clipCache.find(clipNode); |
| - if (it != clipCache.end()) { |
| - clip = it->value; |
| + if (const FloatClipRect* cachedClip = getClip(clipNode, clipAndTransform)) { |
| + clip = *cachedClip; |
| break; |
| } |
| + |
| intermediateNodes.push_back(clipNode); |
| clipNode = clipNode->parent(); |
| } |
| if (!clipNode) { |
| success = false; |
| - return clip; |
| + return m_infiniteClip; |
| } |
| // Iterate down from the top intermediate node found in the previous loop, |
| @@ -347,16 +399,18 @@ FloatClipRect GeometryMapper::localToAncestorClipRectInternal( |
| const TransformationMatrix& transformMatrix = localToAncestorMatrixInternal( |
| (*it)->localTransformSpace(), ancestorTransform, success); |
| if (!success) |
| - return clip; |
| + return m_infiniteClip; |
| FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); |
| clip.intersect(mappedRect); |
| if ((*it)->clipRect().isRounded()) |
| clip.setHasRadius(); |
| - clipCache.set(*it, clip); |
| + setClip(*it, clipAndTransform, clip); |
| } |
| success = true; |
| - return clipCache.find(descendant)->value; |
| + const FloatClipRect* cachedClip = getClip(descendant, clipAndTransform); |
| + DCHECK(cachedClip); |
| + return *cachedClip; |
| } |
| const TransformationMatrix& GeometryMapper::localToAncestorMatrix( |
| @@ -378,8 +432,6 @@ const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( |
| return m_identity; |
| } |
| - TransformCache& transformCache = getTransformCache(ancestorTransformNode); |
| - |
| const TransformPaintPropertyNode* transformNode = localTransformNode; |
| Vector<const TransformPaintPropertyNode*> intermediateNodes; |
| TransformationMatrix transformMatrix; |
| @@ -388,11 +440,12 @@ const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( |
| // Stop if we've found a memoized (precomputed) transform for any particular |
| // node. |
| while (transformNode && transformNode != ancestorTransformNode) { |
| - auto it = transformCache.find(transformNode); |
| - if (it != transformCache.end()) { |
| - transformMatrix = it->value; |
| + if (const TransformationMatrix* cachedMatrix = |
| + getTransform(transformNode, ancestorTransformNode)) { |
| + transformMatrix = *cachedMatrix; |
| break; |
| } |
| + |
| intermediateNodes.push_back(transformNode); |
| transformNode = transformNode->parent(); |
| } |
| @@ -408,10 +461,13 @@ const TransformationMatrix& GeometryMapper::localToAncestorMatrixInternal( |
| TransformationMatrix localTransformMatrix = (*it)->matrix(); |
| localTransformMatrix.applyTransformOrigin((*it)->origin()); |
| transformMatrix = transformMatrix * localTransformMatrix; |
| - transformCache.set(*it, transformMatrix); |
| + setTransform(*it, ancestorTransformNode, transformMatrix); |
| } |
| success = true; |
| - return transformCache.find(localTransformNode)->value; |
| + const TransformationMatrix* cachedMatrix = |
| + getTransform(localTransformNode, ancestorTransformNode); |
| + DCHECK(cachedMatrix); |
| + return *cachedMatrix; |
| } |
| void GeometryMapper::clearCache() { |