Chromium Code Reviews| 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 Rotate)) |
| 100 || effectToAdd.affects(PropertyHandle(CSSPropertyScale)) | |
| 101 || effectToAdd.affects(PropertyHandle(CSSPropertyTransform)) | |
|
dstockwell
2015/07/03 01:53:23
transform should be first (as most common)
soonm
2015/07/03 06:34:29
Done.
| |
| 102 || effectToAdd.affects(PropertyHandle(CSSPropertyTranslate)); | |
| 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 SPropertyRotate)) | |
| 118 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyScale)) | |
| 114 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTransform)) | 119 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTransform)) |
|
dstockwell
2015/07/03 01:53:23
transform should come first
soonm
2015/07/03 06:34:29
Done - As well for the same code below.
| |
| 120 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTranslate)) | |
| 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 bool CompositorAnimations::isCompositableProperty(CSSPropertyID property) |
| 125 CSSPropertyOpacity, CSSPropertyTransform, CSSPropertyWebkitFilter | 131 { |
| 132 for (CSSPropertyID id : compositableProperties) { | |
| 133 if (property == id) | |
| 134 return true; | |
| 135 } | |
| 136 return false; | |
| 137 } | |
| 138 | |
| 139 const CSSPropertyID CompositorAnimations::compositableProperties[6] = { | |
| 140 CSSPropertyOpacity, | |
| 141 CSSPropertyRotate, | |
| 142 CSSPropertyScale, | |
| 143 CSSPropertyTransform, | |
| 144 CSSPropertyTranslate, | |
| 145 CSSPropertyWebkitFilter | |
| 126 }; | 146 }; |
| 127 | 147 |
| 128 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const EffectMod el& effect, double minValue, double maxValue) const | 148 bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const EffectMod el& effect, double minValue, double maxValue) const |
| 129 { | 149 { |
| 130 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); | 150 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); |
| 131 | 151 |
| 132 PropertyHandleSet properties = keyframeEffect.properties(); | 152 PropertyHandleSet properties = keyframeEffect.properties(); |
| 133 | 153 |
| 134 if (properties.isEmpty()) | 154 if (properties.isEmpty()) |
| 135 return true; | 155 return true; |
| 136 | 156 |
| 137 minValue = std::min(minValue, 0.0); | 157 minValue = std::min(minValue, 0.0); |
| 138 maxValue = std::max(maxValue, 1.0); | 158 maxValue = std::max(maxValue, 1.0); |
| 139 | 159 |
| 140 for (const auto& property : properties) { | 160 for (const auto& property : properties) { |
| 141 if (!property.isCSSProperty()) | 161 if (!property.isCSSProperty()) |
| 142 continue; | 162 continue; |
| 143 | 163 |
| 144 // TODO: Add the ability to get expanded bounds for filters as well. | 164 // TODO: Add the ability to get expanded bounds for filters as well. |
| 145 if (property.cssProperty() != CSSPropertyTransform) | 165 if (property.cssProperty() != CSSPropertyRotate |
| 166 && property.cssProperty() != CSSPropertyScale | |
| 167 && property.cssProperty() != CSSPropertyTransform | |
| 168 && property.cssProperty() != CSSPropertyTranslate) | |
| 146 continue; | 169 continue; |
| 147 | 170 |
| 148 const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropert ySpecificKeyframes(property); | 171 const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropert ySpecificKeyframes(property); |
| 149 if (frames.isEmpty() || frames.size() < 2) | 172 if (frames.isEmpty() || frames.size() < 2) |
| 150 continue; | 173 continue; |
| 151 | 174 |
| 152 FloatBox originalBox(box); | 175 FloatBox originalBox(box); |
| 153 | 176 |
| 154 for (size_t j = 0; j < frames.size() - 1; ++j) { | 177 for (size_t j = 0; j < frames.size() - 1; ++j) { |
| 155 const AnimatableTransform* startTransform = toAnimatableTransform(fr ames[j]->getAnimatableValue().get()); | 178 const AnimatableTransform* startTransform = toAnimatableTransform(fr ames[j]->getAnimatableValue().get()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 193 // ----------------------------------------------------------------------- | 216 // ----------------------------------------------------------------------- |
| 194 | 217 |
| 195 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim ing, const Element& targetElement, const Animation* animationToAdd, const Effect Model& effect, double animationPlaybackRate) | 218 bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim ing, const Element& targetElement, const Animation* animationToAdd, const Effect Model& effect, double animationPlaybackRate) |
| 196 { | 219 { |
| 197 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); | 220 const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(ef fect); |
| 198 | 221 |
| 199 PropertyHandleSet properties = keyframeEffect.properties(); | 222 PropertyHandleSet properties = keyframeEffect.properties(); |
| 200 if (properties.isEmpty()) | 223 if (properties.isEmpty()) |
| 201 return false; | 224 return false; |
| 202 | 225 |
| 226 unsigned transformOperationsCount = 0; | |
|
dstockwell
2015/07/03 01:58:40
transformPropertyCount?
soonm
2015/07/03 06:34:29
Yep that sounds better.
| |
| 203 for (const auto& property : properties) { | 227 for (const auto& property : properties) { |
| 204 if (!property.isCSSProperty()) | 228 if (!property.isCSSProperty()) |
| 205 return false; | 229 return false; |
| 206 | 230 |
| 231 if (property.cssProperty() == CSSPropertyRotate | |
|
loyso (OOO)
2015/07/03 03:50:07
You have similar patterns repeated everywhere. Cou
soonm
2015/07/03 06:34:29
Did some clean up and abstracted out common checks
| |
| 232 || property.cssProperty() == CSSPropertyScale | |
| 233 || property.cssProperty() == CSSPropertyTransform | |
| 234 || property.cssProperty() == CSSPropertyTranslate) | |
| 235 transformOperationsCount++; | |
| 236 | |
| 207 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property); | 237 const PropertySpecificKeyframeVector& keyframes = keyframeEffect.getProp ertySpecificKeyframes(property); |
| 208 ASSERT(keyframes.size() >= 2); | 238 ASSERT(keyframes.size() >= 2); |
| 209 for (const auto& keyframe : keyframes) { | 239 for (const auto& keyframe : keyframes) { |
| 210 // FIXME: Determine candidacy based on the CSSValue instead of a sna pshot AnimatableValue. | 240 // 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; | 241 bool isNeutralKeyframe = keyframe->isCSSPropertySpecificKeyframe() & & !toCSSPropertySpecificKeyframe(keyframe.get())->value() && keyframe->composite () == EffectModel::CompositeAdd; |
| 212 if ((keyframe->composite() != EffectModel::CompositeReplace && !isNe utralKeyframe) || !keyframe->getAnimatableValue()) | 242 if ((keyframe->composite() != EffectModel::CompositeReplace && !isNe utralKeyframe) || !keyframe->getAnimatableValue()) |
| 213 return false; | 243 return false; |
| 214 | 244 |
| 215 switch (property.cssProperty()) { | 245 switch (property.cssProperty()) { |
| 216 case CSSPropertyOpacity: | 246 case CSSPropertyOpacity: |
| 217 break; | 247 break; |
| 248 case CSSPropertyRotate: | |
| 249 case CSSPropertyScale: | |
| 250 case CSSPropertyTranslate: | |
| 218 case CSSPropertyTransform: | 251 case CSSPropertyTransform: |
| 219 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize()) | 252 if (toAnimatableTransform(keyframe->getAnimatableValue().get())- >transformOperations().dependsOnBoxSize()) |
| 220 return false; | 253 return false; |
| 221 break; | 254 break; |
| 222 case CSSPropertyWebkitFilter: { | 255 case CSSPropertyWebkitFilter: { |
| 223 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations(); | 256 const FilterOperations& operations = toAnimatableFilterOperation s(keyframe->getAnimatableValue().get())->operations(); |
| 224 if (operations.hasFilterThatMovesPixels()) | 257 if (operations.hasFilterThatMovesPixels()) |
| 225 return false; | 258 return false; |
| 226 break; | 259 break; |
| 227 } | 260 } |
| 228 default: | 261 default: |
| 229 // any other types are not allowed to run on compositor. | 262 // any other types are not allowed to run on compositor. |
| 230 return false; | 263 return false; |
| 231 } | 264 } |
| 232 } | 265 } |
| 233 } | 266 } |
| 234 | 267 |
| 268 // TODO: Support multiple transform property animations on the compositor | |
| 269 if (transformOperationsCount > 1) | |
| 270 return false; | |
| 271 | |
| 235 if (animationToAdd && hasIncompatibleAnimations(targetElement, *animationToA dd, effect)) | 272 if (animationToAdd && hasIncompatibleAnimations(targetElement, *animationToA dd, effect)) |
| 236 return false; | 273 return false; |
| 237 | 274 |
| 238 CompositorAnimationsImpl::CompositorTiming out; | 275 CompositorAnimationsImpl::CompositorTiming out; |
| 239 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, an imationPlaybackRate)) | 276 if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, an imationPlaybackRate)) |
| 240 return false; | 277 return false; |
| 241 | 278 |
| 242 return true; | 279 return true; |
| 243 } | 280 } |
| 244 | 281 |
| 245 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen t& targetElement, const Animation& animationToAdd, const EffectModel& effectToAd d) | 282 void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Elemen t& targetElement, const Animation& animationToAdd, const EffectModel& effectToAd d) |
| 246 { | 283 { |
| 247 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp acity)); | 284 const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOp acity)); |
| 248 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty Transform)); | 285 const bool affectsTransform = effectToAdd.affects(PropertyHandle(CSSProperty Rotate)) |
| 286 || effectToAdd.affects(PropertyHandle(CSSPropertyScale)) | |
| 287 || effectToAdd.affects(PropertyHandle(CSSPropertyTransform)) | |
|
dstockwell
2015/07/03 01:58:40
transform first
soonm
2015/07/03 06:34:29
Done.
| |
| 288 || effectToAdd.affects(PropertyHandle(CSSPropertyTranslate)); | |
| 249 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb kitFilter)); | 289 const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWeb kitFilter)); |
| 250 | 290 |
| 251 if (!targetElement.hasAnimations()) | 291 if (!targetElement.hasAnimations()) |
| 252 return; | 292 return; |
| 253 | 293 |
| 254 ElementAnimations* elementAnimations = targetElement.elementAnimations(); | 294 ElementAnimations* elementAnimations = targetElement.elementAnimations(); |
| 255 ASSERT(elementAnimations); | 295 ASSERT(elementAnimations); |
| 256 | 296 |
| 257 for (const auto& entry : elementAnimations->animations()) { | 297 for (const auto& entry : elementAnimations->animations()) { |
| 258 Animation* attachedAnimation = entry.key; | 298 Animation* attachedAnimation = entry.key; |
| 259 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd) ) | 299 if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd) ) |
| 260 continue; | 300 continue; |
| 261 | 301 |
| 262 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp ertyOpacity)) | 302 if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSProp ertyOpacity)) |
| 303 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyRotate)) | |
| 304 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyScale)) | |
| 263 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTransform)) | 305 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTransform)) |
|
dstockwell
2015/07/03 01:58:40
transform first
soonm
2015/07/03 06:34:29
Done.
| |
| 306 || (affectsTransform && attachedAnimation->affects(targetElement, CS SPropertyTranslate)) | |
| 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 |