dom/smil/nsSMILAnimationController.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef NS_SMILANIMATIONCONTROLLER_H_
michael@0 7 #define NS_SMILANIMATIONCONTROLLER_H_
michael@0 8
michael@0 9 #include "mozilla/Attributes.h"
michael@0 10 #include "nsAutoPtr.h"
michael@0 11 #include "nsCOMPtr.h"
michael@0 12 #include "nsTArray.h"
michael@0 13 #include "nsITimer.h"
michael@0 14 #include "nsTHashtable.h"
michael@0 15 #include "nsHashKeys.h"
michael@0 16 #include "nsSMILTimeContainer.h"
michael@0 17 #include "nsSMILCompositorTable.h"
michael@0 18 #include "nsSMILMilestone.h"
michael@0 19 #include "nsRefreshDriver.h"
michael@0 20
michael@0 21 struct nsSMILTargetIdentifier;
michael@0 22 class nsIDocument;
michael@0 23
michael@0 24 namespace mozilla {
michael@0 25 namespace dom {
michael@0 26 class SVGAnimationElement;
michael@0 27 }
michael@0 28 }
michael@0 29
michael@0 30 //----------------------------------------------------------------------
michael@0 31 // nsSMILAnimationController
michael@0 32 //
michael@0 33 // The animation controller maintains the animation timer and determines the
michael@0 34 // sample times and sample rate for all SMIL animations in a document. There is
michael@0 35 // at most one animation controller per nsDocument so that frame-rate tuning can
michael@0 36 // be performed at a document-level.
michael@0 37 //
michael@0 38 // The animation controller can contain many child time containers (timed
michael@0 39 // document root objects) which may correspond to SVG document fragments within
michael@0 40 // a compound document. These time containers can be paused individually or
michael@0 41 // here, at the document level.
michael@0 42 //
michael@0 43 class nsSMILAnimationController : public nsSMILTimeContainer,
michael@0 44 public nsARefreshObserver
michael@0 45 {
michael@0 46 public:
michael@0 47 nsSMILAnimationController(nsIDocument* aDoc);
michael@0 48 ~nsSMILAnimationController();
michael@0 49
michael@0 50 // Clears mDocument pointer. (Called by our nsIDocument when it's going away)
michael@0 51 void Disconnect();
michael@0 52
michael@0 53 // nsSMILContainer
michael@0 54 virtual void Pause(uint32_t aType) MOZ_OVERRIDE;
michael@0 55 virtual void Resume(uint32_t aType) MOZ_OVERRIDE;
michael@0 56 virtual nsSMILTime GetParentTime() const MOZ_OVERRIDE;
michael@0 57
michael@0 58 // nsARefreshObserver
michael@0 59 NS_IMETHOD_(MozExternalRefCountType) AddRef() MOZ_OVERRIDE;
michael@0 60 NS_IMETHOD_(MozExternalRefCountType) Release() MOZ_OVERRIDE;
michael@0 61
michael@0 62 virtual void WillRefresh(mozilla::TimeStamp aTime) MOZ_OVERRIDE;
michael@0 63
michael@0 64 // Methods for registering and enumerating animation elements
michael@0 65 void RegisterAnimationElement(mozilla::dom::SVGAnimationElement* aAnimationElement);
michael@0 66 void UnregisterAnimationElement(mozilla::dom::SVGAnimationElement* aAnimationElement);
michael@0 67
michael@0 68 // Methods for resampling all animations
michael@0 69 // (A resample performs the same operations as a sample but doesn't advance
michael@0 70 // the current time and doesn't check if the container is paused)
michael@0 71 // This will flush pending style changes for the document.
michael@0 72 void Resample() { DoSample(false); }
michael@0 73
michael@0 74 void SetResampleNeeded()
michael@0 75 {
michael@0 76 if (!mRunningSample) {
michael@0 77 if (!mResampleNeeded) {
michael@0 78 FlagDocumentNeedsFlush();
michael@0 79 }
michael@0 80 mResampleNeeded = true;
michael@0 81 }
michael@0 82 }
michael@0 83
michael@0 84 // This will flush pending style changes for the document.
michael@0 85 void FlushResampleRequests()
michael@0 86 {
michael@0 87 if (!mResampleNeeded)
michael@0 88 return;
michael@0 89
michael@0 90 Resample();
michael@0 91 }
michael@0 92
michael@0 93 // Methods for handling page transitions
michael@0 94 void OnPageShow();
michael@0 95 void OnPageHide();
michael@0 96
michael@0 97 // Methods for supporting cycle-collection
michael@0 98 void Traverse(nsCycleCollectionTraversalCallback* aCallback);
michael@0 99 void Unlink();
michael@0 100
michael@0 101 // Methods for relaying the availability of the refresh driver
michael@0 102 void NotifyRefreshDriverCreated(nsRefreshDriver* aRefreshDriver);
michael@0 103 void NotifyRefreshDriverDestroying(nsRefreshDriver* aRefreshDriver);
michael@0 104
michael@0 105 // Helper to check if we have any animation elements at all
michael@0 106 bool HasRegisteredAnimations()
michael@0 107 { return mAnimationElementTable.Count() != 0; }
michael@0 108
michael@0 109 protected:
michael@0 110 // Typedefs
michael@0 111 typedef nsPtrHashKey<nsSMILTimeContainer> TimeContainerPtrKey;
michael@0 112 typedef nsTHashtable<TimeContainerPtrKey> TimeContainerHashtable;
michael@0 113 typedef nsPtrHashKey<mozilla::dom::SVGAnimationElement> AnimationElementPtrKey;
michael@0 114 typedef nsTHashtable<AnimationElementPtrKey> AnimationElementHashtable;
michael@0 115
michael@0 116 struct SampleTimeContainerParams
michael@0 117 {
michael@0 118 TimeContainerHashtable* mActiveContainers;
michael@0 119 bool mSkipUnchangedContainers;
michael@0 120 };
michael@0 121
michael@0 122 struct SampleAnimationParams
michael@0 123 {
michael@0 124 TimeContainerHashtable* mActiveContainers;
michael@0 125 nsSMILCompositorTable* mCompositorTable;
michael@0 126 };
michael@0 127
michael@0 128 struct GetMilestoneElementsParams
michael@0 129 {
michael@0 130 nsTArray<nsRefPtr<mozilla::dom::SVGAnimationElement> > mElements;
michael@0 131 nsSMILMilestone mMilestone;
michael@0 132 };
michael@0 133
michael@0 134 // Cycle-collection implementation helpers
michael@0 135 static PLDHashOperator CompositorTableEntryTraverse(
michael@0 136 nsSMILCompositor* aCompositor, void* aArg);
michael@0 137
michael@0 138 // Returns mDocument's refresh driver, if it's got one.
michael@0 139 nsRefreshDriver* GetRefreshDriver();
michael@0 140
michael@0 141 // Methods for controlling whether we're sampling
michael@0 142 void StartSampling(nsRefreshDriver* aRefreshDriver);
michael@0 143 void StopSampling(nsRefreshDriver* aRefreshDriver);
michael@0 144
michael@0 145 // Wrapper for StartSampling that defers if no animations are registered.
michael@0 146 void MaybeStartSampling(nsRefreshDriver* aRefreshDriver);
michael@0 147
michael@0 148 // Sample-related callbacks and implementation helpers
michael@0 149 virtual void DoSample() MOZ_OVERRIDE;
michael@0 150 void DoSample(bool aSkipUnchangedContainers);
michael@0 151
michael@0 152 void RewindElements();
michael@0 153 static PLDHashOperator RewindNeeded(
michael@0 154 TimeContainerPtrKey* aKey, void* aData);
michael@0 155 static PLDHashOperator RewindAnimation(
michael@0 156 AnimationElementPtrKey* aKey, void* aData);
michael@0 157 static PLDHashOperator ClearRewindNeeded(
michael@0 158 TimeContainerPtrKey* aKey, void* aData);
michael@0 159
michael@0 160 void DoMilestoneSamples();
michael@0 161 static PLDHashOperator GetNextMilestone(
michael@0 162 TimeContainerPtrKey* aKey, void* aData);
michael@0 163 static PLDHashOperator GetMilestoneElements(
michael@0 164 TimeContainerPtrKey* aKey, void* aData);
michael@0 165
michael@0 166 static PLDHashOperator SampleTimeContainer(
michael@0 167 TimeContainerPtrKey* aKey, void* aData);
michael@0 168 static PLDHashOperator SampleAnimation(
michael@0 169 AnimationElementPtrKey* aKey, void* aData);
michael@0 170 static void SampleTimedElement(mozilla::dom::SVGAnimationElement* aElement,
michael@0 171 TimeContainerHashtable* aActiveContainers);
michael@0 172 static void AddAnimationToCompositorTable(
michael@0 173 mozilla::dom::SVGAnimationElement* aElement, nsSMILCompositorTable* aCompositorTable);
michael@0 174 static bool GetTargetIdentifierForAnimation(
michael@0 175 mozilla::dom::SVGAnimationElement* aAnimElem, nsSMILTargetIdentifier& aResult);
michael@0 176
michael@0 177 // Methods for adding/removing time containers
michael@0 178 virtual nsresult AddChild(nsSMILTimeContainer& aChild) MOZ_OVERRIDE;
michael@0 179 virtual void RemoveChild(nsSMILTimeContainer& aChild) MOZ_OVERRIDE;
michael@0 180
michael@0 181 void FlagDocumentNeedsFlush();
michael@0 182
michael@0 183 // Members
michael@0 184 nsAutoRefCnt mRefCnt;
michael@0 185 NS_DECL_OWNINGTHREAD
michael@0 186
michael@0 187 AnimationElementHashtable mAnimationElementTable;
michael@0 188 TimeContainerHashtable mChildContainerTable;
michael@0 189 mozilla::TimeStamp mCurrentSampleTime;
michael@0 190 mozilla::TimeStamp mStartTime;
michael@0 191
michael@0 192 // Average time between samples from the refresh driver. This is used to
michael@0 193 // detect large unexpected gaps between samples such as can occur when the
michael@0 194 // computer sleeps. The nature of the SMIL model means that catching up these
michael@0 195 // large gaps can be expensive as, for example, many events may need to be
michael@0 196 // dispatched for the intervening time when no samples were received.
michael@0 197 //
michael@0 198 // In such cases, we ignore the intervening gap and continue sampling from
michael@0 199 // when we were expecting the next sample to arrive.
michael@0 200 //
michael@0 201 // Note that we only do this for SMIL and not CSS transitions (which doesn't
michael@0 202 // have so much work to do to catch up) nor scripted animations (which expect
michael@0 203 // animation time to follow real time).
michael@0 204 //
michael@0 205 // This behaviour does not affect pausing (since we're not *expecting* any
michael@0 206 // samples then) nor seeking (where the SMIL model behaves somewhat
michael@0 207 // differently such as not dispatching events).
michael@0 208 nsSMILTime mAvgTimeBetweenSamples;
michael@0 209
michael@0 210 bool mResampleNeeded;
michael@0 211 // If we're told to start sampling but there are no animation elements we just
michael@0 212 // record the time, set the following flag, and then wait until we have an
michael@0 213 // animation element. Then we'll reset this flag and actually start sampling.
michael@0 214 bool mDeferredStartSampling;
michael@0 215 bool mRunningSample;
michael@0 216
michael@0 217 // Are we registered with our document's refresh driver?
michael@0 218 bool mRegisteredWithRefreshDriver;
michael@0 219
michael@0 220 // Store raw ptr to mDocument. It owns the controller, so controller
michael@0 221 // shouldn't outlive it
michael@0 222 nsIDocument* mDocument;
michael@0 223
michael@0 224 // Contains compositors used in our last sample. We keep this around
michael@0 225 // so we can detect when an element/attribute used to be animated,
michael@0 226 // but isn't anymore for some reason. (e.g. if its <animate> element is
michael@0 227 // removed or retargeted)
michael@0 228 nsAutoPtr<nsSMILCompositorTable> mLastCompositorTable;
michael@0 229 };
michael@0 230
michael@0 231 #endif // NS_SMILANIMATIONCONTROLLER_H_

mercurial