tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

CompositorAnimationStorage.h (8134B)


      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 #ifndef mozilla_layers_CompositorAnimationStorage_h
      8 #define mozilla_layers_CompositorAnimationStorage_h
      9 
     10 #include "mozilla/layers/AnimationStorageData.h"
     11 #include "mozilla/layers/LayersMessages.h"  // for TransformData, etc
     12 #include "mozilla/webrender/webrender_ffi.h"
     13 #include "mozilla/Variant.h"
     14 #include "nsClassHashtable.h"
     15 #include "X11UndefineNone.h"
     16 #include <memory>
     17 #include <unordered_map>
     18 #include <unordered_set>
     19 
     20 namespace mozilla {
     21 namespace layers {
     22 class APZSampler;
     23 class Animation;
     24 class CompositorBridgeParent;
     25 class OMTAController;
     26 
     27 using AnimationArray = nsTArray<layers::Animation>;
     28 using SampledAnimationArray = AutoTArray<RefPtr<StyleAnimationValue>, 1>;
     29 
     30 struct AnimationTransform {
     31  /*
     32   * This transform is calculated from frame used for WebRender and used by
     33   * getOMTAStyle() for OMTA testing.
     34   */
     35  gfx::Matrix4x4 mFrameTransform;
     36  TransformData mData;
     37 
     38  /*
     39   * Store the previous sampled transform-like animation values.
     40   * It's unfortunate we have to keep the previous sampled animation value for
     41   * replacing the running transition, because we can not re-create the
     42   * AnimationValues from the matrix.
     43   * Note: We expect the length is one in most cases.
     44   */
     45  SampledAnimationArray mAnimationValues;
     46 };
     47 
     48 struct AnimatedValue final {
     49  typedef Variant<AnimationTransform, float, nscolor> AnimatedValueType;
     50 
     51  const AnimatedValueType& Value() const { return mValue; }
     52  const AnimationTransform& Transform() const {
     53    return mValue.as<AnimationTransform>();
     54  }
     55  const float& Opacity() const { return mValue.as<float>(); }
     56  const nscolor& Color() const { return mValue.as<nscolor>(); }
     57  template <typename T>
     58  bool Is() const {
     59    return mValue.is<T>();
     60  }
     61 
     62  AnimatedValue(const gfx::Matrix4x4& aFrameTransform,
     63                const TransformData& aData, SampledAnimationArray&& aValue)
     64      : mValue(AsVariant(
     65            AnimationTransform{aFrameTransform, aData, std::move(aValue)})) {}
     66 
     67  explicit AnimatedValue(const float& aValue) : mValue(AsVariant(aValue)) {}
     68 
     69  explicit AnimatedValue(nscolor aValue) : mValue(AsVariant(aValue)) {}
     70 
     71  // Note: Only transforms need to store the sampled AnimationValue because it's
     72  // impossible to re-create the AnimationValue from the matrix.
     73  void SetTransform(const gfx::Matrix4x4& aFrameTransform,
     74                    const TransformData& aData,
     75                    SampledAnimationArray&& aValue) {
     76    MOZ_ASSERT(mValue.is<AnimationTransform>());
     77    AnimationTransform& previous = mValue.as<AnimationTransform>();
     78    previous.mFrameTransform = aFrameTransform;
     79    if (previous.mData != aData) {
     80      previous.mData = aData;
     81    }
     82    previous.mAnimationValues = std::move(aValue);
     83  }
     84  void SetOpacity(float aOpacity) {
     85    MOZ_ASSERT(mValue.is<float>());
     86    mValue.as<float>() = aOpacity;
     87  }
     88  void SetColor(nscolor aColor) {
     89    MOZ_ASSERT(mValue.is<nscolor>());
     90    mValue.as<nscolor>() = aColor;
     91  }
     92 
     93  already_AddRefed<StyleAnimationValue> AsAnimationValue(
     94      NonCustomCSSPropertyId) const;
     95 
     96 private:
     97  AnimatedValueType mValue;
     98 };
     99 
    100 struct WrAnimations {
    101  nsTArray<wr::WrOpacityProperty> mOpacityArrays;
    102  nsTArray<wr::WrTransformProperty> mTransformArrays;
    103  nsTArray<wr::WrColorProperty> mColorArrays;
    104 };
    105 
    106 // CompositorAnimationStorage stores the animations and animated values
    107 // keyed by a CompositorAnimationsId. The "animations" are a representation of
    108 // an entire animation over time, while the "animated values" are values sampled
    109 // from the animations at a particular point in time.
    110 //
    111 // There is one CompositorAnimationStorage per CompositorBridgeParent (i.e.
    112 // one per browser window), and the CompositorAnimationsId key is unique within
    113 // a particular CompositorAnimationStorage instance.
    114 //
    115 // Each layer which has animations gets a CompositorAnimationsId key, and reuses
    116 // that key during its lifetime. Likewise, in layers-free webrender, a display
    117 // item that is animated (e.g. nsDisplayTransform) gets a CompositorAnimationsId
    118 // key and reuses that key (it persists the key via the frame user-data
    119 // mechanism).
    120 class CompositorAnimationStorage final {
    121  typedef nsClassHashtable<nsUint64HashKey, AnimatedValue> AnimatedValueTable;
    122  typedef std::unordered_map<uint64_t, std::unique_ptr<AnimationStorageData>>
    123      AnimationsTable;
    124 
    125  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorAnimationStorage)
    126 public:
    127  explicit CompositorAnimationStorage(CompositorBridgeParent* aCompositorBridge)
    128      : mLock("CompositorAnimationStorage::mLock"),
    129        mCompositorBridge(aCompositorBridge) {}
    130 
    131  OMTAValue GetOMTAValue(const uint64_t& aId) const;
    132 
    133  /**
    134   * Collect all animations in this class as WebRender type properties.
    135   */
    136  WrAnimations CollectWebRenderAnimations() const;
    137 
    138  /**
    139   * Set the animations based on the unique id
    140   */
    141  void SetAnimations(uint64_t aId, const LayersId& aLayersId,
    142                     const AnimationArray& aAnimations,
    143                     const TimeStamp& aPreviousSampleTime);
    144 
    145  /**
    146   * Sample animation based the given timestamps and store them in this
    147   * CompositorAnimationStorage. The animated values after sampling will be
    148   * stored in CompositorAnimationStorage as well.
    149   *
    150   * Returns true if there is any animation.
    151   * Note that even if there are only in-delay phase animations (i.e. not
    152   * visually effective), this function returns true to ensure we composite
    153   * again on the next tick.
    154   *
    155   * Note: This is called only by WebRender.
    156   */
    157  bool SampleAnimations(const OMTAController* aOMTAController,
    158                        TimeStamp aPreviousFrameTime,
    159                        TimeStamp aCurrentFrameTime);
    160 
    161  bool HasAnimations() const;
    162 
    163  /**
    164   * Clear AnimatedValues and Animations data
    165   */
    166  void ClearById(const uint64_t& aId);
    167 
    168  /**
    169   * Return the animated value if a given id can map to its animated value
    170   */
    171  AnimatedValue* GetAnimatedValue(const uint64_t& aId) const;
    172 
    173 private:
    174  ~CompositorAnimationStorage() = default;
    175 
    176  /**
    177   * Set the animation transform based on the unique id and also
    178   * set up |aFrameTransform| and |aData| for OMTA testing.
    179   * If |aPreviousValue| is not null, the animation transform replaces the value
    180   * in the |aPreviousValue|.
    181   * NOTE: |aPreviousValue| should be the value for the |aId|.
    182   */
    183  void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
    184                        const gfx::Matrix4x4& aFrameTransform,
    185                        const TransformData& aData,
    186                        SampledAnimationArray&& aValue);
    187 
    188  /**
    189   * Similar to above but for opacity.
    190   */
    191  void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
    192                        float aOpacity);
    193 
    194  /**
    195   * Similar to above but for color.
    196   */
    197  void SetAnimatedValue(uint64_t aId, AnimatedValue* aPreviousValue,
    198                        nscolor aColor);
    199 
    200  using JankedAnimationMap =
    201      std::unordered_map<LayersId, nsTArray<uint64_t>, LayersId::HashFn>;
    202 
    203  /*
    204   * Store the animated values from |aAnimationValues|.
    205   */
    206  void StoreAnimatedValue(
    207      NonCustomCSSPropertyId aProperty, uint64_t aId,
    208      const std::unique_ptr<AnimationStorageData>& aAnimationStorageData,
    209      SampledAnimationArray&& aAnimationValues,
    210      const MutexAutoLock& aProofOfMapLock,
    211      const RefPtr<APZSampler>& aApzSampler, AnimatedValue* aAnimatedValueEntry,
    212      JankedAnimationMap& aJankedAnimationMap);
    213 
    214 private:
    215  AnimatedValueTable mAnimatedValues;
    216  AnimationsTable mAnimations;
    217  std::unordered_set<uint64_t> mNewAnimations;
    218  mutable Mutex mLock MOZ_UNANNOTATED;
    219  // CompositorBridgeParent owns this CompositorAnimationStorage instance.
    220  CompositorBridgeParent* MOZ_NON_OWNING_REF mCompositorBridge;
    221 };
    222 
    223 }  // namespace layers
    224 }  // namespace mozilla
    225 
    226 #endif  // mozilla_layers_CompositorAnimationStorage_h