Title: [236670] trunk/Source/WebCore
Revision
236670
Author
grao...@webkit.org
Date
2018-10-01 10:44:39 -0700 (Mon, 01 Oct 2018)

Log Message

[Web Animations] Ensure renderers with accelerated animations have layers
https://bugs.webkit.org/show_bug.cgi?id=189990

Reviewed by Simon Fraser.

In r236501 we added code that would make a RenderBox and a RenderInline query the document timeline for whether a given element has
accelerated animations running on it. Since the calls to requiresLayer() are in a hot path, we instead keep a list of elements with
exclusively accelerated animations running.

No new tests, this is already covered by webanimations/accelerated-animation-with-delay.html and webanimations/opacity-animation-yields-compositing-span.html
which respectively check that we can apply an accelerated animation to a non-positioned block and an inline element.

* animation/AnimationTimeline.h:
* animation/DocumentTimeline.cpp:
(WebCore::DocumentTimeline::detachFromDocument):
(WebCore::DocumentTimeline::animationWasAddedToElement):
(WebCore::DocumentTimeline::animationWasRemovedFromElement):
(WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange):
(WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Iterate over an element's animations to determine
whether all of its animations are running accelerated, then update the HashSet containing elements running accelerated animations to remove or
add this element.
(WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Make a simple contains() call on the HashSet containing elements
running accelerated animations.
* animation/DocumentTimeline.h:
* animation/KeyframeEffectReadOnly.cpp:
(WebCore::KeyframeEffectReadOnly::updateAcceleratedAnimationState):
(WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions):
* rendering/RenderBoxModelObject.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (236669 => 236670)


--- trunk/Source/WebCore/ChangeLog	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/ChangeLog	2018-10-01 17:44:39 UTC (rev 236670)
@@ -1,3 +1,34 @@
+2018-10-01  Antoine Quint  <grao...@apple.com>
+
+        [Web Animations] Ensure renderers with accelerated animations have layers
+        https://bugs.webkit.org/show_bug.cgi?id=189990
+
+        Reviewed by Simon Fraser.
+
+        In r236501 we added code that would make a RenderBox and a RenderInline query the document timeline for whether a given element has
+        accelerated animations running on it. Since the calls to requiresLayer() are in a hot path, we instead keep a list of elements with
+        exclusively accelerated animations running.
+
+        No new tests, this is already covered by webanimations/accelerated-animation-with-delay.html and webanimations/opacity-animation-yields-compositing-span.html
+        which respectively check that we can apply an accelerated animation to a non-positioned block and an inline element.
+
+        * animation/AnimationTimeline.h:
+        * animation/DocumentTimeline.cpp:
+        (WebCore::DocumentTimeline::detachFromDocument):
+        (WebCore::DocumentTimeline::animationWasAddedToElement):
+        (WebCore::DocumentTimeline::animationWasRemovedFromElement):
+        (WebCore::DocumentTimeline::animationAcceleratedRunningStateDidChange):
+        (WebCore::DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement): Iterate over an element's animations to determine
+        whether all of its animations are running accelerated, then update the HashSet containing elements running accelerated animations to remove or
+        add this element.
+        (WebCore::DocumentTimeline::runningAnimationsForElementAreAllAccelerated const): Make a simple contains() call on the HashSet containing elements
+        running accelerated animations.
+        * animation/DocumentTimeline.h:
+        * animation/KeyframeEffectReadOnly.cpp:
+        (WebCore::KeyframeEffectReadOnly::updateAcceleratedAnimationState):
+        (WebCore::KeyframeEffectReadOnly::applyPendingAcceleratedActions):
+        * rendering/RenderBoxModelObject.h:
+
 2018-10-01  Alicia Boya GarcĂ­a  <ab...@igalia.com>
 
         [GStreamer] Fix abort in gst_sample_get_info()

Modified: trunk/Source/WebCore/animation/AnimationTimeline.h (236669 => 236670)


--- trunk/Source/WebCore/animation/AnimationTimeline.h	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/animation/AnimationTimeline.h	2018-10-01 17:44:39 UTC (rev 236670)
@@ -63,8 +63,8 @@
     void elementWasRemoved(Element&);
     void removeAnimationsForElement(Element&);
     void cancelDeclarativeAnimationsForElement(Element&);
-    void animationWasAddedToElement(WebAnimation&, Element&);
-    void animationWasRemovedFromElement(WebAnimation&, Element&);
+    virtual void animationWasAddedToElement(WebAnimation&, Element&);
+    virtual void animationWasRemovedFromElement(WebAnimation&, Element&);
 
     void updateCSSAnimationsForElement(Element&, const RenderStyle* currentStyle, const RenderStyle& afterChangeStyle);
     void updateCSSTransitionsForElement(Element&, const RenderStyle& currentStyle, const RenderStyle& afterChangeStyle);

Modified: trunk/Source/WebCore/animation/DocumentTimeline.cpp (236669 => 236670)


--- trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/animation/DocumentTimeline.cpp	2018-10-01 17:44:39 UTC (rev 236670)
@@ -72,6 +72,7 @@
     m_invalidationTaskQueue.close();
     m_eventDispatchTaskQueue.close();
     m_animationScheduleTimer.stop();
+    m_elementsWithRunningAcceleratedAnimations.clear();
 
     auto& animationsToRemove = animations();
     while (!animationsToRemove.isEmpty())
@@ -397,11 +398,45 @@
     return result;
 }
 
+void DocumentTimeline::animationWasAddedToElement(WebAnimation& animation, Element& element)
+{
+    AnimationTimeline::animationWasAddedToElement(animation, element);
+    updateListOfElementsWithRunningAcceleratedAnimationsForElement(element);
+}
+
+void DocumentTimeline::animationWasRemovedFromElement(WebAnimation& animation, Element& element)
+{
+    AnimationTimeline::animationWasRemovedFromElement(animation, element);
+    updateListOfElementsWithRunningAcceleratedAnimationsForElement(element);
+}
+
 void DocumentTimeline::animationAcceleratedRunningStateDidChange(WebAnimation& animation)
 {
     m_acceleratedAnimationsPendingRunningStateChange.add(&animation);
+
+    if (is<KeyframeEffectReadOnly>(animation.effect())) {
+        if (auto* target = downcast<KeyframeEffectReadOnly>(animation.effect())->target())
+            updateListOfElementsWithRunningAcceleratedAnimationsForElement(*target);
+    }
 }
 
+void DocumentTimeline::updateListOfElementsWithRunningAcceleratedAnimationsForElement(Element& element)
+{
+    auto animations = animationsForElement(element);
+    bool runningAnimationsForElementAreAllAccelerated = !animations.isEmpty();
+    for (const auto& animation : animations) {
+        if (is<KeyframeEffectReadOnly>(animation->effect()) && !downcast<KeyframeEffectReadOnly>(animation->effect())->isRunningAccelerated()) {
+            runningAnimationsForElementAreAllAccelerated = false;
+            break;
+        }
+    }
+
+    if (runningAnimationsForElementAreAllAccelerated)
+        m_elementsWithRunningAcceleratedAnimations.add(&element);
+    else
+        m_elementsWithRunningAcceleratedAnimations.remove(&element);
+}
+
 void DocumentTimeline::applyPendingAcceleratedAnimations()
 {
     auto acceleratedAnimationsPendingRunningStateChange = m_acceleratedAnimationsPendingRunningStateChange;
@@ -448,15 +483,7 @@
 
 bool DocumentTimeline::runningAnimationsForElementAreAllAccelerated(Element& element) const
 {
-    // FIXME: This will let animations run using hardware compositing even if later in the active
-    // span of the current animations a new animation should require hardware compositing to be
-    // disabled (webkit.org/b/179974).
-    auto animations = animationsForElement(element);
-    for (const auto& animation : animations) {
-        if (is<KeyframeEffectReadOnly>(animation->effect()) && !downcast<KeyframeEffectReadOnly>(animation->effect())->isRunningAccelerated())
-            return false;
-    }
-    return !animations.isEmpty();
+    return m_elementsWithRunningAcceleratedAnimations.contains(&element);
 }
 
 void DocumentTimeline::enqueueAnimationPlaybackEvent(AnimationPlaybackEvent& event)

Modified: trunk/Source/WebCore/animation/DocumentTimeline.h (236669 => 236670)


--- trunk/Source/WebCore/animation/DocumentTimeline.h	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/animation/DocumentTimeline.h	2018-10-01 17:44:39 UTC (rev 236670)
@@ -50,6 +50,9 @@
 
     void timingModelDidChange() override;
 
+    void animationWasAddedToElement(WebAnimation&, Element&) final;
+    void animationWasRemovedFromElement(WebAnimation&, Element&) final;
+
     // If possible, compute the visual extent of any transform animation on the given renderer
     // using the given rect, returning the result in the rect. Return false if there is some
     // transform animation but we were unable to cheaply compute its effect on the extent.
@@ -89,6 +92,7 @@
     void updateAnimations();
     void performEventDispatchTask();
     void maybeClearCachedCurrentTime();
+    void updateListOfElementsWithRunningAcceleratedAnimationsForElement(Element&);
 
     RefPtr<Document> m_document;
     Seconds m_originTime;
@@ -103,6 +107,7 @@
     HashSet<RefPtr<WebAnimation>> m_acceleratedAnimationsPendingRunningStateChange;
     Vector<Ref<AnimationPlaybackEvent>> m_pendingAnimationEvents;
     unsigned m_numberOfAnimationTimelineInvalidationsForTesting { 0 };
+    HashSet<Element*> m_elementsWithRunningAcceleratedAnimations;
 
 #if !USE(REQUEST_ANIMATION_FRAME_DISPLAY_MONITOR)
     void animationResolutionTimerFired();

Modified: trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp (236669 => 236670)


--- trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp	2018-10-01 17:44:39 UTC (rev 236670)
@@ -1231,6 +1231,7 @@
         else {
             m_lastRecordedAcceleratedAction = AcceleratedAction::Stop;
             m_pendingAcceleratedActions.clear();
+            animation()->acceleratedStateDidChange();
         }
         return;
     }
@@ -1294,6 +1295,7 @@
             if (!compositedRenderer->startAnimation(timeOffset, backingAnimationForCompositedRenderer().ptr(), m_blendingKeyframes)) {
                 m_shouldRunAccelerated = false;
                 m_lastRecordedAcceleratedAction = AcceleratedAction::Stop;
+                animation()->acceleratedStateDidChange();
                 return;
             }
             break;

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.h (236669 => 236670)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2018-10-01 17:41:25 UTC (rev 236669)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.h	2018-10-01 17:44:39 UTC (rev 236670)
@@ -241,6 +241,8 @@
     void removeFromContinuationChain();
 
     virtual LayoutRect paintRectToClipOutFromBorder(const LayoutRect&) { return LayoutRect(); };
+
+    bool hasRunningAcceleratedAnimations() const;
     
 protected:
     RenderBoxModelObject(Element&, RenderStyle&&, BaseTypeFlags);
@@ -270,8 +272,6 @@
 
     DecodingMode decodingModeForImageDraw(const Image&, const PaintInfo&) const;
 
-    bool hasRunningAcceleratedAnimations() const;
-
 public:
     // For RenderBlocks and RenderInlines with m_style->styleType() == PseudoId::FirstLetter, this tracks their remaining text fragments
     RenderTextFragment* firstLetterRemainingText() const;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to