gecko-dev/dom/animation/EffectCompositor.h

95 строки
3.3 KiB
C
Исходник Обычный вид История

Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_EffectCompositor_h
#define mozilla_EffectCompositor_h
#include "mozilla/Maybe.h"
#include "mozilla/Pair.h"
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
#include "mozilla/RefPtr.h"
#include "nsCSSPseudoElements.h"
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
#include "nsTArray.h"
class nsCSSPropertySet;
class nsPresContext;
class nsStyleContext;
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
namespace mozilla {
class EffectSet;
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
namespace dom {
class Animation;
class Element;
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
}
class EffectCompositor
{
public:
static bool HasAnimationsForCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty);
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
static nsTArray<RefPtr<dom::Animation>>
GetAnimationsForCompositor(const nsIFrame* aFrame,
nsCSSProperty aProperty);
// Update animation cascade results for the specified (pseudo-)element
// but only if we have marked the cascade as needing an update due a
// the change in the set of effects or a change in one of the effects'
// "in effect" state.
//
// This method does NOT detect if other styles that apply above the
// animation level of the cascade have changed.
static void
MaybeUpdateCascadeResults(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsStyleContext* aStyleContext);
// Update the mWinsInCascade member for each property in effects targetting
// the specified (pseudo-)element.
//
// This can be expensive so we should only call it if styles that apply
// above the animation level of the cascade might have changed. For all
// other cases we should call MaybeUpdateCascadeResults.
static void
UpdateCascadeResults(dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsStyleContext* aStyleContext);
// Helper to fetch the corresponding element and pseudo-type from a frame.
//
// For frames corresponding to pseudo-elements, the returned element is the
// element on which we store the animations (i.e. the EffectSet and/or
// AnimationCollection), *not* the generated content.
//
// Returns an empty result when a suitable element cannot be found including
// when the frame represents a pseudo-element on which we do not support
// animations.
static Maybe<Pair<dom::Element*, nsCSSPseudoElements::Type>>
GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame);
private:
// Get the properties that we are able to animate on the compositor that
// are specified at a higher level in the cascade than the animations
// level in |aStyleContext|.
static void
GetOverriddenProperties(nsStyleContext* aStyleContext,
nsCSSPropertySet& aPropertiesOverridden);
static void
UpdateCascadeResults(EffectSet& aEffectSet,
dom::Element* aElement,
nsCSSPseudoElements::Type aPseudoType,
nsStyleContext* aStyleContext);
static nsPresContext* GetPresContext(dom::Element* aElement);
Bug 1226118 part 8 - Add EffectCompositor::GetAnimationsForCompositor that uses the EffectSet rather than AnimationCollection; r=dholbert This added method should behave in an equivalent manner to the existing CommonAnimationManager::GetAnimationsForCompositor except for the following differences: * It uses the EffectSet attached to a target element rather than one of the AnimationCollection object on the owning element. * It returns an array of Animation objects consisting of only those Animations that actually have the specified property as opposed to the AnimationCollection consisting of *all* CSS animations or *all* CSS transitions for the element regardless of whether they run on the compositor or not. It may not be obvious why these two methods otherwise behave in an equivalent fashion so the following explains how the existing code is mirrored in the new method. The existing code is as follows: > AnimationCollection* > CommonAnimationManager::GetAnimationsForCompositor(const nsIFrame* aFrame, > nsCSSProperty aProperty) > { > AnimationCollection* collection = GetAnimationCollection(aFrame); > if (!collection || > !collection->HasCurrentAnimationOfProperty(aProperty) || > !collection->CanPerformOnCompositorThread(aFrame)) { > return nullptr; > } > > // This animation can be done on the compositor. > return collection; > } The new EffectCompositor::GetAnimationsForCompositor begins with two checks performed at the beginning of CanPerformOnCompositorThread: the checks for whether async animations are enabled or not and whether the frame has refused async animations since these are cheap and it makes sense to check them first. The next part of EffectCompositor::GetAnimationsForCompositor checks if there is an EffectSet associated with the frame. This is equivalent to the check whether |collection| is null or not above. Following, we iterate through the effects in the EffectSet. We first check if each effect is playing or not. In the above code, HasCurrentAnimationOfProperty only checks if the effect is *current* or not. However, CanPerformOnCompositorThread will only return true if it finds an animation that can run on the compositor that is *playing*. Since playing is a strict subset of current we only need to perform the more restrictive test. Next we check if the effect should block running other animations on the compositor. This is equivalent to the remainder of CanPerformOnCompositorThread. Note that the order is important here. Only playing animations should block other animations from running on the compositor. Furthermore, this needs to happen before the following step since animations of property other than |aProperty| can still block animations from running on the compositor. Finally, we check if the effect has an animation of |aProperty|. This is equivalent to the remainder of HasCurrentAnimationOfProperty. If all these checks succeed, we add the effect's animation to the result to return.
2015-12-04 02:34:12 +03:00
};
} // namespace mozilla
#endif // mozilla_EffectCompositor_h