| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "core/animation/CompositorAnimations.h" | 32 #include "core/animation/CompositorAnimations.h" |
| 33 | 33 |
| 34 #include "core/animation/AnimationNode.h" | 34 #include "core/animation/AnimationEffect.h" |
| 35 #include "core/animation/AnimationTranslationUtil.h" | 35 #include "core/animation/AnimationTranslationUtil.h" |
| 36 #include "core/animation/ElementAnimations.h" | 36 #include "core/animation/ElementAnimations.h" |
| 37 #include "core/animation/CompositorAnimationsImpl.h" | 37 #include "core/animation/CompositorAnimationsImpl.h" |
| 38 #include "core/animation/animatable/AnimatableDouble.h" | 38 #include "core/animation/animatable/AnimatableDouble.h" |
| 39 #include "core/animation/animatable/AnimatableFilterOperations.h" | 39 #include "core/animation/animatable/AnimatableFilterOperations.h" |
| 40 #include "core/animation/animatable/AnimatableTransform.h" | 40 #include "core/animation/animatable/AnimatableTransform.h" |
| 41 #include "core/animation/animatable/AnimatableValue.h" | 41 #include "core/animation/animatable/AnimatableValue.h" |
| 42 #include "core/layout/LayoutBoxModelObject.h" | 42 #include "core/layout/LayoutBoxModelObject.h" |
| 43 #include "core/layout/LayoutObject.h" | 43 #include "core/layout/LayoutObject.h" |
| 44 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" | 44 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 66 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, Propert
yHandle property, double scale, PropertySpecificKeyframeVector& values) | 66 void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, Propert
yHandle property, double scale, PropertySpecificKeyframeVector& values) |
| 67 { | 67 { |
| 68 ASSERT(values.isEmpty()); | 68 ASSERT(values.isEmpty()); |
| 69 | 69 |
| 70 for (const auto& keyframe : effect->getPropertySpecificKeyframes(property))
{ | 70 for (const auto& keyframe : effect->getPropertySpecificKeyframes(property))
{ |
| 71 double offset = keyframe->offset() * scale; | 71 double offset = keyframe->offset() * scale; |
| 72 values.append(keyframe->cloneWithOffset(offset)); | 72 values.append(keyframe->cloneWithOffset(offset)); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 | 75 |
| 76 bool considerPlayerAsIncompatible(const AnimationPlayer& player, const Animation
Player& playerToAdd) | 76 bool considerAnimationAsIncompatible(const Animation& animation, const Animation
& animationToAdd) |
| 77 { | 77 { |
| 78 if (&player == &playerToAdd) | 78 if (&animation == &animationToAdd) |
| 79 return false; | 79 return false; |
| 80 | 80 |
| 81 switch (player.playStateInternal()) { | 81 switch (animation.playStateInternal()) { |
| 82 case AnimationPlayer::Idle: | 82 case Animation::Idle: |
| 83 return false; | 83 return false; |
| 84 case AnimationPlayer::Pending: | 84 case Animation::Pending: |
| 85 case AnimationPlayer::Running: | 85 case Animation::Running: |
| 86 return true; | 86 return true; |
| 87 case AnimationPlayer::Paused: | 87 case Animation::Paused: |
| 88 case AnimationPlayer::Finished: | 88 case Animation::Finished: |
| 89 return AnimationPlayer::hasLowerPriority(&playerToAdd, &player); | 89 return Animation::hasLowerPriority(&animationToAdd, &animation); |
| 90 default: | 90 default: |
| 91 ASSERT_NOT_REACHED(); | 91 ASSERT_NOT_REACHED(); |
| 92 return true; | 92 return true; |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool hasIncompatibleAnimations(const Element& targetElement, const AnimationPlay
er& playerToAdd, const AnimationEffect& effectToAdd) | 96 bool hasIncompatibleAnimations(const Element& targetElement, const Animation& an
imationToAdd, const EffectModel& effectToAdd) |
| 97 { | 97 { |
| 98 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); | 98 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); |
| 99 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); | 99 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); |
| 100 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); | 100 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); |
| 101 | 101 |
| 102 if (!targetElement.hasAnimations()) | 102 if (!targetElement.hasAnimations()) |
| 103 return false; | 103 return false; |
| 104 | 104 |
| 105 ElementAnimations* elementAnimations = targetElement.elementAnimations(); | 105 ElementAnimations* elementAnimations = targetElement.elementAnimations(); |
| 106 ASSERT(elementAnimations); | 106 ASSERT(elementAnimations); |
| 107 | 107 |
| 108 for (const auto& entry : elementAnimations->players()) { | 108 for (const auto& entry : elementAnimations->animations()) { |
| 109 const AnimationPlayer* attachedPlayer = entry.key; | 109 const Animation* attachedAnimation = entry.key; |
| 110 if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd)) | 110 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) |
| 111 continue; | 111 continue; |
| 112 | 112 |
| 113 if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropert
yOpacity)) | 113 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) |
| 114 || (affectsTransform && attachedPlayer->affects(targetElement, CSSPr
opertyTransform)) | 114 || (affectsTransform && attachedAnimation->affects(targetElement, CS
SPropertyTransform)) |
| 115 || (affectsFilter && attachedPlayer->affects(targetElement, CSSPrope
rtyWebkitFilter))) | 115 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) |
| 116 return true; | 116 return true; |
| 117 } | 117 } |
| 118 | 118 |
| 119 return false; | 119 return false; |
| 120 } | 120 } |
| 121 | 121 |
| 122 } | 122 } |
| 123 | 123 |
| 124 CSSPropertyID CompositorAnimations::CompositableProperties[3] = { | 124 CSSPropertyID CompositorAnimations::CompositableProperties[3] = { |
| 125 CSSPropertyOpacity, CSSPropertyTransform, CSSPropertyWebkitFilter | 125 CSSPropertyOpacity, CSSPropertyTransform, CSSPropertyWebkitFilter |
| 126 }; | 126 }; |
| 127 | 127 |
| 128 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation
Effect& effect, double minValue, double maxValue) const | 128 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const EffectMod
el& effect, double minValue, double maxValue) const |
| 129 { | 129 { |
| 130 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 130 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 131 | 131 |
| 132 PropertyHandleSet properties = keyframeEffect.properties(); | 132 PropertyHandleSet properties = keyframeEffect.properties(); |
| 133 | 133 |
| 134 if (properties.isEmpty()) | 134 if (properties.isEmpty()) |
| 135 return true; | 135 return true; |
| 136 | 136 |
| 137 minValue = std::min(minValue, 0.0); | 137 minValue = std::min(minValue, 0.0); |
| 138 maxValue = std::max(maxValue, 1.0); | 138 maxValue = std::max(maxValue, 1.0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 151 | 151 |
| 152 FloatBox originalBox(box); | 152 FloatBox originalBox(box); |
| 153 | 153 |
| 154 for (size_t j = 0; j < frames.size() - 1; ++j) { | 154 for (size_t j = 0; j < frames.size() - 1; ++j) { |
| 155 const AnimatableTransform* startTransform = toAnimatableTransform(fr
ames[j]->getAnimatableValue().get()); | 155 const AnimatableTransform* startTransform = toAnimatableTransform(fr
ames[j]->getAnimatableValue().get()); |
| 156 const AnimatableTransform* endTransform = toAnimatableTransform(fram
es[j+1]->getAnimatableValue().get()); | 156 const AnimatableTransform* endTransform = toAnimatableTransform(fram
es[j+1]->getAnimatableValue().get()); |
| 157 if (!startTransform || !endTransform) | 157 if (!startTransform || !endTransform) |
| 158 return false; | 158 return false; |
| 159 | 159 |
| 160 // TODO: Add support for inflating modes other than Replace. | 160 // TODO: Add support for inflating modes other than Replace. |
| 161 if (frames[j]->composite() != AnimationEffect::CompositeReplace) | 161 if (frames[j]->composite() != EffectModel::CompositeReplace) |
| 162 return false; | 162 return false; |
| 163 | 163 |
| 164 const TimingFunction& timing = frames[j]->easing(); | 164 const TimingFunction& timing = frames[j]->easing(); |
| 165 double min = 0; | 165 double min = 0; |
| 166 double max = 1; | 166 double max = 1; |
| 167 if (j == 0) { | 167 if (j == 0) { |
| 168 float frameLength = frames[j+1]->offset(); | 168 float frameLength = frames[j+1]->offset(); |
| 169 if (frameLength > 0) { | 169 if (frameLength > 0) { |
| 170 min = minValue / frameLength; | 170 min = minValue / frameLength; |
| 171 } | 171 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 185 box.expandTo(bounds); | 185 box.expandTo(bounds); |
| 186 } | 186 } |
| 187 } | 187 } |
| 188 return true; | 188 return true; |
| 189 } | 189 } |
| 190 | 190 |
| 191 // ----------------------------------------------------------------------- | 191 // ----------------------------------------------------------------------- |
| 192 // CompositorAnimations public API | 192 // CompositorAnimations public API |
| 193 // ----------------------------------------------------------------------- | 193 // ----------------------------------------------------------------------- |
| 194 | 194 |
| 195 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim
ing, const Element& targetElement, const AnimationPlayer* playerToAdd, const Ani
mationEffect& effect, double playerPlaybackRate) | 195 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim
ing, const Element& targetElement, const Animation* animationToAdd, const Effect
Model& effect, double animationPlaybackRate) |
| 196 { | 196 { |
| 197 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 197 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 198 | 198 |
| 199 PropertyHandleSet properties = keyframeEffect.properties(); | 199 PropertyHandleSet properties = keyframeEffect.properties(); |
| 200 if (properties.isEmpty()) | 200 if (properties.isEmpty()) |
| 201 return false; | 201 return false; |
| 202 | 202 |
| 203 for (const auto& property : properties) { | 203 for (const auto& property : properties) { |
| 204 if (!property.isCSSProperty()) | 204 if (!property.isCSSProperty()) |
| 205 return false; | 205 return false; |
| 206 | 206 |
| 207 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp
ertySpecificKeyframes(property); | 207 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp
ertySpecificKeyframes(property); |
| 208 ASSERT(keyframes.size() >= 2); | 208 ASSERT(keyframes.size() >= 2); |
| 209 for (const auto& keyframe : keyframes) { | 209 for (const auto& keyframe : keyframes) { |
| 210 // FIXME: Determine candidacy based on the CSSValue instead of a sna
pshot AnimatableValue. | 210 // FIXME: Determine candidacy based on the CSSValue instead of a sna
pshot AnimatableValue. |
| 211 bool isNeutralKeyframe = keyframe->isCSSPropertySpecificKeyframe() &
& !toCSSPropertySpecificKeyframe(keyframe.get())->value() && keyframe->composite
() == AnimationEffect::CompositeAdd; | 211 bool isNeutralKeyframe = keyframe->isCSSPropertySpecificKeyframe() &
& !toCSSPropertySpecificKeyframe(keyframe.get())->value() && keyframe->composite
() == EffectModel::CompositeAdd; |
| 212 if ((keyframe->composite() != AnimationEffect::CompositeReplace && !
isNeutralKeyframe) || !keyframe->getAnimatableValue()) | 212 if ((keyframe->composite() != EffectModel::CompositeReplace && !isNe
utralKeyframe) || !keyframe->getAnimatableValue()) |
| 213 return false; | 213 return false; |
| 214 | 214 |
| 215 switch (property.cssProperty()) { | 215 switch (property.cssProperty()) { |
| 216 case CSSPropertyOpacity: | 216 case CSSPropertyOpacity: |
| 217 break; | 217 break; |
| 218 case CSSPropertyTransform: | 218 case CSSPropertyTransform: |
| 219 if (toAnimatableTransform(keyframe->getAnimatableValue().get())-
>transformOperations().dependsOnBoxSize()) | 219 if (toAnimatableTransform(keyframe->getAnimatableValue().get())-
>transformOperations().dependsOnBoxSize()) |
| 220 return false; | 220 return false; |
| 221 break; | 221 break; |
| 222 case CSSPropertyWebkitFilter: { | 222 case CSSPropertyWebkitFilter: { |
| 223 const FilterOperations& operations = toAnimatableFilterOperation
s(keyframe->getAnimatableValue().get())->operations(); | 223 const FilterOperations& operations = toAnimatableFilterOperation
s(keyframe->getAnimatableValue().get())->operations(); |
| 224 if (operations.hasFilterThatMovesPixels()) | 224 if (operations.hasFilterThatMovesPixels()) |
| 225 return false; | 225 return false; |
| 226 break; | 226 break; |
| 227 } | 227 } |
| 228 default: | 228 default: |
| 229 // any other types are not allowed to run on compositor. | 229 // any other types are not allowed to run on compositor. |
| 230 return false; | 230 return false; |
| 231 } | 231 } |
| 232 } | 232 } |
| 233 } | 233 } |
| 234 | 234 |
| 235 if (playerToAdd && hasIncompatibleAnimations(targetElement, *playerToAdd, ef
fect)) | 235 if (animationToAdd && hasIncompatibleAnimations(targetElement, *animationToA
dd, effect)) |
| 236 return false; | 236 return false; |
| 237 | 237 |
| 238 CompositorAnimationsImpl::CompositorTiming out; | 238 CompositorAnimationsImpl::CompositorTiming out; |
| 239 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, pl
ayerPlaybackRate)) | 239 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, an
imationPlaybackRate)) |
| 240 return false; | 240 return false; |
| 241 | 241 |
| 242 return true; | 242 return true; |
| 243 } | 243 } |
| 244 | 244 |
| 245 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen
t& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& eff
ectToAdd) | 245 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen
t& targetElement, const Animation& animationToAdd, const EffectModel& effectToAd
d) |
| 246 { | 246 { |
| 247 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); | 247 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); |
| 248 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); | 248 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); |
| 249 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); | 249 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); |
| 250 | 250 |
| 251 if (!targetElement.hasAnimations()) | 251 if (!targetElement.hasAnimations()) |
| 252 return; | 252 return; |
| 253 | 253 |
| 254 ElementAnimations* elementAnimations = targetElement.elementAnimations(); | 254 ElementAnimations* elementAnimations = targetElement.elementAnimations(); |
| 255 ASSERT(elementAnimations); | 255 ASSERT(elementAnimations); |
| 256 | 256 |
| 257 for (const auto& entry : elementAnimations->players()) { | 257 for (const auto& entry : elementAnimations->animations()) { |
| 258 AnimationPlayer* attachedPlayer = entry.key; | 258 Animation* attachedAnimation = entry.key; |
| 259 if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd)) | 259 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) |
| 260 continue; | 260 continue; |
| 261 | 261 |
| 262 if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropert
yOpacity)) | 262 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) |
| 263 || (affectsTransform && attachedPlayer->affects(targetElement, CSSPr
opertyTransform)) | 263 || (affectsTransform && attachedAnimation->affects(targetElement, CS
SPropertyTransform)) |
| 264 || (affectsFilter && attachedPlayer->affects(targetElement, CSSPrope
rtyWebkitFilter))) | 264 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) |
| 265 attachedPlayer->cancelAnimationOnCompositor(); | 265 attachedAnimation->cancelAnimationOnCompositor(); |
| 266 } | 266 } |
| 267 } | 267 } |
| 268 | 268 |
| 269 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) | 269 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) |
| 270 { | 270 { |
| 271 return element.layoutObject() && element.layoutObject()->compositingState()
== PaintsIntoOwnBacking; | 271 return element.layoutObject() && element.layoutObject()->compositingState()
== PaintsIntoOwnBacking; |
| 272 } | 272 } |
| 273 | 273 |
| 274 bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in
t group, double startTime, double timeOffset, const Timing& timing, const Animat
ionPlayer& player, const AnimationEffect& effect, Vector<int>& startedAnimationI
ds, double playerPlaybackRate) | 274 bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in
t group, double startTime, double timeOffset, const Timing& timing, const Animat
ion& animation, const EffectModel& effect, Vector<int>& startedAnimationIds, dou
ble animationPlaybackRate) |
| 275 { | 275 { |
| 276 ASSERT(startedAnimationIds.isEmpty()); | 276 ASSERT(startedAnimationIds.isEmpty()); |
| 277 ASSERT(isCandidateForAnimationOnCompositor(timing, element, &player, effect,
playerPlaybackRate)); | 277 ASSERT(isCandidateForAnimationOnCompositor(timing, element, &animation, effe
ct, animationPlaybackRate)); |
| 278 ASSERT(canStartAnimationOnCompositor(element)); | 278 ASSERT(canStartAnimationOnCompositor(element)); |
| 279 | 279 |
| 280 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 280 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 281 | 281 |
| 282 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); | 282 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); |
| 283 ASSERT(layer); | 283 ASSERT(layer); |
| 284 | 284 |
| 285 Vector<OwnPtr<WebCompositorAnimation>> animations; | 285 Vector<OwnPtr<WebCompositorAnimation>> animations; |
| 286 CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime,
timeOffset, keyframeEffect, animations, playerPlaybackRate); | 286 CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime,
timeOffset, keyframeEffect, animations, animationPlaybackRate); |
| 287 ASSERT(!animations.isEmpty()); | 287 ASSERT(!animations.isEmpty()); |
| 288 for (auto& animation : animations) { | 288 for (auto& compositorAnimation : animations) { |
| 289 int id = animation->id(); | 289 int id = compositorAnimation->id(); |
| 290 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 290 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { |
| 291 WebCompositorAnimationPlayer* compositorPlayer = player.compositorPl
ayer(); | 291 WebCompositorAnimationPlayer* compositorPlayer = animation.composito
rPlayer(); |
| 292 ASSERT(compositorPlayer); | 292 ASSERT(compositorPlayer); |
| 293 compositorPlayer->addAnimation(animation.leakPtr()); | 293 compositorPlayer->addAnimation(compositorAnimation.leakPtr()); |
| 294 } else if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphics
Layer()->addAnimation(animation.release())) { | 294 } else if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphics
Layer()->addAnimation(compositorAnimation.release())) { |
| 295 // FIXME: We should know ahead of time whether these animations can
be started. | 295 // FIXME: We should know ahead of time whether these animations can
be started. |
| 296 for (int startedAnimationId : startedAnimationIds) | 296 for (int startedAnimationId : startedAnimationIds) |
| 297 cancelAnimationOnCompositor(element, player, startedAnimationId)
; | 297 cancelAnimationOnCompositor(element, animation, startedAnimation
Id); |
| 298 startedAnimationIds.clear(); | 298 startedAnimationIds.clear(); |
| 299 return false; | 299 return false; |
| 300 } | 300 } |
| 301 startedAnimationIds.append(id); | 301 startedAnimationIds.append(id); |
| 302 } | 302 } |
| 303 ASSERT(!startedAnimationIds.isEmpty()); | 303 ASSERT(!startedAnimationIds.isEmpty()); |
| 304 return true; | 304 return true; |
| 305 } | 305 } |
| 306 | 306 |
| 307 void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, c
onst AnimationPlayer& player, int id) | 307 void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, c
onst Animation& animation, int id) |
| 308 { | 308 { |
| 309 if (!canStartAnimationOnCompositor(element)) { | 309 if (!canStartAnimationOnCompositor(element)) { |
| 310 // When an element is being detached, we cancel any associated | 310 // When an element is being detached, we cancel any associated |
| 311 // AnimationPlayers for CSS animations. But by the time we get | 311 // Animations for CSS animations. But by the time we get |
| 312 // here the mapping will have been removed. | 312 // here the mapping will have been removed. |
| 313 // FIXME: Defer remove/pause operations until after the | 313 // FIXME: Defer remove/pause operations until after the |
| 314 // compositing update. | 314 // compositing update. |
| 315 return; | 315 return; |
| 316 } | 316 } |
| 317 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 317 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { |
| 318 WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer
(); | 318 WebCompositorAnimationPlayer* compositorPlayer = animation.compositorPla
yer(); |
| 319 ASSERT(compositorPlayer); | 319 ASSERT(compositorPlayer); |
| 320 compositorPlayer->removeAnimation(id); | 320 compositorPlayer->removeAnimation(id); |
| 321 } else { | 321 } else { |
| 322 toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDepre
catedPaintLayerMapping()->mainGraphicsLayer()->removeAnimation(id); | 322 toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDepre
catedPaintLayerMapping()->mainGraphicsLayer()->removeAnimation(id); |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 | 325 |
| 326 void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& e
lement, const AnimationPlayer& player, int id, double pauseTime) | 326 void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& e
lement, const Animation& animation, int id, double pauseTime) |
| 327 { | 327 { |
| 328 // FIXME: canStartAnimationOnCompositor queries compositingState, which is n
ot necessarily up to date. | 328 // FIXME: canStartAnimationOnCompositor queries compositingState, which is n
ot necessarily up to date. |
| 329 // https://code.google.com/p/chromium/issues/detail?id=339847 | 329 // https://code.google.com/p/chromium/issues/detail?id=339847 |
| 330 DisableCompositingQueryAsserts disabler; | 330 DisableCompositingQueryAsserts disabler; |
| 331 | 331 |
| 332 if (!canStartAnimationOnCompositor(element)) { | 332 if (!canStartAnimationOnCompositor(element)) { |
| 333 ASSERT_NOT_REACHED(); | 333 ASSERT_NOT_REACHED(); |
| 334 return; | 334 return; |
| 335 } | 335 } |
| 336 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 336 if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { |
| 337 WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer
(); | 337 WebCompositorAnimationPlayer* compositorPlayer = animation.compositorPla
yer(); |
| 338 ASSERT(compositorPlayer); | 338 ASSERT(compositorPlayer); |
| 339 compositorPlayer->pauseAnimation(id, pauseTime); | 339 compositorPlayer->pauseAnimation(id, pauseTime); |
| 340 } else { | 340 } else { |
| 341 toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDepre
catedPaintLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); | 341 toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDepre
catedPaintLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 bool CompositorAnimations::canAttachCompositedLayers(const Element& element, con
st AnimationPlayer& player) | 345 bool CompositorAnimations::canAttachCompositedLayers(const Element& element, con
st Animation& animation) |
| 346 { | 346 { |
| 347 if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) | 347 if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) |
| 348 return false; | 348 return false; |
| 349 | 349 |
| 350 if (!player.compositorPlayer()) | 350 if (!animation.compositorPlayer()) |
| 351 return false; | 351 return false; |
| 352 | 352 |
| 353 if (!element.layoutObject() || !element.layoutObject()->isBoxModelObject()) | 353 if (!element.layoutObject() || !element.layoutObject()->isBoxModelObject()) |
| 354 return false; | 354 return false; |
| 355 | 355 |
| 356 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); | 356 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); |
| 357 | 357 |
| 358 if (!layer || !layer->isAllowedToQueryCompositingState() | 358 if (!layer || !layer->isAllowedToQueryCompositingState() |
| 359 || !layer->compositedDeprecatedPaintLayerMapping() | 359 || !layer->compositedDeprecatedPaintLayerMapping() |
| 360 || !layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()) | 360 || !layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()) |
| 361 return false; | 361 return false; |
| 362 | 362 |
| 363 if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->pl
atformLayer()) | 363 if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->pl
atformLayer()) |
| 364 return false; | 364 return false; |
| 365 | 365 |
| 366 return true; | 366 return true; |
| 367 } | 367 } |
| 368 | 368 |
| 369 void CompositorAnimations::attachCompositedLayers(const Element& element, const
AnimationPlayer& player) | 369 void CompositorAnimations::attachCompositedLayers(const Element& element, const
Animation& animation) |
| 370 { | 370 { |
| 371 ASSERT(element.layoutObject()); | 371 ASSERT(element.layoutObject()); |
| 372 | 372 |
| 373 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); | 373 DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())
->layer(); |
| 374 ASSERT(layer); | 374 ASSERT(layer); |
| 375 | 375 |
| 376 WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); | 376 WebCompositorAnimationPlayer* compositorPlayer = animation.compositorPlayer(
); |
| 377 ASSERT(compositorPlayer); | 377 ASSERT(compositorPlayer); |
| 378 | 378 |
| 379 ASSERT(layer->compositedDeprecatedPaintLayerMapping()); | 379 ASSERT(layer->compositedDeprecatedPaintLayerMapping()); |
| 380 compositorPlayer->attachLayer(layer->compositedDeprecatedPaintLayerMapping()
->mainGraphicsLayer()->platformLayer()); | 380 compositorPlayer->attachLayer(layer->compositedDeprecatedPaintLayerMapping()
->mainGraphicsLayer()->platformLayer()); |
| 381 } | 381 } |
| 382 | 382 |
| 383 // ----------------------------------------------------------------------- | 383 // ----------------------------------------------------------------------- |
| 384 // CompositorAnimationsImpl | 384 // CompositorAnimationsImpl |
| 385 // ----------------------------------------------------------------------- | 385 // ----------------------------------------------------------------------- |
| 386 | 386 |
| 387 bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing,
double timeOffset, CompositorTiming& out, double playerPlaybackRate) | 387 bool CompositorAnimationsImpl::convertTimingForCompositor(const Timing& timing,
double timeOffset, CompositorTiming& out, double animationPlaybackRate) |
| 388 { | 388 { |
| 389 timing.assertValid(); | 389 timing.assertValid(); |
| 390 | 390 |
| 391 // FIXME: Compositor does not know anything about endDelay. | 391 // FIXME: Compositor does not know anything about endDelay. |
| 392 if (timing.endDelay != 0) | 392 if (timing.endDelay != 0) |
| 393 return false; | 393 return false; |
| 394 | 394 |
| 395 if (std::isnan(timing.iterationDuration) || !timing.iterationCount || !timin
g.iterationDuration) | 395 if (std::isnan(timing.iterationDuration) || !timing.iterationCount || !timin
g.iterationDuration) |
| 396 return false; | 396 return false; |
| 397 | 397 |
| 398 if (!std::isfinite(timing.iterationCount)) { | 398 if (!std::isfinite(timing.iterationCount)) { |
| 399 out.adjustedIterationCount = -1; | 399 out.adjustedIterationCount = -1; |
| 400 } else { | 400 } else { |
| 401 out.adjustedIterationCount = timing.iterationCount; | 401 out.adjustedIterationCount = timing.iterationCount; |
| 402 } | 402 } |
| 403 | 403 |
| 404 out.scaledDuration = timing.iterationDuration; | 404 out.scaledDuration = timing.iterationDuration; |
| 405 out.direction = timing.direction; | 405 out.direction = timing.direction; |
| 406 // Compositor's time offset is positive for seeking into the animation. | 406 // Compositor's time offset is positive for seeking into the animation. |
| 407 out.scaledTimeOffset = -timing.startDelay / playerPlaybackRate + timeOffset; | 407 out.scaledTimeOffset = -timing.startDelay / animationPlaybackRate + timeOffs
et; |
| 408 out.playbackRate = timing.playbackRate * playerPlaybackRate; | 408 out.playbackRate = timing.playbackRate * animationPlaybackRate; |
| 409 out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNon
e : timing.fillMode; | 409 out.fillMode = timing.fillMode == Timing::FillModeAuto ? Timing::FillModeNon
e : timing.fillMode; |
| 410 out.iterationStart = timing.iterationStart; | 410 out.iterationStart = timing.iterationStart; |
| 411 out.assertValid(); | 411 out.assertValid(); |
| 412 return true; | 412 return true; |
| 413 } | 413 } |
| 414 | 414 |
| 415 namespace { | 415 namespace { |
| 416 | 416 |
| 417 void getCubicBezierTimingFunctionParameters(const TimingFunction& timingFunction
, bool& outCustom, | 417 void getCubicBezierTimingFunctionParameters(const TimingFunction& timingFunction
, bool& outCustom, |
| 418 WebCompositorAnimationCurve::TimingFunctionType& outEaseSubType, | 418 WebCompositorAnimationCurve::TimingFunctionType& outEaseSubType, |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 WebTransformAnimationCurve* transformCurve = static_cast<WebTransfor
mAnimationCurve*>(&curve); | 590 WebTransformAnimationCurve* transformCurve = static_cast<WebTransfor
mAnimationCurve*>(&curve); |
| 591 addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, ke
yframeTimingFunction); | 591 addKeyframeWithTimingFunction(*transformCurve, transformKeyframe, ke
yframeTimingFunction); |
| 592 break; | 592 break; |
| 593 } | 593 } |
| 594 default: | 594 default: |
| 595 ASSERT_NOT_REACHED(); | 595 ASSERT_NOT_REACHED(); |
| 596 } | 596 } |
| 597 } | 597 } |
| 598 } | 598 } |
| 599 | 599 |
| 600 void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, in
t group, double startTime, double timeOffset, const KeyframeEffectModelBase& eff
ect, Vector<OwnPtr<WebCompositorAnimation>>& animations, double playerPlaybackRa
te) | 600 void CompositorAnimationsImpl::getAnimationOnCompositor(const Timing& timing, in
t group, double startTime, double timeOffset, const KeyframeEffectModelBase& eff
ect, Vector<OwnPtr<WebCompositorAnimation>>& animations, double animationPlaybac
kRate) |
| 601 { | 601 { |
| 602 ASSERT(animations.isEmpty()); | 602 ASSERT(animations.isEmpty()); |
| 603 CompositorTiming compositorTiming; | 603 CompositorTiming compositorTiming; |
| 604 bool timingValid = convertTimingForCompositor(timing, timeOffset, compositor
Timing, playerPlaybackRate); | 604 bool timingValid = convertTimingForCompositor(timing, timeOffset, compositor
Timing, animationPlaybackRate); |
| 605 ASSERT_UNUSED(timingValid, timingValid); | 605 ASSERT_UNUSED(timingValid, timingValid); |
| 606 | 606 |
| 607 PropertyHandleSet properties = effect.properties(); | 607 PropertyHandleSet properties = effect.properties(); |
| 608 ASSERT(!properties.isEmpty()); | 608 ASSERT(!properties.isEmpty()); |
| 609 for (const auto& property : properties) { | 609 for (const auto& property : properties) { |
| 610 PropertySpecificKeyframeVector values; | 610 PropertySpecificKeyframeVector values; |
| 611 getKeyframeValuesForProperty(&effect, property, compositorTiming.scaledD
uration, values); | 611 getKeyframeValuesForProperty(&effect, property, compositorTiming.scaledD
uration, values); |
| 612 | 612 |
| 613 WebCompositorAnimation::TargetProperty targetProperty; | 613 WebCompositorAnimation::TargetProperty targetProperty; |
| 614 OwnPtr<WebCompositorAnimationCurve> curve; | 614 OwnPtr<WebCompositorAnimationCurve> curve; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 break; | 686 break; |
| 687 default: | 687 default: |
| 688 ASSERT_NOT_REACHED(); | 688 ASSERT_NOT_REACHED(); |
| 689 } | 689 } |
| 690 animations.append(animation.release()); | 690 animations.append(animation.release()); |
| 691 } | 691 } |
| 692 ASSERT(!animations.isEmpty()); | 692 ASSERT(!animations.isEmpty()); |
| 693 } | 693 } |
| 694 | 694 |
| 695 } // namespace blink | 695 } // namespace blink |
| OLD | NEW |