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