Changeset 294752 in webkit
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
r294641 r294752 3464 3464 } 3465 3465 3466 static const TransformOperations& transformationAnimationValueAt(const KeyframeValueList& valueList, unsigned i) 3467 { 3468 return static_cast<const TransformAnimationValue&>(valueList.at(i)).value(); 3469 } 3470 3471 static bool hasBigRotationAngle(const KeyframeValueList& valueList, const SharedPrimitivesPrefix& prefix) 3472 { 3473 // Hardware non-matrix animations are used for every function in the shared primitives prefix. 3474 // These kind of animations have issues with large rotation angles, so for every function that 3475 // will be represented as a hardware non-matrix animation, check that for each of those functions 3476 // the animation that's created for it will not have two consecutive keyframes that have a large 3477 // rotation angle between them. 3478 const auto& primitives = prefix.primitives(); 3479 for (unsigned animationIndex = 0; animationIndex < primitives.size(); ++animationIndex) { 3480 auto type = primitives[animationIndex]; 3481 if (type != TransformOperation::ROTATE && type != TransformOperation::ROTATE_3D) 3482 continue; 3483 for (size_t i = 1; i < valueList.size(); ++i) { 3484 // Since the shared primitive at this index is a rotation, both of these transform 3485 // functions should be RotateTransformOperations. 3486 auto prevOperation = downcast<RotateTransformOperation>(transformationAnimationValueAt(valueList, i - 1).at(animationIndex)); 3487 auto operation = downcast<RotateTransformOperation>(transformationAnimationValueAt(valueList, i).at(animationIndex)); 3488 auto angle = std::abs((prevOperation ? prevOperation->angle() : 0.0) - (operation ? operation->angle() : 0.0)); 3489 if (angle > 180.0) 3490 return true; 3491 } 3492 } 3493 3494 return false; 3495 } 3496 3466 3497 bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, Seconds timeOffset, const FloatSize& boxSize, bool keyframesShouldUseAnimationWideTimingFunction) 3467 3498 { … … 3480 3511 SharedPrimitivesPrefix prefix; 3481 3512 for (size_t i = 0; i < valueList.size(); ++i) 3482 prefix.update(static_cast<const TransformAnimationValue&>(valueList.at(i)).value()); 3513 prefix.update(transformationAnimationValueAt(valueList, i)); 3514 3515 // If this animation has a big rotation between two keyframes, fall back to software animation. CoreAnimation 3516 // will always take the shortest path between two rotations, which will result in incorrect animation when 3517 // the keyframes specify angles larger than one half rotation. 3518 if (hasBigRotationAngle(valueList, prefix)) 3519 return false; 3483 3520 3484 3521 const auto& primitives = prefix.primitives(); … … 3709 3746 unsigned toIndex = forwards; 3710 3747 3711 auto& startValue = static_cast<const TransformAnimationValue&>(valueList.at(fromIndex));3712 auto& endValue = static_cast<const TransformAnimationValue&>(valueList.at(toIndex));3748 const auto& startValue = transformationAnimationValueAt(valueList, fromIndex); 3749 const auto& endValue = transformationAnimationValueAt(valueList, toIndex); 3713 3750 3714 3751 if (isMatrixAnimation) { 3715 3752 TransformationMatrix fromTransform, toTransform; 3716 startValue. value().apply(boxSize, fromTransform);3717 endValue. value().apply(boxSize, toTransform);3753 startValue.apply(boxSize, fromTransform); 3754 endValue.apply(boxSize, toTransform); 3718 3755 3719 3756 // If any matrix is singular, CA won't animate it correctly. So fall back to software animation … … 3726 3763 if (isTransformTypeNumber(transformOpType)) { 3727 3764 float fromValue; 3728 getTransformFunctionValue(startValue. value().at(functionIndex), transformOpType, boxSize, fromValue);3765 getTransformFunctionValue(startValue.at(functionIndex), transformOpType, boxSize, fromValue); 3729 3766 basicAnim->setFromValue(fromValue); 3730 3767 3731 3768 float toValue; 3732 getTransformFunctionValue(endValue. value().at(functionIndex), transformOpType, boxSize, toValue);3769 getTransformFunctionValue(endValue.at(functionIndex), transformOpType, boxSize, toValue); 3733 3770 basicAnim->setToValue(toValue); 3734 3771 } else if (isTransformTypeFloatPoint3D(transformOpType)) { 3735 3772 FloatPoint3D fromValue; 3736 getTransformFunctionValue(startValue. value().at(functionIndex), transformOpType, boxSize, fromValue);3773 getTransformFunctionValue(startValue.at(functionIndex), transformOpType, boxSize, fromValue); 3737 3774 basicAnim->setFromValue(fromValue); 3738 3775 3739 3776 FloatPoint3D toValue; 3740 getTransformFunctionValue(endValue. value().at(functionIndex), transformOpType, boxSize, toValue);3777 getTransformFunctionValue(endValue.at(functionIndex), transformOpType, boxSize, toValue); 3741 3778 basicAnim->setToValue(toValue); 3742 3779 } else { 3743 3780 TransformationMatrix fromValue; 3744 getTransformFunctionValue(startValue. value().at(functionIndex), transformOpType, boxSize, fromValue);3781 getTransformFunctionValue(startValue.at(functionIndex), transformOpType, boxSize, fromValue); 3745 3782 basicAnim->setFromValue(fromValue); 3746 3783 3747 3784 TransformationMatrix toValue; 3748 getTransformFunctionValue(endValue. value().at(functionIndex), transformOpType, boxSize, toValue);3785 getTransformFunctionValue(endValue.at(functionIndex), transformOpType, boxSize, toValue); 3749 3786 basicAnim->setToValue(toValue); 3750 3787 } -
trunk/Source/WebCore/platform/graphics/transforms/TransformOperations.h
r290667 r294752 119 119 void update(const TransformOperations&); 120 120 bool hadIncompatibleTransformFunctions() { return m_indexOfFirstMismatch.has_value(); } 121 const Vector<TransformOperation::OperationType>& primitives() { return m_primitives; }121 const Vector<TransformOperation::OperationType>& primitives() const { return m_primitives; } 122 122 123 123 private:
Note:
See TracChangeset
for help on using the changeset viewer.