tor-browser

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

SMILAnimationController.h (6715B)


      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 DOM_SMIL_SMILANIMATIONCONTROLLER_H_
      8 #define DOM_SMIL_SMILANIMATIONCONTROLLER_H_
      9 
     10 #include "mozilla/SMILCompositorTable.h"
     11 #include "mozilla/SMILMilestone.h"
     12 #include "mozilla/SMILTimeContainer.h"
     13 #include "mozilla/UniquePtr.h"
     14 #include "nsCOMPtr.h"
     15 #include "nsHashKeys.h"
     16 #include "nsTArray.h"
     17 #include "nsTHashtable.h"
     18 
     19 class nsRefreshDriver;
     20 
     21 namespace mozilla {
     22 struct SMILTargetIdentifier;
     23 namespace dom {
     24 class Element;
     25 class SVGAnimationElement;
     26 }  // namespace dom
     27 
     28 //----------------------------------------------------------------------
     29 // SMILAnimationController
     30 //
     31 // The animation controller maintains the animation timer and determines the
     32 // sample times and sample rate for all SMIL animations in a document. There is
     33 // at most one animation controller per document so that frame-rate tuning can
     34 // be performed at a document-level.
     35 //
     36 // The animation controller can contain many child time containers (timed
     37 // document root objects) which may correspond to SVG document fragments within
     38 // a compound document. These time containers can be paused individually or
     39 // here, at the document level.
     40 //
     41 class SMILAnimationController final : public SMILTimeContainer {
     42 public:
     43  explicit SMILAnimationController(mozilla::dom::Document* aDoc);
     44 
     45  NS_INLINE_DECL_REFCOUNTING(SMILAnimationController)
     46 
     47  // Clears mDocument pointer. (Called by our mozilla::dom::Document when it's
     48  // going away)
     49  void Disconnect();
     50 
     51  // SMILContainer
     52  void Pause(uint32_t aType) override;
     53  void Resume(uint32_t aType) override;
     54  SMILTime GetParentTime() const override;
     55 
     56  // Returns mDocument's refresh driver, if it's got one.
     57  nsRefreshDriver* GetRefreshDriver();
     58  void WillRefresh(mozilla::TimeStamp aTime);
     59 
     60  // Methods for registering and enumerating animation elements
     61  void RegisterAnimationElement(
     62      mozilla::dom::SVGAnimationElement* aAnimationElement);
     63  void UnregisterAnimationElement(
     64      mozilla::dom::SVGAnimationElement* aAnimationElement);
     65 
     66  // Methods for resampling all animations
     67  // (A resample performs the same operations as a sample but doesn't advance
     68  // the current time and doesn't check if the container is paused)
     69  // This will flush pending style changes for the document.
     70  void Resample() { DoSample(false); }
     71 
     72  void SetResampleNeeded() {
     73    if (!mRunningSample && !mResampleNeeded) {
     74      FlagDocumentNeedsFlush();
     75      mResampleNeeded = true;
     76    }
     77  }
     78 
     79  // This will flush pending style changes for the document.
     80  void FlushResampleRequests() {
     81    if (!mResampleNeeded) return;
     82 
     83    Resample();
     84  }
     85 
     86  // Methods for handling page transitions
     87  void OnPageShow();
     88  void OnPageHide();
     89 
     90  // Methods for supporting cycle-collection
     91  void Traverse(nsCycleCollectionTraversalCallback* aCallback);
     92  void Unlink();
     93 
     94  // Helper to check if we have any animation elements at all
     95  bool HasRegisteredAnimations() const {
     96    return mAnimationElementTable.Count() != 0;
     97  }
     98 
     99  bool MightHavePendingStyleUpdates() const {
    100    return mMightHavePendingStyleUpdates;
    101  }
    102 
    103  void PreTraverse();
    104  void PreTraverseInSubtree(mozilla::dom::Element* aRoot);
    105 
    106 protected:
    107  ~SMILAnimationController();
    108 
    109  // alias declarations
    110  using TimeContainerPtrKey = nsPtrHashKey<SMILTimeContainer>;
    111  using TimeContainerHashtable = nsTHashtable<TimeContainerPtrKey>;
    112  using AnimationElementPtrKey = nsPtrHashKey<dom::SVGAnimationElement>;
    113  using AnimationElementHashtable = nsTHashtable<AnimationElementPtrKey>;
    114 
    115  // Methods for controlling whether we're sampling
    116  void UpdateSampling();
    117  bool ShouldSample() const;
    118 
    119  // Sample-related callbacks and implementation helpers
    120  void DoSample() override;
    121  void DoSample(bool aSkipUnchangedContainers);
    122 
    123  void RewindElements();
    124 
    125  void DoMilestoneSamples();
    126 
    127  static void SampleTimedElement(mozilla::dom::SVGAnimationElement* aElement,
    128                                 TimeContainerHashtable* aActiveContainers);
    129 
    130  static void AddAnimationToCompositorTable(
    131      mozilla::dom::SVGAnimationElement* aElement,
    132      SMILCompositorTable* aCompositorTable);
    133 
    134  static bool GetTargetIdentifierForAnimation(
    135      mozilla::dom::SVGAnimationElement* aAnimElem,
    136      SMILTargetIdentifier& aResult);
    137 
    138  // Methods for adding/removing time containers
    139  nsresult AddChild(SMILTimeContainer& aChild) override;
    140  void RemoveChild(SMILTimeContainer& aChild) override;
    141 
    142  void FlagDocumentNeedsFlush();
    143 
    144  // Members
    145 
    146  AnimationElementHashtable mAnimationElementTable;
    147  TimeContainerHashtable mChildContainerTable;
    148  mozilla::TimeStamp mCurrentSampleTime;
    149  mozilla::TimeStamp mStartTime;
    150 
    151  // Average time between samples from the refresh driver. This is used to
    152  // detect large unexpected gaps between samples such as can occur when the
    153  // computer sleeps. The nature of the SMIL model means that catching up these
    154  // large gaps can be expensive as, for example, many events may need to be
    155  // dispatched for the intervening time when no samples were received.
    156  //
    157  // In such cases, we ignore the intervening gap and continue sampling from
    158  // when we were expecting the next sample to arrive.
    159  //
    160  // Note that we only do this for SMIL and not CSS transitions (which doesn't
    161  // have so much work to do to catch up) nor scripted animations (which expect
    162  // animation time to follow real time).
    163  //
    164  // This behaviour does not affect pausing (since we're not *expecting* any
    165  // samples then) nor seeking (where the SMIL model behaves somewhat
    166  // differently such as not dispatching events).
    167  SMILTime mAvgTimeBetweenSamples = 0;
    168 
    169  bool mResampleNeeded = false;
    170  bool mRunningSample = false;
    171 
    172  // Have we updated animated values without adding them to the restyle tracker?
    173  bool mMightHavePendingStyleUpdates = false;
    174 
    175  // Whether we've started sampling. This is only needed because the first
    176  // sample is supposed to run sync.
    177  bool mIsSampling = false;
    178 
    179  // Store raw ptr to mDocument.  It owns the controller, so controller
    180  // shouldn't outlive it
    181  mozilla::dom::Document* mDocument;
    182 
    183  // Contains compositors used in our last sample.  We keep this around
    184  // so we can detect when an element/attribute used to be animated,
    185  // but isn't anymore for some reason. (e.g. if its <animate> element is
    186  // removed or retargeted)
    187  UniquePtr<SMILCompositorTable> mLastCompositorTable;
    188 };
    189 
    190 }  // namespace mozilla
    191 
    192 #endif  // DOM_SMIL_SMILANIMATIONCONTROLLER_H_