tor-browser

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

OMTASampler.h (5617B)


      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_OMTASampler_h
      8 #define mozilla_layers_OMTASampler_h
      9 
     10 #include <unordered_map>
     11 #include <queue>
     12 
     13 #include "base/platform_thread.h"           // for PlatformThreadId
     14 #include "mozilla/layers/OMTAController.h"  // for OMTAController
     15 #include "mozilla/Atomics.h"
     16 #include "mozilla/Maybe.h"
     17 #include "mozilla/StaticMutex.h"
     18 #include "mozilla/StaticPtr.h"
     19 #include "mozilla/webrender/WebRenderTypes.h"  // For WrWindowId, WrEpoch, etc.
     20 
     21 namespace mozilla {
     22 
     23 class TimeStamp;
     24 
     25 namespace wr {
     26 struct Transaction;
     27 class TransactionWrapper;
     28 }  // namespace wr
     29 
     30 namespace layers {
     31 class Animation;
     32 class CompositorAnimationStorage;
     33 class OMTAValue;
     34 struct CompositorAnimationIdsForEpoch;
     35 struct LayersId;
     36 struct WrAnimations;
     37 
     38 /**
     39 * This interface exposes OMTA methods related to "sampling" (i.e. calculating
     40 * animating values) and "". All sampling methods should be called on the
     41 * sampler thread, all some of them should be called on the compositor thread.
     42 */
     43 class OMTASampler final {
     44  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(OMTASampler)
     45 
     46 public:
     47  OMTASampler(const RefPtr<CompositorAnimationStorage>& aAnimStorage,
     48              LayersId aRootLayersId);
     49 
     50  // Whoever creates this sampler is responsible for calling Destroy() on it
     51  // before releasing the owning refptr.
     52  void Destroy();
     53 
     54  void SetWebRenderWindowId(const wr::WrWindowId& aWindowId);
     55 
     56  /**
     57   * This function is invoked from rust on the render backend thread when it
     58   * is created. It effectively tells the OMTASampler "the current thread is
     59   * the sampler thread for this window id" and allows OMTASampler to remember
     60   * which thread it is.
     61   */
     62  static void SetSamplerThread(const wr::WrWindowId& aWindowId);
     63 
     64  static void Sample(const wr::WrWindowId& aWindowId, wr::Transaction* aTxn);
     65 
     66  /**
     67   * Sample all animations, called on the sampler thread.
     68   */
     69  void Sample(wr::TransactionWrapper& aTxn);
     70 
     71  /**
     72   * These funtions get called on the the compositor thread.
     73   */
     74  void SetSampleTime(const TimeStamp& aSampleTime);
     75  void ResetPreviousSampleTime();
     76  void SetAnimations(uint64_t aId, const LayersId& aLayersId,
     77                     const nsTArray<layers::Animation>& aAnimations);
     78  bool HasAnimations() const;
     79 
     80  /**
     81   * Clear AnimatedValues and Animations data, called on the compositor
     82   * thread.
     83   */
     84  void ClearActiveAnimations(
     85      std::unordered_map<uint64_t, wr::Epoch>& aActiveAnimations);
     86  void RemoveEpochDataPriorTo(
     87      std::queue<CompositorAnimationIdsForEpoch>& aCompositorAnimationsToDelete,
     88      std::unordered_map<uint64_t, wr::Epoch>& aActiveAnimations,
     89      const wr::Epoch& aRenderedEpoch);
     90 
     91  // Those two methods are for testing called on the compositor thread.
     92  OMTAValue GetOMTAValue(const uint64_t& aId) const;
     93  /**
     94   * There are two possibilities when this function gets called, either 1) in
     95   * testing refesh driver mode or 2) in normal refresh driver mode. In the case
     96   * of 2) |aTestingSampleTime| should be Nothing() so that we can use
     97   * |mPreviousSampleTime| and |mSampleTime| for sampling animations.
     98   */
     99  void SampleForTesting(const Maybe<TimeStamp>& aTestingSampleTime);
    100 
    101  /**
    102   * Returns true if currently on the "sampler thread".
    103   */
    104  bool IsSamplerThread() const;
    105 
    106  void EnterTestMode() { mIsInTestMode = true; }
    107  void LeaveTestMode() { mIsInTestMode = false; }
    108 
    109 protected:
    110  ~OMTASampler() = default;
    111 
    112  static already_AddRefed<OMTASampler> GetSampler(
    113      const wr::WrWindowId& aWindowId);
    114 
    115 private:
    116  WrAnimations SampleAnimations(const TimeStamp& aPreviousSampleTime,
    117                                const TimeStamp& aSampleTime);
    118 
    119  RefPtr<OMTAController> mController;
    120  // Can only be accessed or modified while holding mStorageLock.
    121  RefPtr<CompositorAnimationStorage> mAnimStorage;
    122  mutable Mutex mStorageLock MOZ_UNANNOTATED;
    123 
    124  // Used to manage the mapping from a WR window id to OMTASampler. These are
    125  // only used if WebRender is enabled. Both sWindowIdMap and mWindowId should
    126  // only be used while holding the sWindowIdLock. Note that we use a
    127  // StaticAutoPtr wrapper on sWindowIdMap to avoid a static initializer for the
    128  // unordered_map. This also avoids the initializer/memory allocation in cases
    129  // where we're not using WebRender.
    130  static StaticMutex sWindowIdLock MOZ_UNANNOTATED;
    131  static StaticAutoPtr<std::unordered_map<uint64_t, RefPtr<OMTASampler>>>
    132      sWindowIdMap;
    133  Maybe<wr::WrWindowId> mWindowId;
    134 
    135  // Lock used to protected mSamplerThreadId
    136  mutable Mutex mThreadIdLock MOZ_UNANNOTATED;
    137  // If WebRender is enabled, this holds the thread id of the render backend
    138  // thread (which is the sampler thread) for the compositor associated with
    139  // this OMTASampler instance.
    140  Maybe<PlatformThreadId> mSamplerThreadId;
    141 
    142  Mutex mSampleTimeLock MOZ_UNANNOTATED;
    143  // Can only be accessed or modified while holding mSampleTimeLock.
    144  TimeStamp mSampleTime;
    145  // Same as |mSampleTime|, can only be accessed or modified while holding
    146  // mSampleTimeLock.
    147  // We basically use this time stamp instead of |mSampleTime| to make
    148  // animations more in sync with other animations on the main thread.
    149  TimeStamp mPreviousSampleTime;
    150  Atomic<bool> mIsInTestMode;
    151 };
    152 
    153 }  // namespace layers
    154 }  // namespace mozilla
    155 
    156 #endif  // mozilla_layers_OMTASampler_h