<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[174971] releases/WebKitGTK/webkit-2.6/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/174971">174971</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2014-10-21 09:23:44 -0700 (Tue, 21 Oct 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/174703">r174703</a> - Introduce an isCSSAnimated flag on RenderElement for performance
https://bugs.webkit.org/show_bug.cgi?id=137583

Reviewed by Simon Fraser.

I noticed when profiling the ebay.com page load that isRunningAnimationOnRenderer()
and isRunningAcceleratedAnimationOnRenderer() were called frequently, causing
~4.7 millions m_compositeAnimations HashMap lookups.

This patch introduces an isCSSAnimated flag on RenderElement to return early if
there is no animation on the renderer, thus avoiding HashMap lookups. This reduces
the number of HashMap lookups from ~4.7 millions to ~68k. On my machine, I see
the following performance improvements:
- isRunning*AnimationOnRenderer() / computeCompositingRequirements()
  - before: ~45ms  / ~90ms
  - after:  ~4ms / ~30ms

No new tests, no behavior change.

* page/animation/AnimationController.cpp:
(WebCore::AnimationControllerPrivate::ensureCompositeAnimation):
(WebCore::AnimationControllerPrivate::clear):
(WebCore::AnimationControllerPrivate::isRunningAnimationOnRenderer):
(WebCore::AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer):
(WebCore::AnimationController::isRunningAnimationOnRenderer):
(WebCore::AnimationController::isRunningAcceleratedAnimationOnRenderer):
* rendering/RenderElement.cpp:
(WebCore::RenderElement::RenderElement):
* rendering/RenderElement.h:
(WebCore::RenderElement::isCSSAnimating):
(WebCore::RenderElement::setIsCSSAnimating):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorerenderingRenderElementcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorerenderingRenderElementh">releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit26SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog (174970 => 174971)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-21 16:06:35 UTC (rev 174970)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2014-10-21 16:23:44 UTC (rev 174971)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2014-10-14  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Introduce an isCSSAnimated flag on RenderElement for performance
+        https://bugs.webkit.org/show_bug.cgi?id=137583
+
+        Reviewed by Simon Fraser.
+
+        I noticed when profiling the ebay.com page load that isRunningAnimationOnRenderer()
+        and isRunningAcceleratedAnimationOnRenderer() were called frequently, causing
+        ~4.7 millions m_compositeAnimations HashMap lookups.
+
+        This patch introduces an isCSSAnimated flag on RenderElement to return early if
+        there is no animation on the renderer, thus avoiding HashMap lookups. This reduces
+        the number of HashMap lookups from ~4.7 millions to ~68k. On my machine, I see
+        the following performance improvements:
+        - isRunning*AnimationOnRenderer() / computeCompositingRequirements()
+          - before: ~45ms  / ~90ms
+          - after:  ~4ms / ~30ms
+
+        No new tests, no behavior change.
+
+        * page/animation/AnimationController.cpp:
+        (WebCore::AnimationControllerPrivate::ensureCompositeAnimation):
+        (WebCore::AnimationControllerPrivate::clear):
+        (WebCore::AnimationControllerPrivate::isRunningAnimationOnRenderer):
+        (WebCore::AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer):
+        (WebCore::AnimationController::isRunningAnimationOnRenderer):
+        (WebCore::AnimationController::isRunningAcceleratedAnimationOnRenderer):
+        * rendering/RenderElement.cpp:
+        (WebCore::RenderElement::RenderElement):
+        * rendering/RenderElement.h:
+        (WebCore::RenderElement::isCSSAnimating):
+        (WebCore::RenderElement::setIsCSSAnimating):
+
</ins><span class="cx"> 2014-10-14  Youenn Fablet  &lt;youennf@gmail.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [XHR] Abort method execution when m_loader-&gt;cancel() in internalAbort() caused reentry
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp (174970 => 174971)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp        2014-10-21 16:06:35 UTC (rev 174970)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp        2014-10-21 16:23:44 UTC (rev 174971)
</span><span class="lines">@@ -70,8 +70,10 @@
</span><span class="cx"> CompositeAnimation&amp; AnimationControllerPrivate::ensureCompositeAnimation(RenderElement* renderer)
</span><span class="cx"> {
</span><span class="cx">     auto result = m_compositeAnimations.add(renderer, nullptr);
</span><del>-    if (result.isNewEntry)
</del><ins>+    if (result.isNewEntry) {
</ins><span class="cx">         result.iterator-&gt;value = CompositeAnimation::create(this);
</span><ins>+        renderer-&gt;setIsCSSAnimating(true);
+    }
</ins><span class="cx">     return *result.iterator-&gt;value;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -82,6 +84,7 @@
</span><span class="cx">     RefPtr&lt;CompositeAnimation&gt; animation = m_compositeAnimations.take(renderer);
</span><span class="cx">     if (!animation)
</span><span class="cx">         return false;
</span><ins>+    renderer-&gt;setIsCSSAnimating(false);
</ins><span class="cx">     animation-&gt;clearRenderer();
</span><span class="cx">     return animation-&gt;isSuspended();
</span><span class="cx"> }
</span><span class="lines">@@ -238,14 +241,18 @@
</span><span class="cx"> 
</span><span class="cx"> bool AnimationControllerPrivate::isRunningAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
</span><span class="cx"> {
</span><del>-    const CompositeAnimation* animation = m_compositeAnimations.get(renderer);
-    return animation &amp;&amp; animation-&gt;isAnimatingProperty(property, false, runningState);
</del><ins>+    ASSERT(renderer-&gt;isCSSAnimating());
+    ASSERT(m_compositeAnimations.contains(renderer));
+    const CompositeAnimation&amp; animation = *m_compositeAnimations.get(renderer);
+    return animation.isAnimatingProperty(property, false, runningState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AnimationControllerPrivate::isRunningAcceleratedAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
</span><span class="cx"> {
</span><del>-    const CompositeAnimation* animation = m_compositeAnimations.get(renderer);
-    return animation &amp;&amp; animation-&gt;isAnimatingProperty(property, true, runningState);
</del><ins>+    ASSERT(renderer-&gt;isCSSAnimating());
+    ASSERT(m_compositeAnimations.contains(renderer));
+    const CompositeAnimation&amp; animation = *m_compositeAnimations.get(renderer);
+    return animation.isAnimatingProperty(property, true, runningState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AnimationControllerPrivate::suspendAnimations()
</span><span class="lines">@@ -557,12 +564,12 @@
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::isRunningAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
</span><span class="cx"> {
</span><del>-    return m_data-&gt;isRunningAnimationOnRenderer(renderer, property, runningState);
</del><ins>+    return renderer-&gt;isCSSAnimating() &amp;&amp; m_data-&gt;isRunningAnimationOnRenderer(renderer, property, runningState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderElement* renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
</span><span class="cx"> {
</span><del>-    return m_data-&gt;isRunningAcceleratedAnimationOnRenderer(renderer, property, runningState);
</del><ins>+    return renderer-&gt;isCSSAnimating() &amp;&amp; m_data-&gt;isRunningAcceleratedAnimationOnRenderer(renderer, property, runningState);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::isSuspended() const
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorerenderingRenderElementcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.cpp (174970 => 174971)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.cpp        2014-10-21 16:06:35 UTC (rev 174970)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.cpp        2014-10-21 16:23:44 UTC (rev 174971)
</span><span class="lines">@@ -86,6 +86,7 @@
</span><span class="cx">     , m_renderBoxNeedsLazyRepaint(false)
</span><span class="cx">     , m_hasPausedImageAnimations(false)
</span><span class="cx">     , m_hasCounterNodeMap(false)
</span><ins>+    , m_isCSSAnimating(false)
</ins><span class="cx">     , m_firstChild(nullptr)
</span><span class="cx">     , m_lastChild(nullptr)
</span><span class="cx">     , m_style(WTF::move(style))
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorerenderingRenderElementh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.h (174970 => 174971)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.h        2014-10-21 16:06:35 UTC (rev 174970)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/rendering/RenderElement.h        2014-10-21 16:23:44 UTC (rev 174971)
</span><span class="lines">@@ -158,6 +158,9 @@
</span><span class="cx">     bool hasCounterNodeMap() const { return m_hasCounterNodeMap; }
</span><span class="cx">     void setHasCounterNodeMap(bool f) { m_hasCounterNodeMap = f; }
</span><span class="cx"> 
</span><ins>+    bool isCSSAnimating() const { return m_isCSSAnimating; }
+    void setIsCSSAnimating(bool b) { m_isCSSAnimating = b; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     enum BaseTypeFlags {
</span><span class="cx">         RenderLayerModelObjectFlag = 1 &lt;&lt; 0,
</span><span class="lines">@@ -224,13 +227,14 @@
</span><span class="cx">     virtual void newImageAnimationFrameAvailable(CachedImage&amp;) final override;
</span><span class="cx"> 
</span><span class="cx">     unsigned m_baseTypeFlags : 6;
</span><del>-    bool m_ancestorLineBoxDirty : 1;
-    bool m_hasInitializedStyle : 1;
</del><ins>+    unsigned m_ancestorLineBoxDirty : 1;
+    unsigned m_hasInitializedStyle : 1;
</ins><span class="cx"> 
</span><del>-    bool m_renderInlineAlwaysCreatesLineBoxes : 1;
-    bool m_renderBoxNeedsLazyRepaint : 1;
-    bool m_hasPausedImageAnimations : 1;
-    bool m_hasCounterNodeMap : 1;
</del><ins>+    unsigned m_renderInlineAlwaysCreatesLineBoxes : 1;
+    unsigned m_renderBoxNeedsLazyRepaint : 1;
+    unsigned m_hasPausedImageAnimations : 1;
+    unsigned m_hasCounterNodeMap : 1;
+    unsigned m_isCSSAnimating : 1;
</ins><span class="cx"> 
</span><span class="cx">     RenderObject* m_firstChild;
</span><span class="cx">     RenderObject* m_lastChild;
</span></span></pre>
</div>
</div>

</body>
</html>