зеркало из https://github.com/mozilla/gecko-dev.git
Bug 914847. Mini-flush for animations. r=dbaron
This commit is contained in:
Родитель
671bba2fbd
Коммит
9aa2bb4046
|
@ -1055,7 +1055,8 @@ nsPresContext::Init(nsDeviceContext* aDeviceContext)
|
||||||
|
|
||||||
// Initialise refresh tick counters for OMTA
|
// Initialise refresh tick counters for OMTA
|
||||||
mLastStyleUpdateForAllAnimations =
|
mLastStyleUpdateForAllAnimations =
|
||||||
mLastUpdateThrottledStyle = mRefreshDriver->MostRecentRefresh();
|
mLastUpdateThrottledAnimationStyle =
|
||||||
|
mLastUpdateThrottledTransitionStyle = mRefreshDriver->MostRecentRefresh();
|
||||||
|
|
||||||
mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
|
mLangService = do_GetService(NS_LANGUAGEATOMSERVICE_CONTRACTID);
|
||||||
|
|
||||||
|
@ -1579,15 +1580,29 @@ nsPresContext::GetDocShell() const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsPresContext::ThrottledStyleIsUpToDate() const
|
nsPresContext::ThrottledTransitionStyleIsUpToDate() const
|
||||||
{
|
{
|
||||||
return mLastUpdateThrottledStyle == mRefreshDriver->MostRecentRefresh();
|
return
|
||||||
|
mLastUpdateThrottledTransitionStyle == mRefreshDriver->MostRecentRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsPresContext::TickLastUpdateThrottledStyle()
|
nsPresContext::TickLastUpdateThrottledTransitionStyle()
|
||||||
{
|
{
|
||||||
mLastUpdateThrottledStyle = mRefreshDriver->MostRecentRefresh();
|
mLastUpdateThrottledTransitionStyle = mRefreshDriver->MostRecentRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsPresContext::ThrottledAnimationStyleIsUpToDate() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
mLastUpdateThrottledAnimationStyle == mRefreshDriver->MostRecentRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsPresContext::TickLastUpdateThrottledAnimationStyle()
|
||||||
|
{
|
||||||
|
mLastUpdateThrottledAnimationStyle = mRefreshDriver->MostRecentRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -664,8 +664,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Getter and setter for OMTA time counters
|
* Getter and setter for OMTA time counters
|
||||||
*/
|
*/
|
||||||
bool ThrottledStyleIsUpToDate() const;
|
bool ThrottledTransitionStyleIsUpToDate() const;
|
||||||
void TickLastUpdateThrottledStyle();
|
void TickLastUpdateThrottledTransitionStyle();
|
||||||
|
bool ThrottledAnimationStyleIsUpToDate() const;
|
||||||
|
void TickLastUpdateThrottledAnimationStyle();
|
||||||
bool StyleUpdateForAllAnimationsIsUpToDate();
|
bool StyleUpdateForAllAnimationsIsUpToDate();
|
||||||
void TickLastStyleUpdateForAllAnimations();
|
void TickLastStyleUpdateForAllAnimations();
|
||||||
|
|
||||||
|
@ -1240,8 +1242,10 @@ protected:
|
||||||
|
|
||||||
mozilla::TimeStamp mReflowStartTime;
|
mozilla::TimeStamp mReflowStartTime;
|
||||||
|
|
||||||
// last time animations/transition styles were flushed to their primary frames
|
// last time animations styles were flushed to their primary frames
|
||||||
mozilla::TimeStamp mLastUpdateThrottledStyle;
|
mozilla::TimeStamp mLastUpdateThrottledAnimationStyle;
|
||||||
|
// last time transition styles were flushed to their primary frames
|
||||||
|
mozilla::TimeStamp mLastUpdateThrottledTransitionStyle;
|
||||||
// last time we did a full style flush
|
// last time we did a full style flush
|
||||||
mozilla::TimeStamp mLastStyleUpdateForAllAnimations;
|
mozilla::TimeStamp mLastStyleUpdateForAllAnimations;
|
||||||
|
|
||||||
|
|
|
@ -6211,6 +6211,7 @@ FlushThrottledStyles(nsIDocument *aDocument, void *aData)
|
||||||
nsPresContext* presContext = shell->GetPresContext();
|
nsPresContext* presContext = shell->GetPresContext();
|
||||||
if (presContext) {
|
if (presContext) {
|
||||||
presContext->TransitionManager()->UpdateAllThrottledStyles();
|
presContext->TransitionManager()->UpdateAllThrottledStyles();
|
||||||
|
presContext->AnimationManager()->UpdateAllThrottledStyles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "gfxPlatform.h"
|
|
||||||
#include "AnimationCommon.h"
|
#include "AnimationCommon.h"
|
||||||
|
#include "nsTransitionManager.h"
|
||||||
|
#include "nsAnimationManager.h"
|
||||||
|
|
||||||
|
#include "gfxPlatform.h"
|
||||||
#include "nsRuleData.h"
|
#include "nsRuleData.h"
|
||||||
#include "nsCSSValue.h"
|
#include "nsCSSValue.h"
|
||||||
#include "nsStyleContext.h"
|
#include "nsStyleContext.h"
|
||||||
|
@ -16,6 +19,9 @@
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "RestyleManager.h"
|
#include "RestyleManager.h"
|
||||||
|
#include "nsStyleSet.h"
|
||||||
|
#include "nsStyleChangeList.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
|
|
||||||
|
@ -142,6 +148,157 @@ CommonAnimationManager::ExtractComputedValueForTransition(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsStyleContext>
|
||||||
|
CommonAnimationManager::ReparentContent(nsIContent* aContent,
|
||||||
|
nsStyleContext* aParentStyle)
|
||||||
|
{
|
||||||
|
nsStyleSet* styleSet = mPresContext->PresShell()->StyleSet();
|
||||||
|
nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aContent);
|
||||||
|
if (!primaryFrame) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
dom::Element* element = aContent->IsElement()
|
||||||
|
? aContent->AsElement()
|
||||||
|
: nullptr;
|
||||||
|
|
||||||
|
nsRefPtr<nsStyleContext> newStyle =
|
||||||
|
styleSet->ReparentStyleContext(primaryFrame->StyleContext(),
|
||||||
|
aParentStyle, element);
|
||||||
|
primaryFrame->SetStyleContext(newStyle);
|
||||||
|
ReparentBeforeAndAfter(element, primaryFrame, newStyle, styleSet);
|
||||||
|
|
||||||
|
return newStyle.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
CommonAnimationManager::ReparentBeforeAndAfter(dom::Element* aElement,
|
||||||
|
nsIFrame* aPrimaryFrame,
|
||||||
|
nsStyleContext* aNewStyle,
|
||||||
|
nsStyleSet* aStyleSet)
|
||||||
|
{
|
||||||
|
if (nsIFrame* before = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) {
|
||||||
|
nsRefPtr<nsStyleContext> beforeStyle =
|
||||||
|
aStyleSet->ReparentStyleContext(before->StyleContext(),
|
||||||
|
aNewStyle, aElement);
|
||||||
|
before->SetStyleContext(beforeStyle);
|
||||||
|
}
|
||||||
|
if (nsIFrame* after = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) {
|
||||||
|
nsRefPtr<nsStyleContext> afterStyle =
|
||||||
|
aStyleSet->ReparentStyleContext(after->StyleContext(),
|
||||||
|
aNewStyle, aElement);
|
||||||
|
after->SetStyleContext(afterStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the next repaint rebuilds the layer tree for aFrame. That
|
||||||
|
// means that changes to animations on aFrame's layer are propagated to
|
||||||
|
// the compositor, which is needed for correct behaviour of new
|
||||||
|
// transitions.
|
||||||
|
static void
|
||||||
|
ForceLayerRerendering(nsIFrame* aFrame, CommonElementAnimationData* aData)
|
||||||
|
{
|
||||||
|
if (aData->HasAnimationOfProperty(eCSSProperty_opacity)) {
|
||||||
|
if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
|
||||||
|
aFrame, nsDisplayItem::TYPE_OPACITY)) {
|
||||||
|
layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aData->HasAnimationOfProperty(eCSSProperty_transform)) {
|
||||||
|
if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
|
||||||
|
aFrame, nsDisplayItem::TYPE_TRANSFORM)) {
|
||||||
|
layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleContext*
|
||||||
|
CommonAnimationManager::UpdateThrottledStyle(dom::Element* aElement,
|
||||||
|
nsStyleContext* aParentStyle,
|
||||||
|
nsStyleChangeList& aChangeList)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mPresContext->TransitionManager()->GetElementTransitions(
|
||||||
|
aElement,
|
||||||
|
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||||
|
false) ||
|
||||||
|
mPresContext->AnimationManager()->GetElementAnimations(
|
||||||
|
aElement,
|
||||||
|
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||||
|
false), "element not animated");
|
||||||
|
|
||||||
|
nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aElement);
|
||||||
|
if (!primaryFrame) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleContext* oldStyle = primaryFrame->StyleContext();
|
||||||
|
nsRuleNode* ruleNode = oldStyle->RuleNode();
|
||||||
|
nsTArray<nsStyleSet::RuleAndLevel> rules;
|
||||||
|
do {
|
||||||
|
if (ruleNode->IsRoot()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsStyleSet::RuleAndLevel curRule;
|
||||||
|
curRule.mLevel = ruleNode->GetLevel();
|
||||||
|
|
||||||
|
if (curRule.mLevel == nsStyleSet::eAnimationSheet) {
|
||||||
|
ElementAnimations* ea =
|
||||||
|
mPresContext->AnimationManager()->GetElementAnimations(
|
||||||
|
aElement,
|
||||||
|
oldStyle->GetPseudoType(),
|
||||||
|
false);
|
||||||
|
NS_ASSERTION(ea,
|
||||||
|
"Rule has level eAnimationSheet without animation on manager");
|
||||||
|
|
||||||
|
mPresContext->AnimationManager()->EnsureStyleRuleFor(ea);
|
||||||
|
curRule.mRule = ea->mStyleRule;
|
||||||
|
|
||||||
|
// FIXME: maybe not needed anymore:
|
||||||
|
ForceLayerRerendering(primaryFrame, ea);
|
||||||
|
} else if (curRule.mLevel == nsStyleSet::eTransitionSheet) {
|
||||||
|
ElementTransitions *et =
|
||||||
|
mPresContext->TransitionManager()->GetElementTransitions(
|
||||||
|
aElement,
|
||||||
|
oldStyle->GetPseudoType(),
|
||||||
|
false);
|
||||||
|
NS_ASSERTION(et,
|
||||||
|
"Rule has level eTransitionSheet without transition on manager");
|
||||||
|
|
||||||
|
et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh());
|
||||||
|
curRule.mRule = et->mStyleRule;
|
||||||
|
|
||||||
|
// FIXME: maybe not needed anymore:
|
||||||
|
ForceLayerRerendering(primaryFrame, et);
|
||||||
|
} else {
|
||||||
|
curRule.mRule = ruleNode->GetRule();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curRule.mRule) {
|
||||||
|
rules.AppendElement(curRule);
|
||||||
|
}
|
||||||
|
} while ((ruleNode = ruleNode->GetParent()));
|
||||||
|
|
||||||
|
nsRefPtr<nsStyleContext> newStyle = mPresContext->PresShell()->StyleSet()->
|
||||||
|
ResolveStyleForRules(aParentStyle, oldStyle, rules);
|
||||||
|
|
||||||
|
// We absolutely must call CalcStyleDifference in order to ensure the
|
||||||
|
// new context has all the structs cached that the old context had.
|
||||||
|
// We also need it for processing of the changes.
|
||||||
|
nsChangeHint styleChange =
|
||||||
|
oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0));
|
||||||
|
aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(),
|
||||||
|
styleChange);
|
||||||
|
|
||||||
|
primaryFrame->SetStyleContext(newStyle);
|
||||||
|
|
||||||
|
ReparentBeforeAndAfter(aElement, primaryFrame, newStyle,
|
||||||
|
mPresContext->PresShell()->StyleSet());
|
||||||
|
|
||||||
|
return newStyle;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(AnimValuesStyleRule, nsIStyleRule)
|
NS_IMPL_ISUPPORTS1(AnimValuesStyleRule, nsIStyleRule)
|
||||||
|
|
||||||
/* virtual */ void
|
/* virtual */ void
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "nsSMILKeySpline.h"
|
#include "nsSMILKeySpline.h"
|
||||||
#include "nsStyleStruct.h"
|
#include "nsStyleStruct.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "nsCSSPseudoElements.h"
|
||||||
|
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsIFrame;
|
class nsIFrame;
|
||||||
|
@ -71,10 +72,82 @@ protected:
|
||||||
virtual void ElementDataRemoved() = 0;
|
virtual void ElementDataRemoved() = 0;
|
||||||
void RemoveAllElementData();
|
void RemoveAllElementData();
|
||||||
|
|
||||||
|
// Update the style on aElement from the transition stored in this manager and
|
||||||
|
// the new parent style - aParentStyle. aElement must be transitioning or
|
||||||
|
// animated. Returns the updated style.
|
||||||
|
nsStyleContext* UpdateThrottledStyle(mozilla::dom::Element* aElement,
|
||||||
|
nsStyleContext* aParentStyle,
|
||||||
|
nsStyleChangeList &aChangeList);
|
||||||
|
// Reparent the style of aContent and any :before and :after pseudo-elements.
|
||||||
|
already_AddRefed<nsStyleContext> ReparentContent(nsIContent* aContent,
|
||||||
|
nsStyleContext* aParentStyle);
|
||||||
|
// reparent :before and :after pseudo elements of aElement
|
||||||
|
static void ReparentBeforeAndAfter(dom::Element* aElement,
|
||||||
|
nsIFrame* aPrimaryFrame,
|
||||||
|
nsStyleContext* aNewStyle,
|
||||||
|
nsStyleSet* aStyleSet);
|
||||||
|
|
||||||
PRCList mElementData;
|
PRCList mElementData;
|
||||||
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
|
nsPresContext *mPresContext; // weak (non-null from ctor to Disconnect)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The internals of UpdateAllThrottledStyles, used by nsAnimationManager and
|
||||||
|
// nsTransitionManager, see the comments in the declaration of the latter.
|
||||||
|
#define IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(class_, animations_getter_) \
|
||||||
|
void \
|
||||||
|
class_::UpdateAllThrottledStylesInternal() \
|
||||||
|
{ \
|
||||||
|
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh(); \
|
||||||
|
\
|
||||||
|
nsStyleChangeList changeList; \
|
||||||
|
\
|
||||||
|
/* update each transitioning element by finding its root-most ancestor
|
||||||
|
with a transition, and flushing the style on that ancestor and all
|
||||||
|
its descendants*/ \
|
||||||
|
PRCList *next = PR_LIST_HEAD(&mElementData); \
|
||||||
|
while (next != &mElementData) { \
|
||||||
|
CommonElementAnimationData* ea = \
|
||||||
|
static_cast<CommonElementAnimationData*>(next); \
|
||||||
|
next = PR_NEXT_LINK(next); \
|
||||||
|
\
|
||||||
|
if (ea->mFlushGeneration == now) { \
|
||||||
|
/* this element has been ticked already */ \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
/* element is initialised to the starting element (i.e., one we know has
|
||||||
|
an animation) and ends up with the root-most animated ancestor,
|
||||||
|
that is, the element where we begin updates. */ \
|
||||||
|
dom::Element* element = ea->mElement; \
|
||||||
|
/* make a list of ancestors */ \
|
||||||
|
nsTArray<dom::Element*> ancestors; \
|
||||||
|
do { \
|
||||||
|
ancestors.AppendElement(element); \
|
||||||
|
} while ((element = element->GetParentElement())); \
|
||||||
|
\
|
||||||
|
/* walk down the ancestors until we find one with a throttled transition */\
|
||||||
|
for (int32_t i = ancestors.Length() - 1; i >= 0; --i) { \
|
||||||
|
if (animations_getter_(ancestors[i], \
|
||||||
|
nsCSSPseudoElements::ePseudo_NotPseudoElement, \
|
||||||
|
false)) { \
|
||||||
|
element = ancestors[i]; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
nsIFrame* primaryFrame; \
|
||||||
|
if (element && \
|
||||||
|
(primaryFrame = nsLayoutUtils::GetStyleFrame(element))) { \
|
||||||
|
UpdateThrottledStylesForSubtree(element, \
|
||||||
|
primaryFrame->StyleContext()->GetParent(), changeList); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
RestyleManager* restyleManager = mPresContext->RestyleManager(); \
|
||||||
|
restyleManager->ProcessRestyledFrames(changeList); \
|
||||||
|
restyleManager->FlushOverflowChangedTracker(); \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A style rule that maps property-nsStyleAnimation::Value pairs.
|
* A style rule that maps property-nsStyleAnimation::Value pairs.
|
||||||
*/
|
*/
|
||||||
|
@ -133,11 +206,12 @@ private:
|
||||||
struct CommonElementAnimationData : public PRCList
|
struct CommonElementAnimationData : public PRCList
|
||||||
{
|
{
|
||||||
CommonElementAnimationData(dom::Element *aElement, nsIAtom *aElementProperty,
|
CommonElementAnimationData(dom::Element *aElement, nsIAtom *aElementProperty,
|
||||||
CommonAnimationManager *aManager)
|
CommonAnimationManager *aManager, TimeStamp aNow)
|
||||||
: mElement(aElement)
|
: mElement(aElement)
|
||||||
, mElementProperty(aElementProperty)
|
, mElementProperty(aElementProperty)
|
||||||
, mManager(aManager)
|
, mManager(aManager)
|
||||||
, mAnimationGeneration(0)
|
, mAnimationGeneration(0)
|
||||||
|
, mFlushGeneration(aNow)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, mCalledPropertyDtor(false)
|
, mCalledPropertyDtor(false)
|
||||||
#endif
|
#endif
|
||||||
|
@ -217,6 +291,11 @@ struct CommonElementAnimationData : public PRCList
|
||||||
// The refresh time associated with mStyleRule.
|
// The refresh time associated with mStyleRule.
|
||||||
TimeStamp mStyleRuleRefreshTime;
|
TimeStamp mStyleRuleRefreshTime;
|
||||||
|
|
||||||
|
// Generation counter for flushes of throttled animations.
|
||||||
|
// Used to prevent updating the styles twice for a given element during
|
||||||
|
// UpdateAllThrottledStyles.
|
||||||
|
TimeStamp mFlushGeneration;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
bool mCalledPropertyDtor;
|
bool mCalledPropertyDtor;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,13 +4,16 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "nsAnimationManager.h"
|
#include "nsAnimationManager.h"
|
||||||
|
#include "nsTransitionManager.h"
|
||||||
|
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
|
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsRuleProcessorData.h"
|
#include "nsRuleProcessorData.h"
|
||||||
#include "nsStyleSet.h"
|
#include "nsStyleSet.h"
|
||||||
|
#include "nsStyleChangeList.h"
|
||||||
#include "nsCSSRules.h"
|
#include "nsCSSRules.h"
|
||||||
|
#include "RestyleManager.h"
|
||||||
#include "nsStyleAnimation.h"
|
#include "nsStyleAnimation.h"
|
||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
#include "nsLayoutUtils.h"
|
#include "nsLayoutUtils.h"
|
||||||
|
@ -22,10 +25,12 @@
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::css;
|
using namespace mozilla::css;
|
||||||
|
|
||||||
ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement,
|
||||||
nsAnimationManager *aAnimationManager)
|
nsIAtom *aElementProperty,
|
||||||
|
nsAnimationManager *aAnimationManager,
|
||||||
|
TimeStamp aNow)
|
||||||
: CommonElementAnimationData(aElement, aElementProperty,
|
: CommonElementAnimationData(aElement, aElementProperty,
|
||||||
aAnimationManager),
|
aAnimationManager, aNow),
|
||||||
mNeedsRefreshes(true)
|
mNeedsRefreshes(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -452,7 +457,8 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
||||||
aElement->GetProperty(propName));
|
aElement->GetProperty(propName));
|
||||||
if (!ea && aCreateIfNeeded) {
|
if (!ea && aCreateIfNeeded) {
|
||||||
// FIXME: Consider arena-allocating?
|
// FIXME: Consider arena-allocating?
|
||||||
ea = new ElementAnimations(aElement, propName, this);
|
ea = new ElementAnimations(aElement, propName, this,
|
||||||
|
mPresContext->RefreshDriver()->MostRecentRefresh());
|
||||||
nsresult rv = aElement->SetProperty(propName, ea,
|
nsresult rv = aElement->SetProperty(propName, ea,
|
||||||
ElementAnimationsPropertyDtor, false);
|
ElementAnimationsPropertyDtor, false);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -1093,3 +1099,62 @@ nsAnimationManager::DoDispatchEvents()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsAnimationManager::UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
|
nsStyleContext* aParentStyle,
|
||||||
|
nsStyleChangeList& aChangeList)
|
||||||
|
{
|
||||||
|
dom::Element* element;
|
||||||
|
if (aContent->IsElement()) {
|
||||||
|
element = aContent->AsElement();
|
||||||
|
} else {
|
||||||
|
element = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<nsStyleContext> newStyle;
|
||||||
|
|
||||||
|
ElementAnimations* ea;
|
||||||
|
if (element &&
|
||||||
|
(ea = GetElementAnimations(element,
|
||||||
|
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
||||||
|
false))) {
|
||||||
|
// re-resolve our style
|
||||||
|
newStyle = UpdateThrottledStyle(element, aParentStyle, aChangeList);
|
||||||
|
// remove the current transition from the working set
|
||||||
|
ea->mFlushGeneration = mPresContext->RefreshDriver()->MostRecentRefresh();
|
||||||
|
} else {
|
||||||
|
newStyle = ReparentContent(aContent, aParentStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk the children
|
||||||
|
if (newStyle) {
|
||||||
|
for (nsIContent *child = aContent->GetFirstChild(); child;
|
||||||
|
child = child->GetNextSibling()) {
|
||||||
|
UpdateThrottledStylesForSubtree(child, newStyle, aChangeList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(nsAnimationManager,
|
||||||
|
GetElementAnimations)
|
||||||
|
|
||||||
|
void
|
||||||
|
nsAnimationManager::UpdateAllThrottledStyles()
|
||||||
|
{
|
||||||
|
if (PR_CLIST_IS_EMPTY(&mElementData)) {
|
||||||
|
// no throttled animations, leave early
|
||||||
|
mPresContext->TickLastUpdateThrottledAnimationStyle();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPresContext->ThrottledAnimationStyleIsUpToDate()) {
|
||||||
|
// throttled transitions are up to date, leave early
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mPresContext->TickLastUpdateThrottledAnimationStyle();
|
||||||
|
|
||||||
|
UpdateAllThrottledStylesInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ struct ElementAnimations MOZ_FINAL
|
||||||
typedef mozilla::TimeDuration TimeDuration;
|
typedef mozilla::TimeDuration TimeDuration;
|
||||||
|
|
||||||
ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
||||||
nsAnimationManager *aAnimationManager);
|
nsAnimationManager *aAnimationManager, TimeStamp aNow);
|
||||||
|
|
||||||
// This function takes as input the start time, duration, and direction of an
|
// This function takes as input the start time, duration, and direction of an
|
||||||
// animation and returns the position in the current iteration. Note that
|
// animation and returns the position in the current iteration. Note that
|
||||||
|
@ -275,6 +275,9 @@ public:
|
||||||
nsCSSPseudoElements::Type aPseudoType,
|
nsCSSPseudoElements::Type aPseudoType,
|
||||||
bool aCreateIfNeeded);
|
bool aCreateIfNeeded);
|
||||||
|
|
||||||
|
// Updates styles on throttled animations. See note on nsTransitionManager
|
||||||
|
void UpdateAllThrottledStyles();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void ElementDataRemoved() MOZ_OVERRIDE
|
virtual void ElementDataRemoved() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
@ -298,6 +301,14 @@ private:
|
||||||
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
|
nsIStyleRule* GetAnimationRule(mozilla::dom::Element* aElement,
|
||||||
nsCSSPseudoElements::Type aPseudoType);
|
nsCSSPseudoElements::Type aPseudoType);
|
||||||
|
|
||||||
|
// Update the animated styles of an element and its descendants.
|
||||||
|
// If the element has an animation, it is flushed back to its primary frame.
|
||||||
|
// If the element does not have an animation, then its style is reparented.
|
||||||
|
void UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
|
nsStyleContext* aParentStyle,
|
||||||
|
nsStyleChangeList &aChangeList);
|
||||||
|
void UpdateAllThrottledStylesInternal();
|
||||||
|
|
||||||
// The guts of DispatchEvents
|
// The guts of DispatchEvents
|
||||||
void DoDispatchEvents();
|
void DoDispatchEvents();
|
||||||
|
|
||||||
|
|
|
@ -41,8 +41,8 @@ ElementTransitions::ElementTransitions(mozilla::dom::Element *aElement,
|
||||||
nsIAtom *aElementProperty,
|
nsIAtom *aElementProperty,
|
||||||
nsTransitionManager *aTransitionManager,
|
nsTransitionManager *aTransitionManager,
|
||||||
TimeStamp aNow)
|
TimeStamp aNow)
|
||||||
: CommonElementAnimationData(aElement, aElementProperty, aTransitionManager)
|
: CommonElementAnimationData(aElement, aElementProperty,
|
||||||
, mFlushGeneration(aNow)
|
aTransitionManager, aNow)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -210,122 +210,6 @@ ElementTransitions::CanPerformOnCompositorThread(CanAnimateFlags aFlags) const
|
||||||
* nsTransitionManager *
|
* nsTransitionManager *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
// reparent :before and :after pseudo elements of aElement
|
|
||||||
static void ReparentBeforeAndAfter(dom::Element* aElement,
|
|
||||||
nsIFrame* aPrimaryFrame,
|
|
||||||
nsStyleContext* aNewStyle,
|
|
||||||
nsStyleSet* aStyleSet)
|
|
||||||
{
|
|
||||||
if (nsIFrame* before = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) {
|
|
||||||
nsRefPtr<nsStyleContext> beforeStyle =
|
|
||||||
aStyleSet->ReparentStyleContext(before->StyleContext(),
|
|
||||||
aNewStyle, aElement);
|
|
||||||
before->SetStyleContext(beforeStyle);
|
|
||||||
}
|
|
||||||
if (nsIFrame* after = nsLayoutUtils::GetBeforeFrame(aPrimaryFrame)) {
|
|
||||||
nsRefPtr<nsStyleContext> afterStyle =
|
|
||||||
aStyleSet->ReparentStyleContext(after->StyleContext(),
|
|
||||||
aNewStyle, aElement);
|
|
||||||
after->SetStyleContext(afterStyle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that the next repaint rebuilds the layer tree for aFrame. That
|
|
||||||
// means that changes to animations on aFrame's layer are propagated to
|
|
||||||
// the compositor, which is needed for correct behaviour of new
|
|
||||||
// transitions.
|
|
||||||
static void
|
|
||||||
ForceLayerRerendering(nsIFrame* aFrame, CommonElementAnimationData* aData)
|
|
||||||
{
|
|
||||||
if (aData->HasAnimationOfProperty(eCSSProperty_opacity)) {
|
|
||||||
if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
|
|
||||||
aFrame, nsDisplayItem::TYPE_OPACITY)) {
|
|
||||||
layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aData->HasAnimationOfProperty(eCSSProperty_transform)) {
|
|
||||||
if (Layer* layer = FrameLayerBuilder::GetDedicatedLayer(
|
|
||||||
aFrame, nsDisplayItem::TYPE_TRANSFORM)) {
|
|
||||||
layer->RemoveUserData(nsIFrame::LayerIsPrerenderedDataKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsStyleContext*
|
|
||||||
nsTransitionManager::UpdateThrottledStyle(dom::Element* aElement,
|
|
||||||
nsStyleContext* aParentStyle,
|
|
||||||
nsStyleChangeList& aChangeList)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(GetElementTransitions(aElement,
|
|
||||||
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
|
||||||
false), "element not transitioning");
|
|
||||||
|
|
||||||
nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aElement);
|
|
||||||
if (!primaryFrame) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsStyleContext* oldStyle = primaryFrame->StyleContext();
|
|
||||||
nsRuleNode* ruleNode = oldStyle->RuleNode();
|
|
||||||
nsTArray<nsStyleSet::RuleAndLevel> rules;
|
|
||||||
do {
|
|
||||||
if (ruleNode->IsRoot()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsStyleSet::RuleAndLevel curRule;
|
|
||||||
curRule.mLevel = ruleNode->GetLevel();
|
|
||||||
|
|
||||||
if (curRule.mLevel == nsStyleSet::eAnimationSheet) {
|
|
||||||
ElementAnimations* ea =
|
|
||||||
mPresContext->AnimationManager()->GetElementAnimations(aElement,
|
|
||||||
oldStyle->GetPseudoType(),
|
|
||||||
false);
|
|
||||||
NS_ASSERTION(ea, "Rule has level eAnimationSheet without animation on manager");
|
|
||||||
|
|
||||||
mPresContext->AnimationManager()->EnsureStyleRuleFor(ea);
|
|
||||||
curRule.mRule = ea->mStyleRule;
|
|
||||||
|
|
||||||
// FIXME: maybe not needed anymore:
|
|
||||||
ForceLayerRerendering(primaryFrame, ea);
|
|
||||||
} else if (curRule.mLevel == nsStyleSet::eTransitionSheet) {
|
|
||||||
ElementTransitions *et =
|
|
||||||
GetElementTransitions(aElement, oldStyle->GetPseudoType(), false);
|
|
||||||
NS_ASSERTION(et, "Rule has level eTransitionSheet without transition on manager");
|
|
||||||
|
|
||||||
et->EnsureStyleRuleFor(mPresContext->RefreshDriver()->MostRecentRefresh());
|
|
||||||
curRule.mRule = et->mStyleRule;
|
|
||||||
|
|
||||||
// FIXME: maybe not needed anymore:
|
|
||||||
ForceLayerRerendering(primaryFrame, et);
|
|
||||||
} else {
|
|
||||||
curRule.mRule = ruleNode->GetRule();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (curRule.mRule) {
|
|
||||||
rules.AppendElement(curRule);
|
|
||||||
}
|
|
||||||
} while ((ruleNode = ruleNode->GetParent()));
|
|
||||||
|
|
||||||
nsRefPtr<nsStyleContext> newStyle = mPresContext->PresShell()->StyleSet()->
|
|
||||||
ResolveStyleForRules(aParentStyle, oldStyle, rules);
|
|
||||||
|
|
||||||
// We absolutely must call CalcStyleDifference in order to ensure the
|
|
||||||
// new context has all the structs cached that the old context had.
|
|
||||||
// We also need it for processing of the changes.
|
|
||||||
nsChangeHint styleChange =
|
|
||||||
oldStyle->CalcStyleDifference(newStyle, nsChangeHint(0));
|
|
||||||
aChangeList.AppendChange(primaryFrame, primaryFrame->GetContent(),
|
|
||||||
styleChange);
|
|
||||||
|
|
||||||
primaryFrame->SetStyleContext(newStyle);
|
|
||||||
|
|
||||||
ReparentBeforeAndAfter(aElement, primaryFrame, newStyle, mPresContext->PresShell()->StyleSet());
|
|
||||||
|
|
||||||
return newStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
nsStyleContext* aParentStyle,
|
nsStyleContext* aParentStyle,
|
||||||
|
@ -350,17 +234,7 @@ nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
// remove the current transition from the working set
|
// remove the current transition from the working set
|
||||||
et->mFlushGeneration = mPresContext->RefreshDriver()->MostRecentRefresh();
|
et->mFlushGeneration = mPresContext->RefreshDriver()->MostRecentRefresh();
|
||||||
} else {
|
} else {
|
||||||
// reparent the element's style
|
newStyle = ReparentContent(aContent, aParentStyle);
|
||||||
nsStyleSet* styleSet = mPresContext->PresShell()->StyleSet();
|
|
||||||
nsIFrame* primaryFrame = nsLayoutUtils::GetStyleFrame(aContent);
|
|
||||||
if (!primaryFrame) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
newStyle = styleSet->ReparentStyleContext(primaryFrame->StyleContext(),
|
|
||||||
aParentStyle, element);
|
|
||||||
primaryFrame->SetStyleContext(newStyle);
|
|
||||||
ReparentBeforeAndAfter(element, primaryFrame, newStyle, styleSet);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// walk the children
|
// walk the children
|
||||||
|
@ -372,68 +246,25 @@ nsTransitionManager::UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMPL_UPDATE_ALL_THROTTLED_STYLES_INTERNAL(nsTransitionManager,
|
||||||
|
GetElementTransitions)
|
||||||
|
|
||||||
void
|
void
|
||||||
nsTransitionManager::UpdateAllThrottledStyles()
|
nsTransitionManager::UpdateAllThrottledStyles()
|
||||||
{
|
{
|
||||||
if (PR_CLIST_IS_EMPTY(&mElementData)) {
|
if (PR_CLIST_IS_EMPTY(&mElementData)) {
|
||||||
// no throttled transitions, leave early
|
// no throttled transitions, leave early
|
||||||
mPresContext->TickLastUpdateThrottledStyle();
|
mPresContext->TickLastUpdateThrottledTransitionStyle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPresContext->ThrottledStyleIsUpToDate()) {
|
if (mPresContext->ThrottledTransitionStyleIsUpToDate()) {
|
||||||
// throttled transitions are up to date, leave early
|
// throttled transitions are up to date, leave early
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPresContext->TickLastUpdateThrottledStyle();
|
mPresContext->TickLastUpdateThrottledTransitionStyle();
|
||||||
TimeStamp now = mPresContext->RefreshDriver()->MostRecentRefresh();
|
UpdateAllThrottledStylesInternal();
|
||||||
|
|
||||||
nsStyleChangeList changeList;
|
|
||||||
|
|
||||||
// update each transitioning element by finding its root-most ancestor with a
|
|
||||||
// transition, and flushing the style on that ancestor and all its descendants
|
|
||||||
PRCList *next = PR_LIST_HEAD(&mElementData);
|
|
||||||
while (next != &mElementData) {
|
|
||||||
ElementTransitions* et = static_cast<ElementTransitions*>(next);
|
|
||||||
next = PR_NEXT_LINK(next);
|
|
||||||
|
|
||||||
if (et->mFlushGeneration == now) {
|
|
||||||
// this element has been ticked already
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// element is initialised to the starting element (i.e., one we know has
|
|
||||||
// a transition) and ends up with the root-most transitioning ancestor,
|
|
||||||
// that is, the element where we begin updates.
|
|
||||||
dom::Element* element = et->mElement;
|
|
||||||
// make a list of ancestors
|
|
||||||
nsTArray<dom::Element*> ancestors;
|
|
||||||
do {
|
|
||||||
ancestors.AppendElement(element);
|
|
||||||
} while ((element = element->GetParentElement()));
|
|
||||||
|
|
||||||
// walk down the ancestors until we find one with a throttled transition
|
|
||||||
for (int32_t i = ancestors.Length() - 1; i >= 0; --i) {
|
|
||||||
if (GetElementTransitions(ancestors[i],
|
|
||||||
nsCSSPseudoElements::ePseudo_NotPseudoElement,
|
|
||||||
false)) {
|
|
||||||
element = ancestors[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIFrame* primaryFrame;
|
|
||||||
if (element &&
|
|
||||||
(primaryFrame = nsLayoutUtils::GetStyleFrame(element))) {
|
|
||||||
UpdateThrottledStylesForSubtree(element,
|
|
||||||
primaryFrame->StyleContext()->GetParent(), changeList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RestyleManager* restyleManager = mPresContext->RestyleManager();
|
|
||||||
restyleManager->ProcessRestyledFrames(changeList);
|
|
||||||
restyleManager->FlushOverflowChangedTracker();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -527,7 +358,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_WARN_IF_FALSE(!nsLayoutUtils::AreAsyncAnimationsEnabled() ||
|
NS_WARN_IF_FALSE(!nsLayoutUtils::AreAsyncAnimationsEnabled() ||
|
||||||
mPresContext->ThrottledStyleIsUpToDate(),
|
mPresContext->ThrottledTransitionStyleIsUpToDate(),
|
||||||
"throttled animations not up to date");
|
"throttled animations not up to date");
|
||||||
|
|
||||||
// Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
|
// Per http://lists.w3.org/Archives/Public/www-style/2009Aug/0109.html
|
||||||
|
|
|
@ -91,11 +91,6 @@ struct ElementTransitions MOZ_FINAL
|
||||||
|
|
||||||
// Either zero or one for each CSS property:
|
// Either zero or one for each CSS property:
|
||||||
nsTArray<ElementPropertyTransition> mPropertyTransitions;
|
nsTArray<ElementPropertyTransition> mPropertyTransitions;
|
||||||
|
|
||||||
// Generation counter for flushes of throttled transitions.
|
|
||||||
// Used to prevent updating the styles twice for a given element during
|
|
||||||
// UpdateAllThrottledStyles.
|
|
||||||
mozilla::TimeStamp mFlushGeneration;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,6 +198,10 @@ public:
|
||||||
// other than primary frames.
|
// other than primary frames.
|
||||||
void UpdateAllThrottledStyles();
|
void UpdateAllThrottledStyles();
|
||||||
|
|
||||||
|
ElementTransitions* GetElementTransitions(mozilla::dom::Element *aElement,
|
||||||
|
nsCSSPseudoElements::Type aPseudoType,
|
||||||
|
bool aCreateIfNeeded);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void ElementDataRemoved() MOZ_OVERRIDE;
|
virtual void ElementDataRemoved() MOZ_OVERRIDE;
|
||||||
virtual void AddElementData(mozilla::css::CommonElementAnimationData* aData) MOZ_OVERRIDE;
|
virtual void AddElementData(mozilla::css::CommonElementAnimationData* aData) MOZ_OVERRIDE;
|
||||||
|
@ -216,24 +215,15 @@ private:
|
||||||
nsStyleContext *aNewStyleContext,
|
nsStyleContext *aNewStyleContext,
|
||||||
bool *aStartedAny,
|
bool *aStartedAny,
|
||||||
nsCSSPropertySet *aWhichStarted);
|
nsCSSPropertySet *aWhichStarted);
|
||||||
ElementTransitions* GetElementTransitions(mozilla::dom::Element *aElement,
|
|
||||||
nsCSSPseudoElements::Type aPseudoType,
|
|
||||||
bool aCreateIfNeeded);
|
|
||||||
void WalkTransitionRule(ElementDependentRuleProcessorData* aData,
|
void WalkTransitionRule(ElementDependentRuleProcessorData* aData,
|
||||||
nsCSSPseudoElements::Type aPseudoType);
|
nsCSSPseudoElements::Type aPseudoType);
|
||||||
|
|
||||||
// Update the animated styles of an element and its descendants.
|
// Update the animated styles of an element and its descendants.
|
||||||
// If the element has a transition, it is flushed back to its primary frame.
|
// If the element has a transition, it is flushed back to its primary frame.
|
||||||
// If the element does not have a transition, then its style is reparented.
|
// If the element does not have a transition, then its style is reparented.
|
||||||
void UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
void UpdateThrottledStylesForSubtree(nsIContent* aContent,
|
||||||
nsStyleContext* aParentStyle,
|
nsStyleContext* aParentStyle,
|
||||||
nsStyleChangeList &aChangeList);
|
nsStyleChangeList &aChangeList);
|
||||||
// Update the style on aElement from the transition stored in this manager and
|
void UpdateAllThrottledStylesInternal();
|
||||||
// the new parent style - aParentStyle. aElement must be transitioning or
|
|
||||||
// animated. Returns the updated style.
|
|
||||||
nsStyleContext* UpdateThrottledStyle(mozilla::dom::Element* aElement,
|
|
||||||
nsStyleContext* aParentStyle,
|
|
||||||
nsStyleChangeList &aChangeList);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* !defined(nsTransitionManager_h_) */
|
#endif /* !defined(nsTransitionManager_h_) */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче