mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 00:32:11 +00:00
062b8a9269
Differential Revision: https://phabricator.services.mozilla.com/D219196
226 lines
7.9 KiB
C++
226 lines
7.9 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_CompositorAnimationStorage_h
|
|
#define mozilla_layers_CompositorAnimationStorage_h
|
|
|
|
#include "mozilla/layers/AnimationStorageData.h"
|
|
#include "mozilla/layers/LayersMessages.h" // for TransformData, etc
|
|
#include "mozilla/webrender/webrender_ffi.h"
|
|
#include "mozilla/Variant.h"
|
|
#include "nsClassHashtable.h"
|
|
#include "X11UndefineNone.h"
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
|
|
namespace mozilla {
|
|
namespace layers {
|
|
class APZSampler;
|
|
class Animation;
|
|
class CompositorBridgeParent;
|
|
class OMTAController;
|
|
|
|
using AnimationArray = nsTArray<layers::Animation>;
|
|
using SampledAnimationArray = AutoTArray<RefPtr<StyleAnimationValue>, 1>;
|
|
|
|
struct AnimationTransform {
|
|
/*
|
|
* This transform is calculated from frame used for WebRender and used by
|
|
* getOMTAStyle() for OMTA testing.
|
|
*/
|
|
gfx::Matrix4x4 mFrameTransform;
|
|
TransformData mData;
|
|
|
|
/*
|
|
* Store the previous sampled transform-like animation values.
|
|
* It's unfortunate we have to keep the previous sampled animation value for
|
|
* replacing the running transition, because we can not re-create the
|
|
* AnimationValues from the matrix.
|
|
* Note: We expect the length is one in most cases.
|
|
*/
|
|
SampledAnimationArray mAnimationValues;
|
|
};
|
|
|
|
struct AnimatedValue final {
|
|
typedef Variant<AnimationTransform, float, nscolor> AnimatedValueType;
|
|
|
|
const AnimatedValueType& Value() const { return mValue; }
|
|
const AnimationTransform& Transform() const {
|
|
return mValue.as<AnimationTransform>();
|
|
}
|
|
const float& Opacity() const { return mValue.as<float>(); }
|
|
const nscolor& Color() const { return mValue.as<nscolor>(); }
|
|
template <typename T>
|
|
bool Is() const {
|
|
return mValue.is<T>();
|
|
}
|
|
|
|
AnimatedValue(const gfx::Matrix4x4& aFrameTransform,
|
|
const TransformData& aData, SampledAnimationArray&& aValue)
|
|
: mValue(AsVariant(
|
|
AnimationTransform{aFrameTransform, aData, std::move(aValue)})) {}
|
|
|
|
explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {}
|
|
|
|
explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {}
|
|
|
|
// Note: Only transforms need to store the sampled AnimationValue because it's
|
|
// impossible to re-create the AnimationValue from the matrix.
|
|
void SetTransform(const gfx::Matrix4x4& aFrameTransform,
|
|
const TransformData& aData,
|
|
SampledAnimationArray&& aValue) {
|
|
MOZ_ASSERT(mValue.is<AnimationTransform>());
|
|
AnimationTransform& previous = mValue.as<AnimationTransform>();
|
|
previous.mFrameTransform = aFrameTransform;
|
|
if (previous.mData != aData) {
|
|
previous.mData = aData;
|
|
}
|
|
previous.mAnimationValues = std::move(aValue);
|
|
}
|
|
void SetOpacity(float aOpacity) {
|
|
MOZ_ASSERT(mValue.is<float>());
|
|
mValue.as<float>() = aOpacity;
|
|
}
|
|
void SetColor(nscolor aColor) {
|
|
MOZ_ASSERT(mValue.is<nscolor>());
|
|
mValue.as<nscolor>() = aColor;
|
|
}
|
|
|
|
already_AddRefed<StyleAnimationValue> AsAnimationValue(nsCSSPropertyID) const;
|
|
|
|
private:
|
|
AnimatedValueType mValue;
|
|
};
|
|
|
|
struct WrAnimations {
|
|
nsTArray<wr::WrOpacityProperty> mOpacityArrays;
|
|
nsTArray<wr::WrTransformProperty> mTransformArrays;
|
|
nsTArray<wr::WrColorProperty> mColorArrays;
|
|
};
|
|
|
|
// 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 std::unordered_map<uint64_t, std::unique_ptr<AnimationStorageData>>
|
|
AnimationsTable;
|
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
|
|
public:
|
|
explicit CompositorAnimationStorage(CompositorBridgeParent* aCompositorBridge)
|
|
: mLock("CompositorAnimationStorage::mLock"),
|
|
mCompositorBridge(aCompositorBridge) {}
|
|
|
|
OMTAValue GetOMTAValue(const uint64_t& aId) const;
|
|
|
|
/**
|
|
* Collect all animations in this class as WebRender type properties.
|
|
*/
|
|
WrAnimations CollectWebRenderAnimations() const;
|
|
|
|
/**
|
|
* Set the animations based on the unique id
|
|
*/
|
|
void SetAnimations(uint64_t aId, const LayersId& aLayersId,
|
|
const AnimationArray& aAnimations,
|
|
const TimeStamp& aPreviousSampleTime);
|
|
|
|
/**
|
|
* Sample animation based the given timestamps and store them in this
|
|
* CompositorAnimationStorage. The animated values after sampling will be
|
|
* stored in CompositorAnimationStorage as well.
|
|
*
|
|
* Returns true if there is any animation.
|
|
* Note that even if there are only in-delay phase animations (i.e. not
|
|
* visually effective), this function returns true to ensure we composite
|
|
* again on the next tick.
|
|
*
|
|
* Note: This is called only by WebRender.
|
|
*/
|
|
bool SampleAnimations(const OMTAController* aOMTAController,
|
|
TimeStamp aPreviousFrameTime,
|
|
TimeStamp aCurrentFrameTime);
|
|
|
|
bool HasAnimations() const;
|
|
|
|
/**
|
|
* Clear AnimatedValues and Animations data
|
|
*/
|
|
void ClearById(const uint64_t& aId);
|
|
|
|
/**
|
|
* Return the animated value if a given id can map to its animated value
|
|
*/
|
|
AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
|
|
|
|
private:
|
|
~CompositorAnimationStorage() = default;
|
|
|
|
/**
|
|
* Set the animation transform based on the unique id and also
|
|
* set up |aFrameTransform| and |aData| for OMTA testing.
|
|
* If |aPreviousValue| is not null, the animation transform replaces the value
|
|
* in the |aPreviousValue|.
|
|
* NOTE: |aPreviousValue| should be the value for the |aId|.
|
|
*/
|
|
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
|
|
const gfx::Matrix4x4& aFrameTransform,
|
|
const TransformData& aData,
|
|
SampledAnimationArray&& aValue);
|
|
|
|
/**
|
|
* Similar to above but for opacity.
|
|
*/
|
|
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
|
|
float aOpacity);
|
|
|
|
/**
|
|
* Similar to above but for color.
|
|
*/
|
|
void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
|
|
nscolor aColor);
|
|
|
|
using JankedAnimationMap =
|
|
std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn>;
|
|
|
|
/*
|
|
* Store the animated values from |aAnimationValues|.
|
|
*/
|
|
void StoreAnimatedValue(
|
|
nsCSSPropertyID aProperty, uint64_t aId,
|
|
const std::unique_ptr<AnimationStorageData>& aAnimationStorageData,
|
|
SampledAnimationArray&& aAnimationValues,
|
|
const MutexAutoLock& aProofOfMapLock,
|
|
const RefPtr<APZSampler>& aApzSampler, AnimatedValue* aAnimatedValueEntry,
|
|
JankedAnimationMap& aJankedAnimationMap);
|
|
|
|
private:
|
|
AnimatedValueTable mAnimatedValues;
|
|
AnimationsTable mAnimations;
|
|
std::unordered_set<uint64_t> mNewAnimations;
|
|
mutable Mutex mLock MOZ_UNANNOTATED;
|
|
// CompositorBridgeParent owns this CompositorAnimationStorage instance.
|
|
CompositorBridgeParent* MOZ_NON_OWNING_REF mCompositorBridge;
|
|
};
|
|
|
|
} // namespace layers
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_layers_CompositorAnimationStorage_h
|