| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 return true; | 86 return true; |
| 87 case Animation::Paused: | 87 case Animation::Paused: |
| 88 case Animation::Finished: | 88 case Animation::Finished: |
| 89 return Animation::hasLowerPriority(&animationToAdd, &animation); | 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 isTransformRelatedCSSProperty(const PropertyHandle property) |
| 97 { |
| 98 return property.isCSSProperty() |
| 99 && property.cssProperty() != CSSPropertyRotate |
| 100 && property.cssProperty() != CSSPropertyScale |
| 101 && property.cssProperty() != CSSPropertyTransform |
| 102 && property.cssProperty() != CSSPropertyTranslate; |
| 103 } |
| 104 |
| 105 bool isTransformRelatedEffect(const EffectModel& effect) |
| 106 { |
| 107 return effect.affects(PropertyHandle(CSSPropertyTransform)) |
| 108 || effect.affects(PropertyHandle(CSSPropertyRotate)) |
| 109 || effect.affects(PropertyHandle(CSSPropertyScale)) |
| 110 || effect.affects(PropertyHandle(CSSPropertyTranslate)); |
| 111 } |
| 112 |
| 113 bool isTransformRelatedAnimation(const Element& targetElement, const Animation*
animation) |
| 114 { |
| 115 return animation->affects(targetElement, CSSPropertyTransform) |
| 116 || animation->affects(targetElement, CSSPropertyRotate) |
| 117 || animation->affects(targetElement, CSSPropertyScale) |
| 118 || animation->affects(targetElement, CSSPropertyTranslate); |
| 119 } |
| 120 |
| 96 bool hasIncompatibleAnimations(const Element& targetElement, const Animation& an
imationToAdd, const EffectModel& effectToAdd) | 121 bool hasIncompatibleAnimations(const Element& targetElement, const Animation& an
imationToAdd, const EffectModel& effectToAdd) |
| 97 { | 122 { |
| 98 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); | 123 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); |
| 99 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); | 124 const bool affectsTransform = isTransformRelatedEffect(effectToAdd); |
| 100 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); | 125 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); |
| 101 | 126 |
| 102 if (!targetElement.hasAnimations()) | 127 if (!targetElement.hasAnimations()) |
| 103 return false; | 128 return false; |
| 104 | 129 |
| 105 ElementAnimations* elementAnimations = targetElement.elementAnimations(); | 130 ElementAnimations* elementAnimations = targetElement.elementAnimations(); |
| 106 ASSERT(elementAnimations); | 131 ASSERT(elementAnimations); |
| 107 | 132 |
| 108 for (const auto& entry : elementAnimations->animations()) { | 133 for (const auto& entry : elementAnimations->animations()) { |
| 109 const Animation* attachedAnimation = entry.key; | 134 const Animation* attachedAnimation = entry.key; |
| 110 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) | 135 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) |
| 111 continue; | 136 continue; |
| 112 | 137 |
| 113 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) | 138 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) |
| 114 || (affectsTransform && attachedAnimation->affects(targetElement, CS
SPropertyTransform)) | 139 || (affectsTransform && isTransformRelatedAnimation(targetElement, a
ttachedAnimation)) |
| 115 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) | 140 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) |
| 116 return true; | 141 return true; |
| 117 } | 142 } |
| 118 | 143 |
| 119 return false; | 144 return false; |
| 120 } | 145 } |
| 121 | 146 |
| 122 } | 147 } |
| 123 | 148 |
| 124 CSSPropertyID CompositorAnimations::CompositableProperties[3] = { | 149 bool CompositorAnimations::isCompositableProperty(CSSPropertyID property) |
| 125 CSSPropertyOpacity, CSSPropertyTransform, CSSPropertyWebkitFilter | 150 { |
| 151 for (CSSPropertyID id : compositableProperties) { |
| 152 if (property == id) |
| 153 return true; |
| 154 } |
| 155 return false; |
| 156 } |
| 157 |
| 158 const CSSPropertyID CompositorAnimations::compositableProperties[6] = { |
| 159 CSSPropertyOpacity, |
| 160 CSSPropertyRotate, |
| 161 CSSPropertyScale, |
| 162 CSSPropertyTransform, |
| 163 CSSPropertyTranslate, |
| 164 CSSPropertyWebkitFilter |
| 126 }; | 165 }; |
| 127 | 166 |
| 128 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const EffectMod
el& effect, double minValue, double maxValue) const | 167 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const EffectMod
el& effect, double minValue, double maxValue) const |
| 129 { | 168 { |
| 130 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 169 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 131 | 170 |
| 132 PropertyHandleSet properties = keyframeEffect.properties(); | 171 PropertyHandleSet properties = keyframeEffect.properties(); |
| 133 | 172 |
| 134 if (properties.isEmpty()) | 173 if (properties.isEmpty()) |
| 135 return true; | 174 return true; |
| 136 | 175 |
| 137 minValue = std::min(minValue, 0.0); | 176 minValue = std::min(minValue, 0.0); |
| 138 maxValue = std::max(maxValue, 1.0); | 177 maxValue = std::max(maxValue, 1.0); |
| 139 | 178 |
| 140 for (const auto& property : properties) { | 179 for (const auto& property : properties) { |
| 141 if (!property.isCSSProperty()) | 180 if (!property.isCSSProperty()) |
| 142 continue; | 181 continue; |
| 143 | 182 |
| 144 // TODO: Add the ability to get expanded bounds for filters as well. | 183 // TODO: Add the ability to get expanded bounds for filters as well. |
| 145 if (property.cssProperty() != CSSPropertyTransform) | 184 if (isTransformRelatedCSSProperty(property)) |
| 146 continue; | 185 continue; |
| 147 | 186 |
| 148 const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropert
ySpecificKeyframes(property); | 187 const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropert
ySpecificKeyframes(property); |
| 149 if (frames.isEmpty() || frames.size() < 2) | 188 if (frames.isEmpty() || frames.size() < 2) |
| 150 continue; | 189 continue; |
| 151 | 190 |
| 152 FloatBox originalBox(box); | 191 FloatBox originalBox(box); |
| 153 | 192 |
| 154 for (size_t j = 0; j < frames.size() - 1; ++j) { | 193 for (size_t j = 0; j < frames.size() - 1; ++j) { |
| 155 const AnimatableTransform* startTransform = toAnimatableTransform(fr
ames[j]->getAnimatableValue().get()); | 194 const AnimatableTransform* startTransform = toAnimatableTransform(fr
ames[j]->getAnimatableValue().get()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 // ----------------------------------------------------------------------- | 232 // ----------------------------------------------------------------------- |
| 194 | 233 |
| 195 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim
ing, const Element& targetElement, const Animation* animationToAdd, const Effect
Model& effect, double animationPlaybackRate) | 234 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim
ing, const Element& targetElement, const Animation* animationToAdd, const Effect
Model& effect, double animationPlaybackRate) |
| 196 { | 235 { |
| 197 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); | 236 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef
fect); |
| 198 | 237 |
| 199 PropertyHandleSet properties = keyframeEffect.properties(); | 238 PropertyHandleSet properties = keyframeEffect.properties(); |
| 200 if (properties.isEmpty()) | 239 if (properties.isEmpty()) |
| 201 return false; | 240 return false; |
| 202 | 241 |
| 242 unsigned transformPropertyCount = 0; |
| 203 for (const auto& property : properties) { | 243 for (const auto& property : properties) { |
| 204 if (!property.isCSSProperty()) | 244 if (!property.isCSSProperty()) |
| 205 return false; | 245 return false; |
| 206 | 246 |
| 247 if (isTransformRelatedCSSProperty(property)) |
| 248 transformPropertyCount++; |
| 249 |
| 207 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp
ertySpecificKeyframes(property); | 250 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp
ertySpecificKeyframes(property); |
| 208 ASSERT(keyframes.size() >= 2); | 251 ASSERT(keyframes.size() >= 2); |
| 209 for (const auto& keyframe : keyframes) { | 252 for (const auto& keyframe : keyframes) { |
| 210 // FIXME: Determine candidacy based on the CSSValue instead of a sna
pshot AnimatableValue. | 253 // FIXME: Determine candidacy based on the CSSValue instead of a sna
pshot AnimatableValue. |
| 211 bool isNeutralKeyframe = keyframe->isCSSPropertySpecificKeyframe() &
& !toCSSPropertySpecificKeyframe(keyframe.get())->value() && keyframe->composite
() == EffectModel::CompositeAdd; | 254 bool isNeutralKeyframe = keyframe->isCSSPropertySpecificKeyframe() &
& !toCSSPropertySpecificKeyframe(keyframe.get())->value() && keyframe->composite
() == EffectModel::CompositeAdd; |
| 212 if ((keyframe->composite() != EffectModel::CompositeReplace && !isNe
utralKeyframe) || !keyframe->getAnimatableValue()) | 255 if ((keyframe->composite() != EffectModel::CompositeReplace && !isNe
utralKeyframe) || !keyframe->getAnimatableValue()) |
| 213 return false; | 256 return false; |
| 214 | 257 |
| 215 switch (property.cssProperty()) { | 258 switch (property.cssProperty()) { |
| 216 case CSSPropertyOpacity: | 259 case CSSPropertyOpacity: |
| 217 break; | 260 break; |
| 261 case CSSPropertyRotate: |
| 262 case CSSPropertyScale: |
| 263 case CSSPropertyTranslate: |
| 218 case CSSPropertyTransform: | 264 case CSSPropertyTransform: |
| 219 if (toAnimatableTransform(keyframe->getAnimatableValue().get())-
>transformOperations().dependsOnBoxSize()) | 265 if (toAnimatableTransform(keyframe->getAnimatableValue().get())-
>transformOperations().dependsOnBoxSize()) |
| 220 return false; | 266 return false; |
| 221 break; | 267 break; |
| 222 case CSSPropertyWebkitFilter: { | 268 case CSSPropertyWebkitFilter: { |
| 223 const FilterOperations& operations = toAnimatableFilterOperation
s(keyframe->getAnimatableValue().get())->operations(); | 269 const FilterOperations& operations = toAnimatableFilterOperation
s(keyframe->getAnimatableValue().get())->operations(); |
| 224 if (operations.hasFilterThatMovesPixels()) | 270 if (operations.hasFilterThatMovesPixels()) |
| 225 return false; | 271 return false; |
| 226 break; | 272 break; |
| 227 } | 273 } |
| 228 default: | 274 default: |
| 229 // any other types are not allowed to run on compositor. | 275 // any other types are not allowed to run on compositor. |
| 230 return false; | 276 return false; |
| 231 } | 277 } |
| 232 } | 278 } |
| 233 } | 279 } |
| 234 | 280 |
| 281 // TODO: Support multiple transform property animations on the compositor |
| 282 if (transformPropertyCount > 1) |
| 283 return false; |
| 284 |
| 235 if (animationToAdd && hasIncompatibleAnimations(targetElement, *animationToA
dd, effect)) | 285 if (animationToAdd && hasIncompatibleAnimations(targetElement, *animationToA
dd, effect)) |
| 236 return false; | 286 return false; |
| 237 | 287 |
| 238 CompositorAnimationsImpl::CompositorTiming out; | 288 CompositorAnimationsImpl::CompositorTiming out; |
| 239 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, an
imationPlaybackRate)) | 289 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, an
imationPlaybackRate)) |
| 240 return false; | 290 return false; |
| 241 | 291 |
| 242 return true; | 292 return true; |
| 243 } | 293 } |
| 244 | 294 |
| 245 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen
t& targetElement, const Animation& animationToAdd, const EffectModel& effectToAd
d) | 295 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen
t& targetElement, const Animation& animationToAdd, const EffectModel& effectToAd
d) |
| 246 { | 296 { |
| 247 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); | 297 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp
acity)); |
| 248 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty
Transform)); | 298 const bool affectsTransform = isTransformRelatedEffect(effectToAdd); |
| 249 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); | 299 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb
kitFilter)); |
| 250 | 300 |
| 251 if (!targetElement.hasAnimations()) | 301 if (!targetElement.hasAnimations()) |
| 252 return; | 302 return; |
| 253 | 303 |
| 254 ElementAnimations* elementAnimations = targetElement.elementAnimations(); | 304 ElementAnimations* elementAnimations = targetElement.elementAnimations(); |
| 255 ASSERT(elementAnimations); | 305 ASSERT(elementAnimations); |
| 256 | 306 |
| 257 for (const auto& entry : elementAnimations->animations()) { | 307 for (const auto& entry : elementAnimations->animations()) { |
| 258 Animation* attachedAnimation = entry.key; | 308 Animation* attachedAnimation = entry.key; |
| 259 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) | 309 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd)
) |
| 260 continue; | 310 continue; |
| 261 | 311 |
| 262 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) | 312 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp
ertyOpacity)) |
| 263 || (affectsTransform && attachedAnimation->affects(targetElement, CS
SPropertyTransform)) | 313 || (affectsTransform && isTransformRelatedAnimation(targetElement, a
ttachedAnimation)) |
| 264 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) | 314 || (affectsFilter && attachedAnimation->affects(targetElement, CSSPr
opertyWebkitFilter))) |
| 265 attachedAnimation->cancelAnimationOnCompositor(); | 315 attachedAnimation->cancelAnimationOnCompositor(); |
| 266 } | 316 } |
| 267 } | 317 } |
| 268 | 318 |
| 269 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) | 319 bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) |
| 270 { | 320 { |
| 271 return element.layoutObject() && element.layoutObject()->compositingState()
== PaintsIntoOwnBacking; | 321 return element.layoutObject() && element.layoutObject()->compositingState()
== PaintsIntoOwnBacking; |
| 272 } | 322 } |
| 273 | 323 |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 break; | 673 break; |
| 624 } | 674 } |
| 625 case CSSPropertyWebkitFilter: { | 675 case CSSPropertyWebkitFilter: { |
| 626 targetProperty = WebCompositorAnimation::TargetPropertyFilter; | 676 targetProperty = WebCompositorAnimation::TargetPropertyFilter; |
| 627 WebFilterAnimationCurve* filterCurve = Platform::current()->composit
orSupport()->createFilterAnimationCurve(); | 677 WebFilterAnimationCurve* filterCurve = Platform::current()->composit
orSupport()->createFilterAnimationCurve(); |
| 628 addKeyframesToCurve(*filterCurve, values, timing); | 678 addKeyframesToCurve(*filterCurve, values, timing); |
| 629 setTimingFunctionOnCurve(*filterCurve, timing.timingFunction.get()); | 679 setTimingFunctionOnCurve(*filterCurve, timing.timingFunction.get()); |
| 630 curve = adoptPtr(filterCurve); | 680 curve = adoptPtr(filterCurve); |
| 631 break; | 681 break; |
| 632 } | 682 } |
| 683 case CSSPropertyRotate: |
| 684 case CSSPropertyScale: |
| 685 case CSSPropertyTranslate: |
| 633 case CSSPropertyTransform: { | 686 case CSSPropertyTransform: { |
| 634 targetProperty = WebCompositorAnimation::TargetPropertyTransform; | 687 targetProperty = WebCompositorAnimation::TargetPropertyTransform; |
| 635 WebTransformAnimationCurve* transformCurve = Platform::current()->co
mpositorSupport()->createTransformAnimationCurve(); | 688 WebTransformAnimationCurve* transformCurve = Platform::current()->co
mpositorSupport()->createTransformAnimationCurve(); |
| 636 addKeyframesToCurve(*transformCurve, values, timing); | 689 addKeyframesToCurve(*transformCurve, values, timing); |
| 637 setTimingFunctionOnCurve(*transformCurve, timing.timingFunction.get(
)); | 690 setTimingFunctionOnCurve(*transformCurve, timing.timingFunction.get(
)); |
| 638 curve = adoptPtr(transformCurve); | 691 curve = adoptPtr(transformCurve); |
| 639 break; | 692 break; |
| 640 } | 693 } |
| 641 default: | 694 default: |
| 642 ASSERT_NOT_REACHED(); | 695 ASSERT_NOT_REACHED(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 break; | 739 break; |
| 687 default: | 740 default: |
| 688 ASSERT_NOT_REACHED(); | 741 ASSERT_NOT_REACHED(); |
| 689 } | 742 } |
| 690 animations.append(animation.release()); | 743 animations.append(animation.release()); |
| 691 } | 744 } |
| 692 ASSERT(!animations.isEmpty()); | 745 ASSERT(!animations.isEmpty()); |
| 693 } | 746 } |
| 694 | 747 |
| 695 } // namespace blink | 748 } // namespace blink |
| OLD | NEW |