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

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

Issue 2729243002: Improve performance of GeometryMapper cache. (Closed)
Patch Set: none 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 side-by-side diff with in-line comments
Download patch
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() {

Powered by Google App Engine
This is Rietveld 408576698