<!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>[178356] 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/178356">178356</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2015-01-13 03:50:53 -0800 (Tue, 13 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/177302">r177302</a> - REGRESSION (<a href="http://trac.webkit.org/projects/webkit/changeset/168217">r168217</a>): Images are cropped out during animation at jetblue.com
https://bugs.webkit.org/show_bug.cgi?id=136410
rdar://problem/18188533

Reviewed by Dean Jackson.

During GraphicsLayer flushing, for tiled layers we can compute a visible rect using
the current state of an animation, which is obtained via the AnimationController.
If that animation was running in a subframe, AnimationController could use a stale
beginAnimationUpdateTime since no-one called its beginAnimationUpdate(). That
resulted in an incorrect computation of the visible rect, resulting in missing tiles.

There are two parts to this fix. First, add an assertion that beginAnimationUpdateTime()
is being called inside an animation update block. This required moving m_beginAnimationUpdateCount
into AnimationControllerPrivate, and changes to endAnimationUpdate().

The second is adding a AnimationUpdateBlock to getAnimatedStyleForRenderer(), which
can be called outside of style resolution. We also need some in other API functions.

Testing revealed that layout can call via layoutOverflowRectForPropagation(), suggesting
that we should have an animation batch inside FrameView::layout(). In addition, a single
resolveStyle/layout should use the same animationBeginTime, so we add a batch to
updateLayoutAndStyleIfNeededRecursive().

No test because it's timing-dependent. Existing tests exercise the new assertion.

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::computeRenderStyleForProperty):
* page/FrameView.cpp:
(WebCore::FrameView::layout):
(WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
* page/animation/AnimationController.cpp:
(WebCore::AnimationPrivateUpdateBlock::AnimationPrivateUpdateBlock):
(WebCore::AnimationPrivateUpdateBlock::~AnimationPrivateUpdateBlock):
(WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
(WebCore::AnimationControllerPrivate::animationTimerFired):
(WebCore::AnimationControllerPrivate::suspendAnimationsForDocument):
(WebCore::AnimationControllerPrivate::resumeAnimationsForDocument):
(WebCore::AnimationControllerPrivate::beginAnimationUpdateTime):
(WebCore::AnimationControllerPrivate::beginAnimationUpdate):
(WebCore::AnimationControllerPrivate::endAnimationUpdate):
(WebCore::AnimationControllerPrivate::getAnimatedStyleForRenderer):
(WebCore::AnimationController::AnimationController):
(WebCore::AnimationController::notifyAnimationStarted):
(WebCore::AnimationController::pauseAnimationAtTime):
(WebCore::AnimationController::pauseTransitionAtTime):
(WebCore::AnimationController::resumeAnimationsForDocument):
(WebCore::AnimationController::startAnimationsIfNotSuspended):
(WebCore::AnimationController::beginAnimationUpdate):
(WebCore::AnimationController::endAnimationUpdate):
* page/animation/AnimationController.h:
* page/animation/AnimationControllerPrivate.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorecssCSSComputedStyleDeclarationcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/css/CSSComputedStyleDeclaration.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCoredomDocumentcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorepageFrameViewcpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/page/FrameView.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllercpp">releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllerh">releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.h</a></li>
<li><a href="#releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllerPrivateh">releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationControllerPrivate.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 (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/ChangeLog        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -1,3 +1,78 @@
</span><ins>+2014-12-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        REGRESSION (r168217): Images are cropped out during animation at jetblue.com
+        https://bugs.webkit.org/show_bug.cgi?id=136410
+        rdar://problem/18188533
+
+        Reviewed by Dean Jackson.
+        
+        During GraphicsLayer flushing, for tiled layers we can compute a visible rect using
+        the current state of an animation, which is obtained via the AnimationController.
+        If that animation was running in a subframe, AnimationController could use a stale
+        beginAnimationUpdateTime since no-one called its beginAnimationUpdate(). That
+        resulted in an incorrect computation of the visible rect, resulting in missing tiles.
+        
+        There are two parts to this fix. First, add an assertion that beginAnimationUpdateTime()
+        is being called inside an animation update block. This required moving m_beginAnimationUpdateCount
+        into AnimationControllerPrivate, and changes to endAnimationUpdate().
+        
+        The second is adding a AnimationUpdateBlock to getAnimatedStyleForRenderer(), which
+        can be called outside of style resolution. We also need some in other API functions.
+        
+        Testing revealed that layout can call via layoutOverflowRectForPropagation(), suggesting
+        that we should have an animation batch inside FrameView::layout(). In addition, a single
+        resolveStyle/layout should use the same animationBeginTime, so we add a batch to 
+        updateLayoutAndStyleIfNeededRecursive().
+        
+        Identical to the patch that was rolled out in r177269 with the addition of a 
+        Ref&lt;Frame&gt; protector(m_frame) in AnimationControllerPrivate::animationTimerFired()
+        that ensures that the AnimationControllerPrivate is kept alive for the scope of
+        the AnimationPrivateUpdateBlock, when a transitionEnd event destroys an iframe.
+        
+        No test because it's timing-dependent. Existing tests exercise the new assertion.
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::computeRenderStyleForProperty):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::layout):
+        (WebCore::FrameView::updateLayoutAndStyleIfNeededRecursive):
+        * page/animation/AnimationController.cpp:
+        (WebCore::AnimationPrivateUpdateBlock::AnimationPrivateUpdateBlock):
+        (WebCore::AnimationPrivateUpdateBlock::~AnimationPrivateUpdateBlock):
+        (WebCore::AnimationControllerPrivate::AnimationControllerPrivate):
+        (WebCore::AnimationControllerPrivate::animationTimerFired):
+        (WebCore::AnimationControllerPrivate::suspendAnimationsForDocument):
+        (WebCore::AnimationControllerPrivate::resumeAnimationsForDocument):
+        (WebCore::AnimationControllerPrivate::beginAnimationUpdateTime):
+        (WebCore::AnimationControllerPrivate::beginAnimationUpdate):
+        (WebCore::AnimationControllerPrivate::endAnimationUpdate):
+        (WebCore::AnimationControllerPrivate::getAnimatedStyleForRenderer):
+        (WebCore::AnimationController::AnimationController):
+        (WebCore::AnimationController::notifyAnimationStarted):
+        (WebCore::AnimationController::pauseAnimationAtTime):
+        (WebCore::AnimationController::pauseTransitionAtTime):
+        (WebCore::AnimationController::resumeAnimationsForDocument):
+        (WebCore::AnimationController::startAnimationsIfNotSuspended):
+        (WebCore::AnimationController::beginAnimationUpdate):
+        (WebCore::AnimationController::endAnimationUpdate):
+        * page/animation/AnimationController.h:
+        * page/animation/AnimationControllerPrivate.h:
+
+2014-12-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        REGRESSION (r168217): Images are cropped out during animation at jetblue.com
+        https://bugs.webkit.org/show_bug.cgi?id=136410
+
+        Reviewed by Dean Jackson.
+
+        We were hitting the new assertion under Page::setPageScaleFactor(), which
+        calls recalcStyle(), so move the AnimationUpdateBlock from updateStyleIfNeeded()
+        to recalcStyle().
+
+        * dom/Document.cpp:
+        (WebCore::Document::recalcStyle):
+        (WebCore::Document::updateStyleIfNeeded):
+
</ins><span class="cx"> 2014-12-15  Xavier Claessens  &lt;xavier.claessens@collabora.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GStreamer] the webkitwebsrc element can stale
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorecssCSSComputedStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -1663,7 +1663,6 @@
</span><span class="cx">     RenderObject* renderer = styledNode-&gt;renderer();
</span><span class="cx"> 
</span><span class="cx">     if (renderer &amp;&amp; renderer-&gt;isComposited() &amp;&amp; AnimationController::supportsAcceleratedAnimationOfProperty(propertyID)) {
</span><del>-        AnimationUpdateBlock animationUpdateBlock(&amp;renderer-&gt;animation());
</del><span class="cx">         RefPtr&lt;RenderStyle&gt; style = renderer-&gt;animation().getAnimatedStyleForRenderer(toRenderElement(*renderer));
</span><span class="cx">         if (pseudoElementSpecifier &amp;&amp; !styledNode-&gt;isPseudoElement()) {
</span><span class="cx">             // FIXME: This cached pseudo style will only exist if the animation has been run at least once.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/dom/Document.cpp        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -1765,6 +1765,7 @@
</span><span class="cx">         return; // Guard against re-entrancy. -dwh
</span><span class="cx"> 
</span><span class="cx">     RenderView::RepaintRegionAccumulator repaintRegionAccumulator(renderView());
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(&amp;m_frame-&gt;animation());
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: We should update style on our ancestor chain before proceeding (especially for seamless),
</span><span class="cx">     // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
</span><span class="lines">@@ -1837,7 +1838,6 @@
</span><span class="cx">     if ((!m_pendingStyleRecalcShouldForce &amp;&amp; !childNeedsStyleRecalc()) || inPageCache())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    AnimationUpdateBlock animationUpdateBlock(m_frame ? &amp;m_frame-&gt;animation() : nullptr);
</del><span class="cx">     recalcStyle(Style::NoChange);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorepageFrameViewcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/page/FrameView.cpp (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/page/FrameView.cpp        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/page/FrameView.cpp        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -1141,7 +1141,8 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willLayout(&amp;frame());
</span><del>-
</del><ins>+    AnimationUpdateBlock animationUpdateBlock(&amp;frame().animation());
+    
</ins><span class="cx">     if (!allowSubtree &amp;&amp; m_layoutRoot) {
</span><span class="cx">         m_layoutRoot-&gt;markContainingBlocksForLayout(false);
</span><span class="cx">         m_layoutRoot = 0;
</span><span class="lines">@@ -3885,6 +3886,8 @@
</span><span class="cx">     // region but then become included later by the second frame adding rects to the dirty region
</span><span class="cx">     // when it lays out.
</span><span class="cx"> 
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(&amp;frame().animation());
+
</ins><span class="cx">     frame().document()-&gt;updateStyleIfNeeded();
</span><span class="cx"> 
</span><span class="cx">     if (needsLayout())
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.cpp        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -50,6 +50,22 @@
</span><span class="cx"> static const double cAnimationTimerDelay = 0.025;
</span><span class="cx"> static const double cBeginAnimationUpdateTimeNotSet = -1;
</span><span class="cx"> 
</span><ins>+class AnimationPrivateUpdateBlock {
+public:
+    AnimationPrivateUpdateBlock(AnimationControllerPrivate&amp; animationController)
+        : m_animationController(animationController)
+    {
+        m_animationController.beginAnimationUpdate();
+    }
+    
+    ~AnimationPrivateUpdateBlock()
+    {
+        m_animationController.endAnimationUpdate();
+    }
+    
+    AnimationControllerPrivate&amp; m_animationController;
+};
+
</ins><span class="cx"> AnimationControllerPrivate::AnimationControllerPrivate(Frame&amp; frame)
</span><span class="cx">     : m_animationTimer(this, &amp;AnimationControllerPrivate::animationTimerFired)
</span><span class="cx">     , m_updateStyleIfNeededDispatcher(this, &amp;AnimationControllerPrivate::updateStyleIfNeededDispatcherFired)
</span><span class="lines">@@ -57,6 +73,7 @@
</span><span class="cx">     , m_beginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet)
</span><span class="cx">     , m_animationsWaitingForStyle()
</span><span class="cx">     , m_animationsWaitingForStartTimeResponse()
</span><ins>+    , m_beginAnimationUpdateCount(0)
</ins><span class="cx">     , m_waitingForAsyncStartNotification(false)
</span><span class="cx">     , m_isSuspended(false)
</span><span class="cx">     , m_allowsNewAnimationsWhileSuspended(false)
</span><span class="lines">@@ -227,9 +244,12 @@
</span><span class="cx"> 
</span><span class="cx"> void AnimationControllerPrivate::animationTimerFired(Timer&lt;AnimationControllerPrivate&gt;&amp;)
</span><span class="cx"> {
</span><ins>+    // We need to keep the frame alive, since it owns us.
+    Ref&lt;Frame&gt; protector(m_frame);
+
</ins><span class="cx">     // Make sure animationUpdateTime is updated, so that it is current even if no
</span><span class="cx">     // styleChange has happened (e.g. accelerated animations)
</span><del>-    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
</del><ins>+    AnimationPrivateUpdateBlock updateBlock(*this);
</ins><span class="cx"> 
</span><span class="cx">     // When the timer fires, all we do is call setChanged on all DOM nodes with running animations and then do an immediate
</span><span class="cx">     // updateStyleIfNeeded.  It will then call back to us with new information.
</span><span class="lines">@@ -286,7 +306,7 @@
</span><span class="cx"> 
</span><span class="cx"> void AnimationControllerPrivate::suspendAnimationsForDocument(Document* document)
</span><span class="cx"> {
</span><del>-    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
</del><ins>+    AnimationPrivateUpdateBlock updateBlock(*this);
</ins><span class="cx"> 
</span><span class="cx">     for (auto it = m_compositeAnimations.begin(), end = m_compositeAnimations.end(); it != end; ++it) {
</span><span class="cx">         if (&amp;it-&gt;key-&gt;document() == document)
</span><span class="lines">@@ -298,7 +318,7 @@
</span><span class="cx"> 
</span><span class="cx"> void AnimationControllerPrivate::resumeAnimationsForDocument(Document* document)
</span><span class="cx"> {
</span><del>-    setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
</del><ins>+    AnimationPrivateUpdateBlock updateBlock(*this);
</ins><span class="cx"> 
</span><span class="cx">     for (auto it = m_compositeAnimations.begin(), end = m_compositeAnimations.end(); it != end; ++it) {
</span><span class="cx">         if (&amp;it-&gt;key-&gt;document() == document)
</span><span class="lines">@@ -351,16 +371,29 @@
</span><span class="cx"> 
</span><span class="cx"> double AnimationControllerPrivate::beginAnimationUpdateTime()
</span><span class="cx"> {
</span><ins>+    ASSERT(m_beginAnimationUpdateCount);
</ins><span class="cx">     if (m_beginAnimationUpdateTime == cBeginAnimationUpdateTimeNotSet)
</span><span class="cx">         m_beginAnimationUpdateTime = monotonicallyIncreasingTime();
</span><ins>+
</ins><span class="cx">     return m_beginAnimationUpdateTime;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AnimationControllerPrivate::beginAnimationUpdate()
+{
+    if (!m_beginAnimationUpdateCount)
+        setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
+    ++m_beginAnimationUpdateCount;
+}
+
</ins><span class="cx"> void AnimationControllerPrivate::endAnimationUpdate()
</span><span class="cx"> {
</span><del>-    styleAvailable();
-    if (!m_waitingForAsyncStartNotification)
-        startTimeResponse(beginAnimationUpdateTime());
</del><ins>+    ASSERT(m_beginAnimationUpdateCount &gt; 0);
+    if (m_beginAnimationUpdateCount == 1) {
+        styleAvailable();
+        if (!m_waitingForAsyncStartNotification)
+            startTimeResponse(beginAnimationUpdateTime());
+    }
+    --m_beginAnimationUpdateCount;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AnimationControllerPrivate::receivedStartTimeResponse(double time)
</span><span class="lines">@@ -371,6 +404,8 @@
</span><span class="cx"> 
</span><span class="cx"> PassRefPtr&lt;RenderStyle&gt; AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderElement&amp; renderer)
</span><span class="cx"> {
</span><ins>+    AnimationPrivateUpdateBlock animationUpdateBlock(*this);
+
</ins><span class="cx">     ASSERT(renderer.isCSSAnimating());
</span><span class="cx">     ASSERT(m_compositeAnimations.contains(&amp;renderer));
</span><span class="cx">     const CompositeAnimation&amp; rendererAnimations = *m_compositeAnimations.get(&amp;renderer);
</span><span class="lines">@@ -468,7 +503,6 @@
</span><span class="cx"> 
</span><span class="cx"> AnimationController::AnimationController(Frame&amp; frame)
</span><span class="cx">     : m_data(std::make_unique&lt;AnimationControllerPrivate&gt;(frame))
</span><del>-    , m_beginAnimationUpdateCount(0)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -544,11 +578,13 @@
</span><span class="cx"> 
</span><span class="cx"> void AnimationController::notifyAnimationStarted(RenderElement&amp;, double startTime)
</span><span class="cx"> {
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(this);
</ins><span class="cx">     m_data-&gt;receivedStartTimeResponse(startTime);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::pauseAnimationAtTime(RenderElement* renderer, const AtomicString&amp; name, double t)
</span><span class="cx"> {
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(this);
</ins><span class="cx">     return m_data-&gt;pauseAnimationAtTime(renderer, name, t);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -559,6 +595,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::pauseTransitionAtTime(RenderElement* renderer, const String&amp; property, double t)
</span><span class="cx"> {
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(this);
</ins><span class="cx">     return m_data-&gt;pauseTransitionAtTime(renderer, property, t);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -615,28 +652,26 @@
</span><span class="cx"> void AnimationController::resumeAnimationsForDocument(Document* document)
</span><span class="cx"> {
</span><span class="cx">     LOG(Animations, &quot;resuming animations for document %p&quot;, document);
</span><ins>+    AnimationUpdateBlock animationUpdateBlock(this);
</ins><span class="cx">     m_data-&gt;resumeAnimationsForDocument(document);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AnimationController::startAnimationsIfNotSuspended(Document* document)
</span><span class="cx"> {
</span><span class="cx">     LOG(Animations, &quot;animations may start for document %p&quot;, document);
</span><ins>+
+    AnimationUpdateBlock animationUpdateBlock(this);
</ins><span class="cx">     m_data-&gt;startAnimationsIfNotSuspended(document);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AnimationController::beginAnimationUpdate()
</span><span class="cx"> {
</span><del>-    if (!m_beginAnimationUpdateCount)
-        m_data-&gt;setBeginAnimationUpdateTime(cBeginAnimationUpdateTimeNotSet);
-    ++m_beginAnimationUpdateCount;
</del><ins>+    m_data-&gt;beginAnimationUpdate();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AnimationController::endAnimationUpdate()
</span><span class="cx"> {
</span><del>-    ASSERT(m_beginAnimationUpdateCount &gt; 0);
-    --m_beginAnimationUpdateCount;
-    if (!m_beginAnimationUpdateCount)
-        m_data-&gt;endAnimationUpdate();
</del><ins>+    m_data-&gt;endAnimationUpdate();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool AnimationController::supportsAcceleratedAnimationOfProperty(CSSPropertyID property)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.h (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.h        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationController.h        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -82,7 +82,6 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     const std::unique_ptr&lt;AnimationControllerPrivate&gt; m_data;
</span><del>-    int m_beginAnimationUpdateCount;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class AnimationUpdateBlock {
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit26SourceWebCorepageanimationAnimationControllerPrivateh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationControllerPrivate.h (178355 => 178356)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationControllerPrivate.h        2015-01-13 11:40:38 UTC (rev 178355)
+++ releases/WebKitGTK/webkit-2.6/Source/WebCore/page/animation/AnimationControllerPrivate.h        2015-01-13 11:50:53 UTC (rev 178356)
</span><span class="lines">@@ -97,6 +97,8 @@
</span><span class="cx"> 
</span><span class="cx">     double beginAnimationUpdateTime();
</span><span class="cx">     void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; }
</span><ins>+    
+    void beginAnimationUpdate();
</ins><span class="cx">     void endAnimationUpdate();
</span><span class="cx">     void receivedStartTimeResponse(double);
</span><span class="cx">     
</span><span class="lines">@@ -141,6 +143,9 @@
</span><span class="cx">     typedef HashSet&lt;RefPtr&lt;AnimationBase&gt;&gt; WaitingAnimationsSet;
</span><span class="cx">     WaitingAnimationsSet m_animationsWaitingForStyle;
</span><span class="cx">     WaitingAnimationsSet m_animationsWaitingForStartTimeResponse;
</span><ins>+
+    int m_beginAnimationUpdateCount;
+
</ins><span class="cx">     bool m_waitingForAsyncStartNotification;
</span><span class="cx">     bool m_isSuspended;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>