LCOV - code coverage report
Current view: top level - gfx/layers - AnimationHelper.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 12 320 3.8 %
Date: 2017-07-14 16:53:18 Functions: 3 19 15.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "AnimationHelper.h"
       8             : #include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
       9             : #include "mozilla/dom/AnimationEffectReadOnlyBinding.h" // for dom::FillMode
      10             : #include "mozilla/dom/KeyframeEffectBinding.h" // for dom::IterationComposite
      11             : #include "mozilla/dom/KeyframeEffectReadOnly.h" // for dom::KeyFrameEffectReadOnly
      12             : #include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
      13             : #include "mozilla/layers/LayerAnimationUtils.h" // for TimingFunctionToComputedTimingFunction
      14             : #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
      15             : #include "nsDeviceContext.h"            // for AppUnitsPerCSSPixel
      16             : #include "nsDisplayList.h"              // for nsDisplayTransform, etc
      17             : 
      18             : namespace mozilla {
      19             : namespace layers {
      20             : 
      21           0 : struct StyleAnimationValueCompositePair {
      22             :   StyleAnimationValue mValue;
      23             :   dom::CompositeOperation mComposite;
      24             : };
      25             : 
      26             : void
      27          29 : CompositorAnimationStorage::Clear()
      28             : {
      29          29 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
      30             : 
      31          29 :   mAnimatedValues.Clear();
      32          29 :   mAnimations.Clear();
      33          29 : }
      34             : 
      35             : void
      36           0 : CompositorAnimationStorage::ClearById(const uint64_t& aId)
      37             : {
      38           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
      39             : 
      40           0 :   mAnimatedValues.Remove(aId);
      41           0 :   mAnimations.Remove(aId);
      42           0 : }
      43             : 
      44             : AnimatedValue*
      45           0 : CompositorAnimationStorage::GetAnimatedValue(const uint64_t& aId) const
      46             : {
      47           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
      48           0 :   return mAnimatedValues.Get(aId);
      49             : }
      50             : 
      51             : Maybe<float>
      52           0 : CompositorAnimationStorage::GetAnimationOpacity(const uint64_t& aId) const
      53             : {
      54           0 :   auto value = GetAnimatedValue(aId);
      55           0 :   if (!value || value->mType != AnimatedValue::OPACITY) {
      56           0 :     return Nothing();
      57             :   }
      58             : 
      59           0 :   return Some(value->mOpacity);
      60             : }
      61             : 
      62             : Maybe<gfx::Matrix4x4>
      63           0 : CompositorAnimationStorage::GetAnimationTransform(const uint64_t& aId) const
      64             : {
      65           0 :   auto value = GetAnimatedValue(aId);
      66           0 :   if (!value || value->mType != AnimatedValue::TRANSFORM) {
      67           0 :     return Nothing();
      68             :   }
      69             : 
      70           0 :   gfx::Matrix4x4 transform = value->mTransform.mFrameTransform;
      71           0 :   const TransformData& data = value->mTransform.mData;
      72           0 :   float scale = data.appUnitsPerDevPixel();
      73           0 :   gfx::Point3D transformOrigin = data.transformOrigin();
      74             : 
      75             :   // Undo the rebasing applied by
      76             :   // nsDisplayTransform::GetResultingTransformMatrixInternal
      77           0 :   transform.ChangeBasis(-transformOrigin);
      78             : 
      79             :   // Convert to CSS pixels (this undoes the operations performed by
      80             :   // nsStyleTransformMatrix::ProcessTranslatePart which is called from
      81             :   // nsDisplayTransform::GetResultingTransformMatrix)
      82             :   double devPerCss =
      83           0 :     double(scale) / double(nsDeviceContext::AppUnitsPerCSSPixel());
      84           0 :   transform._41 *= devPerCss;
      85           0 :   transform._42 *= devPerCss;
      86           0 :   transform._43 *= devPerCss;
      87             : 
      88           0 :   return Some(transform);
      89             : }
      90             : 
      91             : void
      92           0 : CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
      93             :                                              gfx::Matrix4x4&& aTransformInDevSpace,
      94             :                                              gfx::Matrix4x4&& aFrameTransform,
      95             :                                              const TransformData& aData)
      96             : {
      97           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
      98             :   AnimatedValue* value = new AnimatedValue(Move(aTransformInDevSpace),
      99             :                                            Move(aFrameTransform),
     100           0 :                                            aData);
     101           0 :   mAnimatedValues.Put(aId, value);
     102           0 : }
     103             : 
     104             : void
     105           0 : CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
     106             :                                              gfx::Matrix4x4&& aTransformInDevSpace)
     107             : {
     108           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     109           0 :   const TransformData dontCare = {};
     110             :   AnimatedValue* value = new AnimatedValue(Move(aTransformInDevSpace),
     111           0 :                                            gfx::Matrix4x4(),
     112           0 :                                            dontCare);
     113           0 :   mAnimatedValues.Put(aId, value);
     114           0 : }
     115             : 
     116             : void
     117           0 : CompositorAnimationStorage::SetAnimatedValue(uint64_t aId,
     118             :                                              const float& aOpacity)
     119             : {
     120           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     121           0 :   AnimatedValue* value = new AnimatedValue(aOpacity);
     122           0 :   mAnimatedValues.Put(aId, value);
     123           0 : }
     124             : 
     125             : AnimationArray*
     126           0 : CompositorAnimationStorage::GetAnimations(const uint64_t& aId) const
     127             : {
     128           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     129           0 :   return mAnimations.Get(aId);
     130             : }
     131             : 
     132             : void
     133           0 : CompositorAnimationStorage::SetAnimations(uint64_t aId, const AnimationArray& aValue)
     134             : {
     135           0 :   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
     136           0 :   AnimationArray* value = new AnimationArray(aValue);
     137           0 :   mAnimations.Put(aId, value);
     138           0 : }
     139             : 
     140             : static StyleAnimationValue
     141           0 : SampleValue(double aPortion, const layers::Animation& aAnimation,
     142             :             const StyleAnimationValueCompositePair& aStart,
     143             :             const StyleAnimationValueCompositePair& aEnd,
     144             :             const StyleAnimationValue& aLastValue,
     145             :             uint64_t aCurrentIteration,
     146             :             const StyleAnimationValue& aUnderlyingValue)
     147             : {
     148           0 :   NS_ASSERTION(aStart.mValue.IsNull() || aEnd.mValue.IsNull() ||
     149             :                aStart.mValue.GetUnit() == aEnd.mValue.GetUnit(),
     150             :                "Must have same unit");
     151             : 
     152             :   StyleAnimationValue startValue =
     153           0 :     dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
     154             :                                                 aStart.mValue,
     155             :                                                 aUnderlyingValue,
     156           0 :                                                 aStart.mComposite);
     157             :   StyleAnimationValue endValue =
     158           0 :     dom::KeyframeEffectReadOnly::CompositeValue(aAnimation.property(),
     159             :                                                 aEnd.mValue,
     160             :                                                 aUnderlyingValue,
     161           0 :                                                 aEnd.mComposite);
     162             : 
     163             :   // Iteration composition for accumulate
     164           0 :   if (static_cast<dom::IterationCompositeOperation>
     165           0 :         (aAnimation.iterationComposite()) ==
     166           0 :           dom::IterationCompositeOperation::Accumulate &&
     167             :       aCurrentIteration > 0) {
     168             :     // FIXME: Bug 1293492: Add a utility function to calculate both of
     169             :     // below StyleAnimationValues.
     170             :     startValue =
     171           0 :       StyleAnimationValue::Accumulate(aAnimation.property(),
     172           0 :                                       aLastValue.IsNull()
     173             :                                         ? aUnderlyingValue
     174             :                                         : aLastValue,
     175           0 :                                       Move(startValue),
     176           0 :                                       aCurrentIteration);
     177             :     endValue =
     178           0 :       StyleAnimationValue::Accumulate(aAnimation.property(),
     179           0 :                                       aLastValue.IsNull()
     180             :                                         ? aUnderlyingValue
     181             :                                         : aLastValue,
     182           0 :                                       Move(endValue),
     183           0 :                                       aCurrentIteration);
     184             :   }
     185             : 
     186           0 :   StyleAnimationValue interpolatedValue;
     187             :   // This should never fail because we only pass transform and opacity values
     188             :   // to the compositor and they should never fail to interpolate.
     189             :   DebugOnly<bool> uncomputeResult =
     190           0 :     StyleAnimationValue::Interpolate(aAnimation.property(),
     191             :                                      startValue, endValue,
     192           0 :                                      aPortion, interpolatedValue);
     193           0 :   MOZ_ASSERT(uncomputeResult, "could not uncompute value");
     194           0 :   return interpolatedValue;
     195             : }
     196             : 
     197             : bool
     198         215 : AnimationHelper::SampleAnimationForEachNode(TimeStamp aTime,
     199             :                            AnimationArray& aAnimations,
     200             :                            InfallibleTArray<AnimData>& aAnimationData,
     201             :                            StyleAnimationValue& aAnimationValue,
     202             :                            bool& aHasInEffectAnimations)
     203             : {
     204         215 :   bool activeAnimations = false;
     205             : 
     206         215 :   if (aAnimations.IsEmpty()) {
     207         215 :     return activeAnimations;
     208             :   }
     209             : 
     210             :   // Process in order, since later aAnimations override earlier ones.
     211           0 :   for (size_t i = 0, iEnd = aAnimations.Length(); i < iEnd; ++i) {
     212           0 :     Animation& animation = aAnimations[i];
     213           0 :     AnimData& animData = aAnimationData[i];
     214             : 
     215           0 :     activeAnimations = true;
     216             : 
     217           0 :     MOZ_ASSERT((!animation.originTime().IsNull() &&
     218             :                 animation.startTime().type() ==
     219             :                   MaybeTimeDuration::TTimeDuration) ||
     220             :                animation.isNotPlaying(),
     221             :                "If we are playing, we should have an origin time and a start"
     222             :                " time");
     223             :     // If the animation is not currently playing, e.g. paused or
     224             :     // finished, then use the hold time to stay at the same position.
     225             :     TimeDuration elapsedDuration =
     226           0 :       animation.isNotPlaying() ||
     227           0 :       animation.startTime().type() != MaybeTimeDuration::TTimeDuration
     228           0 :       ? animation.holdTime()
     229           0 :       : (aTime - animation.originTime() -
     230           0 :          animation.startTime().get_TimeDuration())
     231           0 :         .MultDouble(animation.playbackRate());
     232             :     TimingParams timing {
     233           0 :       animation.duration(),
     234           0 :       animation.delay(),
     235           0 :       animation.endDelay(),
     236           0 :       animation.iterations(),
     237           0 :       animation.iterationStart(),
     238           0 :       static_cast<dom::PlaybackDirection>(animation.direction()),
     239           0 :       static_cast<dom::FillMode>(animation.fillMode()),
     240           0 :       Move(AnimationUtils::TimingFunctionToComputedTimingFunction(
     241           0 :            animation.easingFunction()))
     242           0 :     };
     243             : 
     244             :     ComputedTiming computedTiming =
     245             :       dom::AnimationEffectReadOnly::GetComputedTimingAt(
     246           0 :         Nullable<TimeDuration>(elapsedDuration), timing,
     247           0 :         animation.playbackRate());
     248             : 
     249           0 :     if (computedTiming.mProgress.IsNull()) {
     250           0 :       continue;
     251             :     }
     252             : 
     253           0 :     uint32_t segmentIndex = 0;
     254           0 :     size_t segmentSize = animation.segments().Length();
     255           0 :     AnimationSegment* segment = animation.segments().Elements();
     256           0 :     while (segment->endPortion() < computedTiming.mProgress.Value() &&
     257           0 :            segmentIndex < segmentSize - 1) {
     258           0 :       ++segment;
     259           0 :       ++segmentIndex;
     260             :     }
     261             : 
     262             :     double positionInSegment =
     263           0 :       (computedTiming.mProgress.Value() - segment->startPortion()) /
     264           0 :       (segment->endPortion() - segment->startPortion());
     265             : 
     266             :     double portion =
     267           0 :       ComputedTimingFunction::GetPortion(animData.mFunctions[segmentIndex],
     268             :                                          positionInSegment,
     269           0 :                                      computedTiming.mBeforeFlag);
     270             : 
     271             :     StyleAnimationValueCompositePair from {
     272           0 :       animData.mStartValues[segmentIndex],
     273           0 :       static_cast<dom::CompositeOperation>(segment->startComposite())
     274           0 :     };
     275             :     StyleAnimationValueCompositePair to {
     276           0 :       animData.mEndValues[segmentIndex],
     277           0 :       static_cast<dom::CompositeOperation>(segment->endComposite())
     278           0 :     };
     279             :     // interpolate the property
     280           0 :     aAnimationValue = SampleValue(portion,
     281             :                                  animation,
     282             :                                  from, to,
     283           0 :                                  animData.mEndValues.LastElement(),
     284             :                                  computedTiming.mCurrentIteration,
     285           0 :                                  aAnimationValue);
     286           0 :     aHasInEffectAnimations = true;
     287             :   }
     288             : 
     289             : #ifdef DEBUG
     290             :   // Sanity check that all of animation data are the same.
     291           0 :   const AnimationData& lastData = aAnimations.LastElement().data();
     292           0 :   for (const Animation& animation : aAnimations) {
     293           0 :     const AnimationData& data = animation.data();
     294           0 :     MOZ_ASSERT(data.type() == lastData.type(),
     295             :                "The type of AnimationData should be the same");
     296           0 :     if (data.type() == AnimationData::Tnull_t) {
     297           0 :       continue;
     298             :     }
     299             : 
     300           0 :     MOZ_ASSERT(data.type() == AnimationData::TTransformData);
     301           0 :     const TransformData& transformData = data.get_TransformData();
     302           0 :     const TransformData& lastTransformData = lastData.get_TransformData();
     303           0 :     MOZ_ASSERT(transformData.origin() == lastTransformData.origin() &&
     304             :                transformData.transformOrigin() ==
     305             :                  lastTransformData.transformOrigin() &&
     306             :                transformData.bounds() == lastTransformData.bounds() &&
     307             :                transformData.appUnitsPerDevPixel() ==
     308             :                  lastTransformData.appUnitsPerDevPixel(),
     309             :                "All of members of TransformData should be the same");
     310             :   }
     311             : #endif
     312           0 :   return activeAnimations;
     313             : }
     314             : 
     315             : static inline void
     316           0 : SetCSSAngle(const CSSAngle& aAngle, nsCSSValue& aValue)
     317             : {
     318           0 :   aValue.SetFloatValue(aAngle.value(), nsCSSUnit(aAngle.unit()));
     319           0 : }
     320             : 
     321             : static nsCSSValueSharedList*
     322           0 : CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
     323             : {
     324           0 :   nsAutoPtr<nsCSSValueList> result;
     325           0 :   nsCSSValueList** resultTail = getter_Transfers(result);
     326           0 :   for (uint32_t i = 0; i < aFunctions.Length(); i++) {
     327           0 :     RefPtr<nsCSSValue::Array> arr;
     328           0 :     switch (aFunctions[i].type()) {
     329             :       case TransformFunction::TRotationX:
     330             :       {
     331           0 :         const CSSAngle& angle = aFunctions[i].get_RotationX().angle();
     332           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_rotatex,
     333           0 :                                                            resultTail);
     334           0 :         SetCSSAngle(angle, arr->Item(1));
     335           0 :         break;
     336             :       }
     337             :       case TransformFunction::TRotationY:
     338             :       {
     339           0 :         const CSSAngle& angle = aFunctions[i].get_RotationY().angle();
     340           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_rotatey,
     341           0 :                                                            resultTail);
     342           0 :         SetCSSAngle(angle, arr->Item(1));
     343           0 :         break;
     344             :       }
     345             :       case TransformFunction::TRotationZ:
     346             :       {
     347           0 :         const CSSAngle& angle = aFunctions[i].get_RotationZ().angle();
     348           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_rotatez,
     349           0 :                                                            resultTail);
     350           0 :         SetCSSAngle(angle, arr->Item(1));
     351           0 :         break;
     352             :       }
     353             :       case TransformFunction::TRotation:
     354             :       {
     355           0 :         const CSSAngle& angle = aFunctions[i].get_Rotation().angle();
     356           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_rotate,
     357           0 :                                                            resultTail);
     358           0 :         SetCSSAngle(angle, arr->Item(1));
     359           0 :         break;
     360             :       }
     361             :       case TransformFunction::TRotation3D:
     362             :       {
     363           0 :         float x = aFunctions[i].get_Rotation3D().x();
     364           0 :         float y = aFunctions[i].get_Rotation3D().y();
     365           0 :         float z = aFunctions[i].get_Rotation3D().z();
     366           0 :         const CSSAngle& angle = aFunctions[i].get_Rotation3D().angle();
     367             :         arr =
     368           0 :           StyleAnimationValue::AppendTransformFunction(eCSSKeyword_rotate3d,
     369           0 :                                                        resultTail);
     370           0 :         arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
     371           0 :         arr->Item(2).SetFloatValue(y, eCSSUnit_Number);
     372           0 :         arr->Item(3).SetFloatValue(z, eCSSUnit_Number);
     373           0 :         SetCSSAngle(angle, arr->Item(4));
     374           0 :         break;
     375             :       }
     376             :       case TransformFunction::TScale:
     377             :       {
     378             :         arr =
     379           0 :           StyleAnimationValue::AppendTransformFunction(eCSSKeyword_scale3d,
     380           0 :                                                        resultTail);
     381           0 :         arr->Item(1).SetFloatValue(aFunctions[i].get_Scale().x(), eCSSUnit_Number);
     382           0 :         arr->Item(2).SetFloatValue(aFunctions[i].get_Scale().y(), eCSSUnit_Number);
     383           0 :         arr->Item(3).SetFloatValue(aFunctions[i].get_Scale().z(), eCSSUnit_Number);
     384           0 :         break;
     385             :       }
     386             :       case TransformFunction::TTranslation:
     387             :       {
     388             :         arr =
     389           0 :           StyleAnimationValue::AppendTransformFunction(eCSSKeyword_translate3d,
     390           0 :                                                        resultTail);
     391           0 :         arr->Item(1).SetFloatValue(aFunctions[i].get_Translation().x(), eCSSUnit_Pixel);
     392           0 :         arr->Item(2).SetFloatValue(aFunctions[i].get_Translation().y(), eCSSUnit_Pixel);
     393           0 :         arr->Item(3).SetFloatValue(aFunctions[i].get_Translation().z(), eCSSUnit_Pixel);
     394           0 :         break;
     395             :       }
     396             :       case TransformFunction::TSkewX:
     397             :       {
     398           0 :         const CSSAngle& x = aFunctions[i].get_SkewX().x();
     399           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_skewx,
     400           0 :                                                            resultTail);
     401           0 :         SetCSSAngle(x, arr->Item(1));
     402           0 :         break;
     403             :       }
     404             :       case TransformFunction::TSkewY:
     405             :       {
     406           0 :         const CSSAngle& y = aFunctions[i].get_SkewY().y();
     407           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_skewy,
     408           0 :                                                            resultTail);
     409           0 :         SetCSSAngle(y, arr->Item(1));
     410           0 :         break;
     411             :       }
     412             :       case TransformFunction::TSkew:
     413             :       {
     414           0 :         const CSSAngle& x = aFunctions[i].get_Skew().x();
     415           0 :         const CSSAngle& y = aFunctions[i].get_Skew().y();
     416           0 :         arr = StyleAnimationValue::AppendTransformFunction(eCSSKeyword_skew,
     417           0 :                                                            resultTail);
     418           0 :         SetCSSAngle(x, arr->Item(1));
     419           0 :         SetCSSAngle(y, arr->Item(2));
     420           0 :         break;
     421             :       }
     422             :       case TransformFunction::TTransformMatrix:
     423             :       {
     424             :         arr =
     425           0 :           StyleAnimationValue::AppendTransformFunction(eCSSKeyword_matrix3d,
     426           0 :                                                        resultTail);
     427           0 :         const gfx::Matrix4x4& matrix = aFunctions[i].get_TransformMatrix().value();
     428           0 :         arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number);
     429           0 :         arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number);
     430           0 :         arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number);
     431           0 :         arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number);
     432           0 :         arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number);
     433           0 :         arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number);
     434           0 :         arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number);
     435           0 :         arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number);
     436           0 :         arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number);
     437           0 :         arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number);
     438           0 :         arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number);
     439           0 :         arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number);
     440           0 :         arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number);
     441           0 :         arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number);
     442           0 :         arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number);
     443           0 :         arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number);
     444           0 :         break;
     445             :       }
     446             :       case TransformFunction::TPerspective:
     447             :       {
     448           0 :         float perspective = aFunctions[i].get_Perspective().value();
     449             :         arr =
     450           0 :           StyleAnimationValue::AppendTransformFunction(eCSSKeyword_perspective,
     451           0 :                                                        resultTail);
     452           0 :         arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel);
     453           0 :         break;
     454             :       }
     455             :       default:
     456           0 :         NS_ASSERTION(false, "All functions should be implemented?");
     457             :     }
     458             :   }
     459           0 :   if (aFunctions.Length() == 0) {
     460           0 :     result = new nsCSSValueList();
     461           0 :     result->mValue.SetNoneValue();
     462             :   }
     463           0 :   return new nsCSSValueSharedList(result.forget());
     464             : }
     465             : 
     466             : static StyleAnimationValue
     467           0 : ToStyleAnimationValue(const Animatable& aAnimatable)
     468             : {
     469           0 :   StyleAnimationValue result;
     470             : 
     471           0 :   switch (aAnimatable.type()) {
     472             :     case Animatable::Tnull_t:
     473           0 :       break;
     474             :     case Animatable::TArrayOfTransformFunction: {
     475             :       const InfallibleTArray<TransformFunction>& transforms =
     476           0 :         aAnimatable.get_ArrayOfTransformFunction();
     477           0 :       result.SetTransformValue(CreateCSSValueList(transforms));
     478           0 :       break;
     479             :     }
     480             :     case Animatable::Tfloat:
     481           0 :       result.SetFloatValue(aAnimatable.get_float());
     482           0 :       break;
     483             :     default:
     484           0 :       MOZ_ASSERT_UNREACHABLE("Unsupported type");
     485             :   }
     486             : 
     487           0 :   return result;
     488             : }
     489             : 
     490             : void
     491         124 : AnimationHelper::SetAnimations(AnimationArray& aAnimations,
     492             :                                InfallibleTArray<AnimData>& aAnimData,
     493             :                                StyleAnimationValue& aBaseAnimationStyle)
     494             : {
     495         124 :   for (uint32_t i = 0; i < aAnimations.Length(); i++) {
     496           0 :     Animation& animation = aAnimations[i];
     497             :     // Adjust fill mode to fill forwards so that if the main thread is delayed
     498             :     // in clearing this animation we don't introduce flicker by jumping back to
     499             :     // the old underlying value
     500           0 :     switch (static_cast<dom::FillMode>(animation.fillMode())) {
     501             :       case dom::FillMode::None:
     502           0 :         animation.fillMode() = static_cast<uint8_t>(dom::FillMode::Forwards);
     503           0 :         break;
     504             :       case dom::FillMode::Backwards:
     505           0 :         animation.fillMode() = static_cast<uint8_t>(dom::FillMode::Both);
     506           0 :         break;
     507             :       default:
     508           0 :         break;
     509             :     }
     510             : 
     511           0 :     if (animation.baseStyle().type() != Animatable::Tnull_t) {
     512           0 :       aBaseAnimationStyle = ToStyleAnimationValue(animation.baseStyle());
     513             :     }
     514             : 
     515           0 :     AnimData* data = aAnimData.AppendElement();
     516             :     InfallibleTArray<Maybe<ComputedTimingFunction>>& functions =
     517           0 :       data->mFunctions;
     518           0 :     const InfallibleTArray<AnimationSegment>& segments = animation.segments();
     519           0 :     for (uint32_t j = 0; j < segments.Length(); j++) {
     520           0 :       TimingFunction tf = segments.ElementAt(j).sampleFn();
     521             : 
     522             :       Maybe<ComputedTimingFunction> ctf =
     523           0 :         AnimationUtils::TimingFunctionToComputedTimingFunction(tf);
     524           0 :       functions.AppendElement(ctf);
     525             :     }
     526             : 
     527             :     // Precompute the StyleAnimationValues that we need if this is a transform
     528             :     // animation.
     529           0 :     InfallibleTArray<StyleAnimationValue>& startValues = data->mStartValues;
     530           0 :     InfallibleTArray<StyleAnimationValue>& endValues = data->mEndValues;
     531           0 :     for (const AnimationSegment& segment : segments) {
     532           0 :       startValues.AppendElement(ToStyleAnimationValue(segment.startState()));
     533           0 :       endValues.AppendElement(ToStyleAnimationValue(segment.endState()));
     534             :     }
     535             :   }
     536         124 : }
     537             : 
     538             : uint64_t
     539           0 : AnimationHelper::GetNextCompositorAnimationsId()
     540             : {
     541             :   static uint32_t sNextId = 0;
     542           0 :   ++sNextId;
     543             : 
     544           0 :   uint32_t procId = static_cast<uint32_t>(base::GetCurrentProcId());
     545           0 :   uint64_t nextId = procId;
     546           0 :   nextId = nextId << 32 | sNextId;
     547           0 :   return nextId;
     548             : }
     549             : 
     550             : void
     551           0 : AnimationHelper::SampleAnimations(CompositorAnimationStorage* aStorage,
     552             :                                   TimeStamp aTime)
     553             : {
     554           0 :   MOZ_ASSERT(aStorage);
     555             : 
     556             :   // Do nothing if there are no compositor animations
     557           0 :   if (!aStorage->AnimationsCount()) {
     558           0 :     return;
     559             :   }
     560             : 
     561             :   //Sample the animations in CompositorAnimationStorage
     562           0 :   for (auto iter = aStorage->ConstAnimationsTableIter();
     563           0 :        !iter.Done(); iter.Next()) {
     564           0 :     bool hasInEffectAnimations = false;
     565           0 :     AnimationArray* animations = iter.UserData();
     566           0 :     StyleAnimationValue animationValue;
     567           0 :     InfallibleTArray<AnimData> animationData;
     568             :     AnimationHelper::SetAnimations(*animations,
     569             :                                    animationData,
     570           0 :                                    animationValue);
     571             :     AnimationHelper::SampleAnimationForEachNode(aTime,
     572             :                                                 *animations,
     573             :                                                 animationData,
     574             :                                                 animationValue,
     575           0 :                                                 hasInEffectAnimations);
     576             : 
     577           0 :     if (!hasInEffectAnimations) {
     578           0 :       continue;
     579             :     }
     580             : 
     581             :     // Store the AnimatedValue
     582           0 :     Animation& animation = animations->LastElement();
     583           0 :     switch (animation.property()) {
     584             :       case eCSSProperty_opacity: {
     585           0 :         aStorage->SetAnimatedValue(iter.Key(),
     586           0 :                                    animationValue.GetFloatValue());
     587           0 :         break;
     588             :       }
     589             :       case eCSSProperty_transform: {
     590           0 :         nsCSSValueSharedList* list = animationValue.GetCSSValueSharedListValue();
     591           0 :         const TransformData& transformData = animation.data().get_TransformData();
     592           0 :         nsPoint origin = transformData.origin();
     593             :         // we expect all our transform data to arrive in device pixels
     594           0 :         gfx::Point3D transformOrigin = transformData.transformOrigin();
     595             :         nsDisplayTransform::FrameTransformProperties props(list,
     596           0 :                                                            transformOrigin);
     597             : 
     598             :         gfx::Matrix4x4 transform =
     599             :           nsDisplayTransform::GetResultingTransformMatrix(props, origin,
     600           0 :                                                           transformData.appUnitsPerDevPixel(),
     601           0 :                                                           0, &transformData.bounds());
     602           0 :         gfx::Matrix4x4 frameTransform = transform;
     603             :         // If the parent has perspective transform, then the offset into reference
     604             :         // frame coordinates is already on this transform. If not, then we need to ask
     605             :         // for it to be added here.
     606           0 :         if (!transformData.hasPerspectiveParent()) {
     607           0 :            nsLayoutUtils::PostTranslate(transform, origin,
     608           0 :                                         transformData.appUnitsPerDevPixel(),
     609           0 :                                         true);
     610             :         }
     611             : 
     612           0 :         transform.PostScale(transformData.inheritedXScale(),
     613           0 :                             transformData.inheritedYScale(),
     614           0 :                             1);
     615             : 
     616           0 :         aStorage->SetAnimatedValue(iter.Key(),
     617           0 :                                    Move(transform), Move(frameTransform),
     618           0 :                                    transformData);
     619           0 :         break;
     620             :       }
     621             :       default:
     622           0 :         MOZ_ASSERT_UNREACHABLE("Unhandled animated property");
     623             :     }
     624             :   }
     625             : }
     626             : 
     627             : } // namespace layers
     628             : } // namespace mozilla

Generated by: LCOV version 1.13