2017-01-25 05:51:30 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef mozilla_layers_AnimationHelper_h
|
|
|
|
#define mozilla_layers_AnimationHelper_h
|
|
|
|
|
|
|
|
#include "mozilla/ComputedTimingFunction.h" // for ComputedTimingFunction
|
2017-02-10 01:30:11 +03:00
|
|
|
#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
|
2017-01-25 05:51:30 +03:00
|
|
|
#include "mozilla/TimeStamp.h" // for TimeStamp
|
|
|
|
|
|
|
|
|
|
|
|
namespace mozilla {
|
2017-02-10 01:30:11 +03:00
|
|
|
class StyleAnimationValue;
|
2017-01-25 05:51:30 +03:00
|
|
|
namespace layers {
|
|
|
|
class Animation;
|
|
|
|
|
|
|
|
typedef InfallibleTArray<layers::Animation> AnimationArray;
|
|
|
|
|
|
|
|
struct AnimData {
|
|
|
|
InfallibleTArray<mozilla::StyleAnimationValue> mStartValues;
|
|
|
|
InfallibleTArray<mozilla::StyleAnimationValue> mEndValues;
|
|
|
|
InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
|
|
|
|
};
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
struct AnimationTransform {
|
|
|
|
/*
|
|
|
|
* This transform is calculated from sampleanimation in device pixel
|
|
|
|
* and used by compositor.
|
|
|
|
*/
|
|
|
|
gfx::Matrix4x4 mTransformInDevSpace;
|
|
|
|
/*
|
|
|
|
* This transform is calculated from frame and used by getOMTAStyle()
|
|
|
|
* for OMTA testing.
|
|
|
|
*/
|
|
|
|
gfx::Matrix4x4 mFrameTransform;
|
|
|
|
TransformData mData;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AnimatedValue {
|
|
|
|
enum {
|
|
|
|
TRANSFORM,
|
|
|
|
OPACITY,
|
|
|
|
NONE
|
|
|
|
} mType {NONE};
|
|
|
|
|
|
|
|
union {
|
|
|
|
AnimationTransform mTransform;
|
|
|
|
float mOpacity;
|
|
|
|
};
|
|
|
|
|
|
|
|
AnimatedValue(gfx::Matrix4x4&& aTransformInDevSpace,
|
|
|
|
gfx::Matrix4x4&& aFrameTransform,
|
|
|
|
const TransformData& aData)
|
|
|
|
: mType(AnimatedValue::TRANSFORM)
|
|
|
|
{
|
|
|
|
mTransform.mTransformInDevSpace = Move(aTransformInDevSpace);
|
|
|
|
mTransform.mFrameTransform = Move(aFrameTransform);
|
|
|
|
mTransform.mData = aData;
|
|
|
|
}
|
|
|
|
|
|
|
|
explicit AnimatedValue(const float& aValue)
|
|
|
|
: mType(AnimatedValue::OPACITY)
|
|
|
|
, mOpacity(aValue)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
~AnimatedValue() {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
AnimatedValue() = delete;
|
|
|
|
};
|
|
|
|
|
|
|
|
// CompositorAnimationStorage stores the layer animations and animated value
|
|
|
|
// after sampling based on an unique id (CompositorAnimationsId)
|
|
|
|
class CompositorAnimationStorage final
|
2017-01-25 05:51:30 +03:00
|
|
|
{
|
2017-02-10 01:30:11 +03:00
|
|
|
typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
|
|
|
|
typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable;
|
|
|
|
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
|
2017-01-25 05:51:30 +03:00
|
|
|
public:
|
2017-01-26 10:04:16 +03:00
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
/**
|
2017-04-25 06:52:44 +03:00
|
|
|
* Set the animation transform based on the unique id and also
|
|
|
|
* set up |aFrameTransform| and |aData| for OMTA testing
|
2017-02-10 01:30:11 +03:00
|
|
|
*/
|
|
|
|
void SetAnimatedValue(uint64_t aId,
|
|
|
|
gfx::Matrix4x4&& aTransformInDevSpace,
|
|
|
|
gfx::Matrix4x4&& aFrameTransform,
|
|
|
|
const TransformData& aData);
|
|
|
|
|
2017-04-25 06:52:44 +03:00
|
|
|
/**
|
|
|
|
* Set the animation transform in device pixel based on the unique id
|
|
|
|
*/
|
|
|
|
void SetAnimatedValue(uint64_t aId,
|
|
|
|
gfx::Matrix4x4&& aTransformInDevSpace);
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
/**
|
|
|
|
* Set the animation opacity based on the unique id
|
|
|
|
*/
|
|
|
|
void SetAnimatedValue(uint64_t aId, const float& aOpacity);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the animated value if a given id can map to its animated value
|
|
|
|
*/
|
|
|
|
AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
/**
|
|
|
|
* Return the iterator of animated value table
|
|
|
|
*/
|
|
|
|
AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const
|
|
|
|
{
|
|
|
|
return mAnimatedValues.ConstIter();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t AnimatedValueCount() const
|
|
|
|
{
|
|
|
|
return mAnimatedValues.Count();
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
/**
|
|
|
|
* Set the animations based on the unique id
|
|
|
|
*/
|
|
|
|
void SetAnimations(uint64_t aId, const AnimationArray& aAnimations);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the animations if a given id can map to its animations
|
|
|
|
*/
|
|
|
|
AnimationArray* GetAnimations(const uint64_t& aId) const;
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
/**
|
|
|
|
* Return the iterator of animations table
|
|
|
|
*/
|
|
|
|
AnimationsTable::Iterator ConstAnimationsTableIter() const
|
|
|
|
{
|
|
|
|
return mAnimations.ConstIter();
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t AnimationsCount() const
|
|
|
|
{
|
|
|
|
return mAnimations.Count();
|
|
|
|
}
|
|
|
|
|
2017-02-10 01:30:11 +03:00
|
|
|
/**
|
|
|
|
* Clear AnimatedValues and Animations data
|
|
|
|
*/
|
|
|
|
void Clear();
|
|
|
|
|
2017-04-12 11:40:48 +03:00
|
|
|
void ClearById(const uint64_t& aId);
|
2017-02-10 01:30:11 +03:00
|
|
|
private:
|
|
|
|
~CompositorAnimationStorage() { Clear(); };
|
|
|
|
|
|
|
|
private:
|
|
|
|
AnimatedValueTable mAnimatedValues;
|
|
|
|
AnimationsTable mAnimations;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AnimationHelper
|
|
|
|
{
|
|
|
|
public:
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TODO Bug 1356509 Once we decouple the compositor animations and layers
|
|
|
|
* in parent side, the API will be called inside SampleAnimations.
|
|
|
|
* Before this, we expose this API for AsyncCompositionManager.
|
|
|
|
*
|
|
|
|
* Sample animations based on a given time stamp for a element(layer) with
|
|
|
|
* its animation data.
|
|
|
|
* Returns true if there exists compositor animation, and stores corresponding
|
|
|
|
* animated value in |aAnimationValue|.
|
|
|
|
*/
|
2017-01-26 10:04:16 +03:00
|
|
|
static bool
|
2017-04-12 11:40:48 +03:00
|
|
|
SampleAnimationForEachNode(TimeStamp aTime,
|
2017-01-26 10:04:16 +03:00
|
|
|
AnimationArray& aAnimations,
|
|
|
|
InfallibleTArray<AnimData>& aAnimationData,
|
|
|
|
StyleAnimationValue& aAnimationValue,
|
|
|
|
bool& aHasInEffectAnimations);
|
2017-04-12 11:40:48 +03:00
|
|
|
/*
|
|
|
|
* TODO Bug 1356509 Once we decouple the compositor animations and layers
|
|
|
|
* in parent side, the API will be called inside SampleAnimations.
|
|
|
|
* Before this, we expose this API for AsyncCompositionManager.
|
|
|
|
*
|
|
|
|
* Populates AnimData stuctures into |aAnimData| based on |aAnimations|
|
|
|
|
*/
|
2017-01-25 05:51:30 +03:00
|
|
|
static void
|
|
|
|
SetAnimations(AnimationArray& aAnimations,
|
|
|
|
InfallibleTArray<AnimData>& aAnimData,
|
|
|
|
StyleAnimationValue& aBaseAnimationStyle);
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Get a unique id to represent the compositor animation between child
|
|
|
|
* and parent side. This id will be used as a key to store animation
|
|
|
|
* data in the CompositorAnimationStorage per compositor.
|
|
|
|
* Each layer on the content side calls this when it gets new animation
|
|
|
|
* data.
|
|
|
|
*/
|
2017-02-08 22:31:45 +03:00
|
|
|
static uint64_t GetNextCompositorAnimationsId();
|
2017-04-12 11:40:48 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Sample animation based a given time stamp |aTime| and the animation
|
|
|
|
* data inside CompositorAnimationStorage |aStorage|. The animated values
|
|
|
|
* after sampling will be stored in CompositorAnimationStorage as well.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
SampleAnimations(CompositorAnimationStorage* aStorage,
|
|
|
|
TimeStamp aTime);
|
2017-01-25 05:51:30 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace layers
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_layers_AnimationHelper_h
|