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