From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- gfx/layers/CompositorAnimationStorage.h | 213 ++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 gfx/layers/CompositorAnimationStorage.h (limited to 'gfx/layers/CompositorAnimationStorage.h') diff --git a/gfx/layers/CompositorAnimationStorage.h b/gfx/layers/CompositorAnimationStorage.h new file mode 100644 index 0000000000..7d6b7dc3a7 --- /dev/null +++ b/gfx/layers/CompositorAnimationStorage.h @@ -0,0 +1,213 @@ +/* -*- 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 +#include +#include + +namespace mozilla { +namespace layers { +class APZSampler; +class Animation; +class CompositorBridgeParent; +class OMTAController; + +typedef nsTArray AnimationArray; + +struct AnimationTransform { + /* + * This transform is calculated from sampleanimation in device pixel + * and used for layers (i.e. non WebRender) + */ + gfx::Matrix4x4 mTransformInDevSpace; + /* + * This transform is calculated from frame used for WebRender and used by + * getOMTAStyle() for OMTA testing. + */ + gfx::Matrix4x4 mFrameTransform; + TransformData mData; +}; + +struct AnimatedValue final { + typedef Variant AnimatedValueType; + + const AnimatedValueType& Value() const { return mValue; } + const AnimationTransform& Transform() const { + return mValue.as(); + } + const float& Opacity() const { return mValue.as(); } + const nscolor& Color() const { return mValue.as(); } + template + bool Is() const { + return mValue.is(); + } + + AnimatedValue(const gfx::Matrix4x4& aTransformInDevSpace, + const gfx::Matrix4x4& aFrameTransform, + const TransformData& aData) + : mValue(AsVariant(AnimationTransform{aTransformInDevSpace, + aFrameTransform, aData})) {} + + explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {} + + explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {} + + void SetTransform(const gfx::Matrix4x4& aFrameTransform, + const TransformData& aData) { + MOZ_ASSERT(mValue.is()); + AnimationTransform& previous = mValue.as(); + previous.mFrameTransform = aFrameTransform; + if (previous.mData != aData) { + previous.mData = aData; + } + } + void SetOpacity(float aOpacity) { + MOZ_ASSERT(mValue.is()); + mValue.as() = aOpacity; + } + void SetColor(nscolor aColor) { + MOZ_ASSERT(mValue.is()); + mValue.as() = aColor; + } + + private: + AnimatedValueType mValue; +}; + +struct WrAnimations { + nsTArray mOpacityArrays; + nsTArray mTransformArrays; + nsTArray 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 AnimatedValueTable; + typedef std::unordered_map> + 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); + + /** + * 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); + + private: + ~CompositorAnimationStorage() = default; + + /** + * Return the animated value if a given id can map to its animated value + */ + AnimatedValue* GetAnimatedValue(const uint64_t& aId) const; + + /** + * 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); + + /** + * 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::HashFn>; + + /* + * Store the animated values from |aAnimationValues|. + */ + void StoreAnimatedValue( + nsCSSPropertyID aProperty, uint64_t aId, + const std::unique_ptr& aAnimationStorageData, + const AutoTArray, 1>& aAnimationValues, + const MutexAutoLock& aProofOfMapLock, + const RefPtr& aApzSampler, AnimatedValue* aAnimatedValueEntry, + JankedAnimationMap& aJankedAnimationMap); + + private: + AnimatedValueTable mAnimatedValues; + AnimationsTable mAnimations; + std::unordered_set 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 -- cgit v1.2.3