gecko/dom/animation/AnimationTimeline.h

93 lines
3.1 KiB
C
Raw Normal View History

/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* 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_dom_AnimationTimeline_h
#define mozilla_dom_AnimationTimeline_h
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "mozilla/TimeStamp.h"
#include "nsIGlobalObject.h"
#include "js/TypeDecls.h"
#include "nsIDocument.h"
#include "nsRefreshDriver.h"
struct JSContext;
namespace mozilla {
namespace dom {
class AnimationTimeline MOZ_FINAL : public nsWrapperCache
{
public:
explicit AnimationTimeline(nsIDocument* aDocument)
: mDocument(aDocument)
, mWindow(aDocument->GetParentObject())
{
MOZ_ASSERT(mWindow);
}
protected:
virtual ~AnimationTimeline() { }
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationTimeline)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(AnimationTimeline)
nsIGlobalObject* GetParentObject() const
{
return mWindow;
}
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
// AnimationTimeline methods
Nullable<TimeDuration> GetCurrentTime() const;
// Wrapper functions for AnimationTimeline DOM methods when called from
// script.
Nullable<double> GetCurrentTimeAsDouble() const;
// Converts a TimeStamp to the equivalent value in timeline time.
// Note that when IsUnderTestControl() is true, there is no correspondence
// between timeline time and wallclock time. In such a case, passing a
// timestamp from TimeStamp::Now() to this method will not return a
// meaningful result.
Nullable<TimeDuration> ToTimelineTime(const TimeStamp& aTimeStamp) const;
TimeStamp ToTimeStamp(const TimeDuration& aTimelineTime) const;
nsRefreshDriver* GetRefreshDriver() const;
// Returns true if this timeline is driven by a refresh driver that is
// under test control. In such a case, there is no correspondence between
// TimeStamp values returned by the refresh driver and wallclock time.
// As a result, passing a value from TimeStamp::Now() to ToTimelineTime()
// would not return a meaningful result.
bool IsUnderTestControl() const
{
nsRefreshDriver* refreshDriver = GetRefreshDriver();
return refreshDriver && refreshDriver->IsTestControllingRefreshesEnabled();
}
protected:
TimeStamp GetCurrentTimeStamp() const;
// Sometimes documents can be given a new window, or windows can be given a
// new document (e.g. document.open()). Since GetParentObject is required to
// _always_ return the same object it can't get the window from our
// mDocument, which is why we have pointers to both our document and window.
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIGlobalObject> mWindow;
Bug 927349 part 8 - Fast-forward the timeline before resolving start times; r=jwatt Normally animation players get times from their timeline which is based on the refresh driver for their associated document. However, for animations that we time from when their first frame has been rendered, we want to record the actual time when painting finished as their start time. If we wait until the next refresh driver tick then the delay between playing an animation and its actual start will be too great. In this patch, we introduce a mechanism for fast-forwarding a timeline to a time between the current refresh driver time and the next refresh driver tick. By adjusting the timeline rather than the player we maintain a consistent state (in fact, if we just naively set the animation player start time to the timestamp value we recorded when painting finished it will appear to start in the future and the animation will temporarily jump from playing, to waiting to start, then back to playing again on the next refresh driver tick). To be completely consistent, however, when we fast-forward the timeline we should tell all animation players listening to the timeline to mark their target element as needing a style flush. Otherwise we may be able to observe an inconsistency between some animation players' current time and the computed style of their targets. We don't, however, currently know which players are observing a given timeline. We will likely introduce that in the near future (in order to implement AnimationTimeline.getAnimationPlayers) and fix the inconsistency in timing then. A test later in the patch series verifies this inconsistency so it is easy to fix in future. An alternative approach would be to simply record the time when animation should start, send that time to the compositor but don't actually update the animation start time on the main thread until the subsequent refresh driver tick. Such an approach is complex as it introduces an additional state--"finished pending but not yet started". We will attempt to switch to that approach in bug 1112480.
2014-12-21 16:35:41 -08:00
// The most recently used refresh driver time. This is used in cases where
// we don't have a refresh driver (e.g. because we are in a display:none
// iframe).
mutable TimeStamp mLastRefreshDriverTime;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_AnimationTimeline_h