Eliminate styleDidChange with StyleDifferenceEqual when updates are actually necessary
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Apr 2015 04:59:48 +0000 (04:59 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Apr 2015 04:59:48 +0000 (04:59 +0000)
commit9411ffdd5bf654a3450c0da61a3b463ca58689f4
treec1431196a643368c2373ddf6d6fa1358b3647c9e
parente3a314fa902a5faa518c112f9f13fb97986e1c20
Eliminate styleDidChange with StyleDifferenceEqual when updates are actually necessary
https://bugs.webkit.org/show_bug.cgi?id=144198

Reviewed by Darin Adler, Antti Koivisto.

Source/WebCore:

SyntheticStyleChange style recalcs are triggered for cases where behavior depends
on state which is outside of RenderStyle; this includes triggering compositing for
animations, for video and canvas, and for iframes with composited content.

In these cases, we'd run through RenderElement::setStyle() and its fan-out, but
with diff == StyleDifferenceEqual, and so be unable to determine if there
is actual work to be done.

This patch enforces the contract that the diff is never StyleDifferenceEqual if
compositing or other work has to happen from setStyle(). This is achieved by
passing in a 'hasSideEffects' flag, which causes the diff to become at least
StyleDifferenceRecompositeLayer.

RenderLayerCompositor::layerStyleChanged() can now safely early return
if the diff is equal. Future patches will reduce redundant work even more.

Test: compositing/animation/no-style-recalc-during-accelerated-animation.html

* page/animation/AnimationBase.h:
(WebCore::AnimationBase::animate): Returns a bool now if the state changed.
(WebCore::AnimationBase::state):
* page/animation/AnimationController.cpp:
(WebCore::AnimationController::updateAnimations): bool out param which indicates
whether any animations changed state.
* page/animation/AnimationController.h:
* page/animation/CompositeAnimation.cpp:
(WebCore::CompositeAnimation::animate): If any transitions or animations changed
state, set the animationStateChanged out param to true.
* page/animation/CompositeAnimation.h:
* page/animation/ImplicitAnimation.cpp:
(WebCore::ImplicitAnimation::animate): Return true if the state changed.
* page/animation/ImplicitAnimation.h:
* page/animation/KeyframeAnimation.cpp:
(WebCore::KeyframeAnimation::animate): Return true if the state changed.
* page/animation/KeyframeAnimation.h:
* rendering/RenderElement.cpp:
(WebCore::RenderElement::adjustStyleDifference): We may enter here now with diff
!= StyleDifferenceEqual, but still need to do the check to see if layers changed.
(WebCore::RenderElement::initializeStyle): When setting style for the first time,
don't use StyleDifferenceEqual.
(WebCore::RenderElement::setStyle): Additional flag to indicate whether this style
change involves side effects. If the diff is equal but the flag is set, change
the diff to StyleDifferenceRecompositeLayer (the "lowest" non-zero diff).
* rendering/RenderElement.h:
(WebCore::RenderElement::setAnimatableStyle): Pass true to setStyle() if hasSideEffects
is true, or if animation state changed.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::styleChanged): Pass the diff down.
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::layerStyleChanged): Return if the diff is equal.
* rendering/RenderLayerCompositor.h:
* rendering/style/RenderStyleConstants.h: StyleDifferenceNewStyle is used when
setting style for the first time.
* style/StyleResolveTree.cpp:
(WebCore::Style::createRendererIfNeeded): Provide animationsChanged bool (which is unused).
(WebCore::Style::resolveLocal): If the style change is synthetic, set the flag that
says there are side-effects.

LayoutTests:

New test that detects whether a "hardware" animation is firing the style recalc
timer on every frame, which happened during development of this patch.

* compositing/animation/no-style-recalc-during-accelerated-animation-expected.txt: Added.
* compositing/animation/no-style-recalc-during-accelerated-animation.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183454 268f45cc-cd09-0410-ab3c-d52691b4dbfc
20 files changed:
LayoutTests/ChangeLog
Source/WebCore/ChangeLog
Source/WebCore/page/animation/AnimationBase.h
Source/WebCore/page/animation/AnimationController.cpp
Source/WebCore/page/animation/AnimationController.h
Source/WebCore/page/animation/CompositeAnimation.cpp
Source/WebCore/page/animation/CompositeAnimation.h
Source/WebCore/page/animation/ImplicitAnimation.cpp
Source/WebCore/page/animation/ImplicitAnimation.h
Source/WebCore/page/animation/KeyframeAnimation.cpp
Source/WebCore/page/animation/KeyframeAnimation.h
Source/WebCore/rendering/RenderElement.cpp
Source/WebCore/rendering/RenderElement.h
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/RenderStyleConstants.h
Source/WebCore/rendering/style/StyleRareNonInheritedData.h
Source/WebCore/style/StyleResolveTree.cpp