зеркало из https://github.com/mozilla/gecko-dev.git
240 строки
7.2 KiB
C++
240 строки
7.2 KiB
C++
/* -*- 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
|
|
#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
|
|
#include "mozilla/TimeStamp.h" // for TimeStamp
|
|
|
|
|
|
namespace mozilla {
|
|
struct AnimationValue;
|
|
namespace layers {
|
|
class Animation;
|
|
|
|
typedef InfallibleTArray<layers::Animation> AnimationArray;
|
|
|
|
struct AnimData {
|
|
InfallibleTArray<mozilla::AnimationValue> mStartValues;
|
|
InfallibleTArray<mozilla::AnimationValue> mEndValues;
|
|
InfallibleTArray<Maybe<mozilla::ComputedTimingFunction>> mFunctions;
|
|
};
|
|
|
|
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 animations and animated values
|
|
// keyed by a CompositorAnimationsId. The "animations" are a representation of
|
|
// an entire animation over time, while the "animated values" are values sampled
|
|
// from the animations at a particular point in time.
|
|
//
|
|
// There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
|
|
// one per browser window), and the CompositorAnimationsId key is unique within
|
|
// a particular CompositorAnimationStorage instance.
|
|
//
|
|
// Each layer which has animations gets a CompositorAnimationsId key, and reuses
|
|
// that key during its lifetime. Likewise, in layers-free webrender, a display
|
|
// item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
|
|
// key and reuses that key (it persists the key via the frame user-data
|
|
// mechanism).
|
|
class CompositorAnimationStorage final
|
|
{
|
|
typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
|
|
typedef nsClassHashtable<nsUint64HashKey, AnimationArray> AnimationsTable;
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
|
|
public:
|
|
|
|
/**
|
|
* Set the animation transform based on the unique id and also
|
|
* set up |aFrameTransform| and |aData| for OMTA testing
|
|
*/
|
|
void SetAnimatedValue(uint64_t aId,
|
|
gfx::Matrix4x4&& aTransformInDevSpace,
|
|
gfx::Matrix4x4&& aFrameTransform,
|
|
const TransformData& aData);
|
|
|
|
/**
|
|
* Set the animation transform in device pixel based on the unique id
|
|
*/
|
|
void SetAnimatedValue(uint64_t aId,
|
|
gfx::Matrix4x4&& aTransformInDevSpace);
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Like GetAnimatedValue(), but ensures the value is an opacity and returns
|
|
* the float value if possible, or Nothing() otherwise.
|
|
*/
|
|
Maybe<float> GetAnimationOpacity(const uint64_t& aId) const;
|
|
|
|
/**
|
|
* Like GetAnimatedValue(), but ensures the value is a transform and returns
|
|
* the transform matrix if possible, or Nothing() otherwise. It also does
|
|
* some post-processing on the transform matrix as well. See the comments
|
|
* inside the function for details.
|
|
*/
|
|
Maybe<gfx::Matrix4x4> GetAnimationTransform(const uint64_t& aId) const;
|
|
|
|
/**
|
|
* Return the iterator of animated value table
|
|
*/
|
|
AnimatedValueTable::Iterator ConstAnimatedValueTableIter() const
|
|
{
|
|
return mAnimatedValues.ConstIter();
|
|
}
|
|
|
|
uint32_t AnimatedValueCount() const
|
|
{
|
|
return mAnimatedValues.Count();
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Return the iterator of animations table
|
|
*/
|
|
AnimationsTable::Iterator ConstAnimationsTableIter() const
|
|
{
|
|
return mAnimations.ConstIter();
|
|
}
|
|
|
|
uint32_t AnimationsCount() const
|
|
{
|
|
return mAnimations.Count();
|
|
}
|
|
|
|
/**
|
|
* Clear AnimatedValues and Animations data
|
|
*/
|
|
void Clear();
|
|
void ClearById(const uint64_t& aId);
|
|
|
|
private:
|
|
~CompositorAnimationStorage() { };
|
|
|
|
private:
|
|
AnimatedValueTable mAnimatedValues;
|
|
AnimationsTable mAnimations;
|
|
};
|
|
|
|
/**
|
|
* This utility class allows reusing code between the webrender and
|
|
* non-webrender compositor-side implementations. It provides
|
|
* utility functions for sampling animations at particular timestamps.
|
|
*/
|
|
class AnimationHelper
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* 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|.
|
|
*/
|
|
static bool
|
|
SampleAnimationForEachNode(TimeStamp aTime,
|
|
AnimationArray& aAnimations,
|
|
InfallibleTArray<AnimData>& aAnimationData,
|
|
AnimationValue& aAnimationValue,
|
|
bool& aHasInEffectAnimations);
|
|
/**
|
|
* Populates AnimData stuctures into |aAnimData| and |aBaseAnimationStyle|
|
|
* based on |aAnimations|.
|
|
*/
|
|
static void
|
|
SetAnimations(AnimationArray& aAnimations,
|
|
InfallibleTArray<AnimData>& aAnimData,
|
|
AnimationValue& aBaseAnimationStyle);
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
static uint64_t GetNextCompositorAnimationsId();
|
|
|
|
/**
|
|
* 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);
|
|
};
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_layers_AnimationHelper_h
|