- 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;