зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1415780 - Let nsPresContext have AnimationEventDispatcher. r=birtles
Now we sort CSS animation/transition events by scheduled event time prior to compositor order. SortEvents() will be a private method in the next patch in this patch series. MozReview-Commit-ID: ICkOayquN0f --HG-- extra : rebase_source : 52226c33a511451c31d4c3fef94ff02de8462256
This commit is contained in:
Родитель
f61cc0132a
Коммит
99f98b1bd6
|
@ -97,21 +97,28 @@ struct AnimationEventInfo
|
|||
class AnimationEventDispatcher final
|
||||
{
|
||||
public:
|
||||
AnimationEventDispatcher() : mIsSorted(true) { }
|
||||
explicit AnimationEventDispatcher(nsPresContext* aPresContext)
|
||||
: mPresContext(aPresContext)
|
||||
, mIsSorted(true)
|
||||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(AnimationEventDispatcher)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(AnimationEventDispatcher)
|
||||
|
||||
void Disconnect() {
|
||||
mPresContext = nullptr;
|
||||
}
|
||||
|
||||
void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
|
||||
{
|
||||
mPendingEvents.AppendElements(Move(aEvents));
|
||||
mIsSorted = false;
|
||||
}
|
||||
|
||||
// This is exposed as a separate method so that when we are dispatching
|
||||
// *both* transition events and animation events we can sort both lists
|
||||
// once using the current state of the document before beginning any
|
||||
// dispatch.
|
||||
// Sort all pending CSS animation/transition events by scheduled event time
|
||||
// and composite order.
|
||||
// https://drafts.csswg.org/web-animations/#update-animations-and-send-events
|
||||
void SortEvents()
|
||||
{
|
||||
if (mIsSorted) {
|
||||
|
@ -125,15 +132,11 @@ public:
|
|||
mIsSorted = true;
|
||||
}
|
||||
|
||||
// Takes a reference to the owning manager's pres context so it can
|
||||
// detect if the pres context is destroyed while dispatching one of
|
||||
// the events.
|
||||
//
|
||||
// This will call SortEvents automatically if it has not already been
|
||||
// called.
|
||||
void DispatchEvents(nsPresContext* const & aPresContext)
|
||||
void DispatchEvents()
|
||||
{
|
||||
if (!aPresContext || mPendingEvents.IsEmpty()) {
|
||||
if (!mPresContext || mPendingEvents.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,10 +151,12 @@ public:
|
|||
!info.AsWidgetEvent()->mFlags.mDispatchedAtLeastOnce,
|
||||
"The WidgetEvent should be fresh");
|
||||
EventDispatcher::Dispatch(info.mElement,
|
||||
aPresContext,
|
||||
mPresContext,
|
||||
info.AsWidgetEvent());
|
||||
|
||||
if (!aPresContext) {
|
||||
// Bail out if our mPresContext was nullified due to destroying the pres
|
||||
// context.
|
||||
if (!mPresContext) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +191,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
nsPresContext* mPresContext;
|
||||
typedef nsTArray<AnimationEventInfo> EventArray;
|
||||
EventArray mPendingEvents;
|
||||
bool mIsSorted;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/PresShell.h"
|
||||
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/StyleSheetInlines.h"
|
||||
|
@ -1362,8 +1363,7 @@ PresShell::Destroy()
|
|||
}
|
||||
|
||||
if (mPresContext) {
|
||||
mPresContext->AnimationManager()->ClearEventQueue();
|
||||
mPresContext->TransitionManager()->ClearEventQueue();
|
||||
mPresContext->AnimationEventDispatcher()->ClearEventQueue();
|
||||
}
|
||||
|
||||
// Revoke any pending events. We need to do this and cancel pending reflows
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "gfxPlatform.h"
|
||||
#include "nsCSSRules.h"
|
||||
#include "nsFontFaceLoader.h"
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "prenv.h"
|
||||
|
@ -442,8 +443,7 @@ nsPresContext::LastRelease()
|
|||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPresContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPresContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationManager);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransitionManager);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnimationEventDispatcher);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument);
|
||||
// NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDeviceContext); // not xpcom
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEffectCompositor);
|
||||
|
@ -457,8 +457,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPresContext)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPresContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationManager);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransitionManager);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnimationEventDispatcher);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDeviceContext); // worth bothering?
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEffectCompositor);
|
||||
|
@ -888,6 +887,7 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
|
|||
|
||||
mEventManager = new mozilla::EventStateManager();
|
||||
|
||||
mAnimationEventDispatcher = new mozilla::AnimationEventDispatcher(this);
|
||||
mEffectCompositor = new mozilla::EffectCompositor(this);
|
||||
mTransitionManager = new nsTransitionManager(this);
|
||||
mAnimationManager = new nsAnimationManager(this);
|
||||
|
@ -1066,6 +1066,10 @@ nsPresContext::DetachShell()
|
|||
|
||||
mShell = nullptr;
|
||||
|
||||
if (mAnimationEventDispatcher) {
|
||||
mAnimationEventDispatcher->Disconnect();
|
||||
mAnimationEventDispatcher = nullptr;
|
||||
}
|
||||
if (mEffectCompositor) {
|
||||
mEffectCompositor->Disconnect();
|
||||
mEffectCompositor = nullptr;
|
||||
|
|
|
@ -73,6 +73,7 @@ class nsDeviceContext;
|
|||
class gfxMissingFontRecorder;
|
||||
|
||||
namespace mozilla {
|
||||
class AnimationEventDispatcher;
|
||||
class EffectCompositor;
|
||||
class Encoding;
|
||||
class EventStateManager;
|
||||
|
@ -236,6 +237,10 @@ public:
|
|||
nsCSSFrameConstructor* FrameConstructor()
|
||||
{ return PresShell()->FrameConstructor(); }
|
||||
|
||||
mozilla::AnimationEventDispatcher* AnimationEventDispatcher()
|
||||
{
|
||||
return mAnimationEventDispatcher;
|
||||
}
|
||||
mozilla::EffectCompositor* EffectCompositor() { return mEffectCompositor; }
|
||||
nsTransitionManager* TransitionManager() { return mTransitionManager; }
|
||||
nsAnimationManager* AnimationManager() { return mAnimationManager; }
|
||||
|
@ -1296,6 +1301,7 @@ protected:
|
|||
// from gfx back to layout.
|
||||
RefPtr<mozilla::EventStateManager> mEventManager;
|
||||
RefPtr<nsRefreshDriver> mRefreshDriver;
|
||||
RefPtr<mozilla::AnimationEventDispatcher> mAnimationEventDispatcher;
|
||||
RefPtr<mozilla::EffectCompositor> mEffectCompositor;
|
||||
RefPtr<nsTransitionManager> mTransitionManager;
|
||||
RefPtr<nsAnimationManager> mAnimationManager;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "WinUtils.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/IntegerRange.h"
|
||||
|
@ -1652,16 +1653,7 @@ nsRefreshDriver::DispatchAnimationEvents()
|
|||
continue;
|
||||
}
|
||||
|
||||
context->TransitionManager()->SortEvents();
|
||||
context->AnimationManager()->SortEvents();
|
||||
|
||||
// Dispatch transition events first since transitions conceptually sit
|
||||
// below animations in terms of compositing order.
|
||||
context->TransitionManager()->DispatchEvents();
|
||||
// Check that the presshell has not been destroyed
|
||||
if (context->GetPresShell()) {
|
||||
context->AnimationManager()->DispatchEvents();
|
||||
}
|
||||
context->AnimationEventDispatcher()->DispatchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_css_AnimationCommon_h
|
||||
|
||||
#include "mozilla/AnimationCollection.h"
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/dom/Animation.h"
|
||||
#include "mozilla/Attributes.h" // For MOZ_NON_OWNING_REF
|
||||
|
@ -21,7 +20,6 @@ class nsPresContext;
|
|||
|
||||
namespace mozilla {
|
||||
enum class CSSPseudoElementType : uint8_t;
|
||||
class AnimationEventDispatcher;
|
||||
|
||||
namespace dom {
|
||||
class Element;
|
||||
|
@ -33,7 +31,6 @@ public:
|
|||
explicit CommonAnimationManager(nsPresContext *aPresContext)
|
||||
: mPresContext(aPresContext)
|
||||
{
|
||||
mEventDispatcher = new AnimationEventDispatcher();
|
||||
}
|
||||
|
||||
// NOTE: This can return null after Disconnect().
|
||||
|
@ -70,17 +67,6 @@ public:
|
|||
collection->Destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add pending events.
|
||||
*/
|
||||
void QueueEvents(nsTArray<AnimationEventInfo>&& aEvents)
|
||||
{
|
||||
mEventDispatcher->QueueEvents(Move(aEvents));
|
||||
}
|
||||
|
||||
void SortEvents() { mEventDispatcher->SortEvents(); }
|
||||
void ClearEventQueue() { mEventDispatcher->ClearEventQueue(); }
|
||||
|
||||
protected:
|
||||
virtual ~CommonAnimationManager()
|
||||
{
|
||||
|
@ -101,8 +87,6 @@ protected:
|
|||
|
||||
LinkedList<AnimationCollection<AnimationType>> mElementCollections;
|
||||
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
|
||||
|
||||
RefPtr<mozilla::AnimationEventDispatcher> mEventDispatcher;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsTransitionManager.h"
|
||||
#include "mozilla/dom/CSSAnimationBinding.h"
|
||||
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/AnimationTarget.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
|
@ -299,7 +300,7 @@ CSSAnimation::QueueEvents(const StickyTimeDuration& aActiveTime)
|
|||
mPreviousIteration = currentIteration;
|
||||
|
||||
if (!events.IsEmpty()) {
|
||||
presContext->AnimationManager()->QueueEvents(Move(events));
|
||||
presContext->AnimationEventDispatcher()->QueueEvents(Move(events));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -317,11 +318,6 @@ CSSAnimation::UpdateTiming(SeekFlag aSeekFlag, SyncNotifyFlag aSyncNotifyFlag)
|
|||
|
||||
////////////////////////// nsAnimationManager ////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(nsAnimationManager, mEventDispatcher)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsAnimationManager, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsAnimationManager, Release)
|
||||
|
||||
// Find the matching animation by |aName| in the old list
|
||||
// of animations and remove the matched animation from the list.
|
||||
static already_AddRefed<CSSAnimation>
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/Keyframe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsStyleContext;
|
||||
|
@ -282,8 +283,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsAnimationManager)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsAnimationManager)
|
||||
NS_INLINE_DECL_REFCOUNTING(nsAnimationManager)
|
||||
|
||||
typedef mozilla::AnimationCollection<mozilla::dom::CSSAnimation>
|
||||
CSSAnimationCollection;
|
||||
|
@ -310,12 +310,6 @@ public:
|
|||
mozilla::CSSPseudoElementType aPseudoType,
|
||||
const mozilla::ServoStyleContext* aComputedValues);
|
||||
|
||||
void DispatchEvents()
|
||||
{
|
||||
RefPtr<nsAnimationManager> kungFuDeathGrip(this);
|
||||
mEventDispatcher->DispatchEvents(mPresContext);
|
||||
}
|
||||
|
||||
// Utility function to walk through |aIter| to find the Keyframe with
|
||||
// matching offset and timing function but stopping as soon as the offset
|
||||
// differs from |aOffset| (i.e. it assumes a sorted iterator).
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "nsRuleProcessorData.h"
|
||||
#include "nsRuleWalker.h"
|
||||
#include "nsCSSPropertyIDSet.h"
|
||||
#include "mozilla/AnimationEventDispatcher.h"
|
||||
#include "mozilla/EffectCompositor.h"
|
||||
#include "mozilla/EffectSet.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
|
@ -336,7 +337,7 @@ CSSTransition::QueueEvents(const StickyTimeDuration& aActiveTime)
|
|||
mPreviousTransitionPhase = currentPhase;
|
||||
|
||||
if (!events.IsEmpty()) {
|
||||
presContext->TransitionManager()->QueueEvents(Move(events));
|
||||
presContext->AnimationEventDispatcher()->QueueEvents(Move(events));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,11 +423,6 @@ CSSTransition::SetEffectFromStyle(dom::AnimationEffectReadOnly* aEffect)
|
|||
|
||||
////////////////////////// nsTransitionManager ////////////////////////////
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION(nsTransitionManager, mEventDispatcher)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsTransitionManager, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsTransitionManager, Release)
|
||||
|
||||
static inline bool
|
||||
ExtractNonDiscreteComputedValue(nsCSSPropertyID aProperty,
|
||||
GeckoStyleContext* aStyleContext,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "mozilla/dom/Animation.h"
|
||||
#include "mozilla/dom/KeyframeEffectReadOnly.h"
|
||||
#include "AnimationCommon.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
class nsIGlobalObject;
|
||||
class nsStyleContext;
|
||||
|
@ -310,8 +311,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsTransitionManager)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsTransitionManager)
|
||||
NS_INLINE_DECL_REFCOUNTING(nsTransitionManager)
|
||||
|
||||
typedef mozilla::AnimationCollection<mozilla::dom::CSSTransition>
|
||||
CSSTransitionCollection;
|
||||
|
@ -363,12 +363,6 @@ public:
|
|||
return mInAnimationOnlyStyleUpdate;
|
||||
}
|
||||
|
||||
void DispatchEvents()
|
||||
{
|
||||
RefPtr<nsTransitionManager> kungFuDeathGrip(this);
|
||||
mEventDispatcher->DispatchEvents(mPresContext);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~nsTransitionManager() {}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче