mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1181011 - Don't use cached rule node structs for animations within pseudo-elements. r=dbaron a=abillings
This commit is contained in:
parent
c8f4c9b8ba
commit
d8b0ee0385
@ -231,6 +231,7 @@ CommonAnimationManager::RulesMatching(ElementRuleProcessorData* aData)
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement);
|
||||
if (rule) {
|
||||
aData->mRuleWalker->Forward(rule);
|
||||
aData->mRuleWalker->CurrentNode()->SetIsAnimationRule();
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,6 +251,7 @@ CommonAnimationManager::RulesMatching(PseudoElementRuleProcessorData* aData)
|
||||
nsIStyleRule *rule = GetAnimationRule(aData->mElement, aData->mPseudoType);
|
||||
if (rule) {
|
||||
aData->mRuleWalker->Forward(rule);
|
||||
aData->mRuleWalker->CurrentNode()->SetIsAnimationRule();
|
||||
}
|
||||
}
|
||||
|
||||
@ -486,6 +488,15 @@ AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
|
||||
// Don't apply transitions or animations to things inside of
|
||||
// pseudo-elements.
|
||||
// FIXME (Bug 522599): Add tests for this.
|
||||
|
||||
// Prevent structs from being cached on the rule node since we're inside
|
||||
// a pseudo-element, as we could determine cacheability differently
|
||||
// when walking the rule tree for a style context that is not inside
|
||||
// a pseudo-element. Note that nsRuleNode::GetStyle##name_ and GetStyleData
|
||||
// will never look at cached structs when we're animating things inside
|
||||
// a pseduo-element, so that we don't incorrectly return a struct that
|
||||
// is only appropriate for non-pseudo-elements.
|
||||
aRuleData->mConditions.SetUncacheable();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1475,7 +1475,8 @@ nsRuleNode::nsRuleNode(nsPresContext* aContext, nsRuleNode* aParent,
|
||||
mNextSibling(nullptr),
|
||||
mDependentBits((uint32_t(aLevel) << NS_RULE_NODE_LEVEL_SHIFT) |
|
||||
(aIsImportant ? NS_RULE_NODE_IS_IMPORTANT : 0)),
|
||||
mNoneBits(0),
|
||||
mNoneBits(aParent ? aParent->mNoneBits & NS_RULE_NODE_HAS_ANIMATION_DATA :
|
||||
0),
|
||||
mRefCnt(0)
|
||||
{
|
||||
MOZ_ASSERT(aContext);
|
||||
@ -9321,9 +9322,14 @@ nsRuleNode::GetStyleData(nsStyleStructID aSID,
|
||||
"in some way.");
|
||||
|
||||
const void *data;
|
||||
data = mStyleData.GetStyleData(aSID, aContext);
|
||||
if (MOZ_LIKELY(data != nullptr))
|
||||
return data; // We have a fully specified struct. Just return it.
|
||||
|
||||
// Never use cached data for animated style inside a pseudo-element;
|
||||
// see comment on cacheability in AnimValuesStyleRule::MapRuleInfoInto.
|
||||
if (!(HasAnimationData() && ParentHasPseudoElementData(aContext))) {
|
||||
data = mStyleData.GetStyleData(aSID, aContext);
|
||||
if (MOZ_LIKELY(data != nullptr))
|
||||
return data; // We have a fully specified struct. Just return it.
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(!aComputeData))
|
||||
return nullptr;
|
||||
@ -9779,3 +9785,10 @@ nsRuleNode::ComputeColor(const nsCSSValue& aValue, nsPresContext* aPresContext,
|
||||
MOZ_ASSERT(ok || !(aPresContext && aStyleContext));
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsRuleNode::ParentHasPseudoElementData(nsStyleContext* aContext)
|
||||
{
|
||||
nsStyleContext* parent = aContext->GetParent();
|
||||
return parent && parent->HasPseudoElementData();
|
||||
}
|
||||
|
@ -843,6 +843,29 @@ public:
|
||||
return (mDependentBits & NS_RULE_NODE_USED_DIRECTLY) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the mRule of this rule node an AnimValuesStyleRule?
|
||||
*/
|
||||
void SetIsAnimationRule() {
|
||||
MOZ_ASSERT(!HaveChildren() ||
|
||||
(mDependentBits & NS_RULE_NODE_IS_ANIMATION_RULE),
|
||||
"SetIsAnimationRule must only set the IS_ANIMATION_RULE bit "
|
||||
"before the rule node has children");
|
||||
mDependentBits |= NS_RULE_NODE_IS_ANIMATION_RULE;
|
||||
mNoneBits |= NS_RULE_NODE_HAS_ANIMATION_DATA;
|
||||
}
|
||||
bool IsAnimationRule() const {
|
||||
return (mDependentBits & NS_RULE_NODE_IS_ANIMATION_RULE) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the mRule of this rule node or any of its ancestors an
|
||||
* AnimValuesStyleRule?
|
||||
*/
|
||||
bool HasAnimationData() const {
|
||||
return (mNoneBits & NS_RULE_NODE_HAS_ANIMATION_DATA) != 0;
|
||||
}
|
||||
|
||||
// NOTE: Does not |AddRef|. Null only for the root.
|
||||
nsIStyleRule* GetRule() const { return mRule; }
|
||||
// NOTE: Does not |AddRef|. Never null.
|
||||
@ -866,9 +889,14 @@ public:
|
||||
"in some way."); \
|
||||
\
|
||||
const nsStyle##name_ *data; \
|
||||
data = mStyleData.GetStyle##name_(); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
\
|
||||
/* Never use cached data for animated style inside a pseudo-element; */ \
|
||||
/* see comment on cacheability in AnimValuesStyleRule::MapRuleInfoInto */ \
|
||||
if (!(HasAnimationData() && ParentHasPseudoElementData(aContext))) { \
|
||||
data = mStyleData.GetStyle##name_(); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
} \
|
||||
\
|
||||
if (!aComputeData) \
|
||||
return nullptr; \
|
||||
@ -891,9 +919,14 @@ public:
|
||||
"in some way."); \
|
||||
\
|
||||
const nsStyle##name_ *data; \
|
||||
data = mStyleData.GetStyle##name_(aContext); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
\
|
||||
/* Never use cached data for animated style inside a pseudo-element; */ \
|
||||
/* see comment on cacheability in AnimValuesStyleRule::MapRuleInfoInto */ \
|
||||
if (!(HasAnimationData() && ParentHasPseudoElementData(aContext))) { \
|
||||
data = mStyleData.GetStyle##name_(aContext); \
|
||||
if (MOZ_LIKELY(data != nullptr)) \
|
||||
return data; \
|
||||
} \
|
||||
\
|
||||
if (!aComputeData) \
|
||||
return nullptr; \
|
||||
@ -1017,6 +1050,8 @@ public:
|
||||
nsPresContext* aPresContext,
|
||||
nsStyleContext* aStyleContext,
|
||||
nscolor& aResult);
|
||||
|
||||
static bool ParentHasPseudoElementData(nsStyleContext* aContext);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -845,6 +845,7 @@ ReplaceAnimationRule(nsRuleNode *aOldRuleNode,
|
||||
|
||||
if (aNewAnimRule) {
|
||||
n = n->Transition(aNewAnimRule, nsStyleSet::eAnimationSheet, false);
|
||||
n->SetIsAnimationRule();
|
||||
}
|
||||
|
||||
for (uint32_t i = moreSpecificNodes.Length(); i-- != 0; ) {
|
||||
@ -1439,6 +1440,7 @@ struct RuleNodeInfo {
|
||||
nsIStyleRule* mRule;
|
||||
uint8_t mLevel;
|
||||
bool mIsImportant;
|
||||
bool mIsAnimationRule;
|
||||
};
|
||||
|
||||
struct CascadeLevel {
|
||||
@ -1508,6 +1510,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
curRule->mRule = ruleNode->GetRule();
|
||||
curRule->mLevel = ruleNode->GetLevel();
|
||||
curRule->mIsImportant = ruleNode->IsImportantRule();
|
||||
curRule->mIsAnimationRule = ruleNode->IsAnimationRule();
|
||||
}
|
||||
|
||||
nsRuleWalker ruleWalker(mRuleTree, mAuthorStyleDisabled);
|
||||
@ -1538,6 +1541,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
GetAnimationRule(aElement, aPseudoType);
|
||||
if (rule) {
|
||||
ruleWalker.ForwardOnPossiblyCSSRule(rule);
|
||||
ruleWalker.CurrentNode()->SetIsAnimationRule();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1550,6 +1554,7 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
GetAnimationRule(aElement, aPseudoType);
|
||||
if (rule) {
|
||||
ruleWalker.ForwardOnPossiblyCSSRule(rule);
|
||||
ruleWalker.CurrentNode()->SetIsAnimationRule();
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1615,6 +1620,9 @@ nsStyleSet::RuleNodeWithReplacement(Element* aElement,
|
||||
|
||||
if (!doReplace) {
|
||||
ruleWalker.ForwardOnPossiblyCSSRule(ruleInfo.mRule);
|
||||
if (ruleInfo.mIsAnimationRule) {
|
||||
ruleWalker.CurrentNode()->SetIsAnimationRule();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,12 +67,16 @@ class imgIContainer;
|
||||
#define NS_STYLE_CONTEXT_TYPE_SHIFT 34
|
||||
|
||||
// Additional bits for nsRuleNode's mDependentBits:
|
||||
#define NS_RULE_NODE_IS_ANIMATION_RULE 0x01000000
|
||||
#define NS_RULE_NODE_GC_MARK 0x02000000
|
||||
#define NS_RULE_NODE_USED_DIRECTLY 0x04000000
|
||||
#define NS_RULE_NODE_IS_IMPORTANT 0x08000000
|
||||
#define NS_RULE_NODE_LEVEL_MASK 0xf0000000
|
||||
#define NS_RULE_NODE_LEVEL_SHIFT 28
|
||||
|
||||
// Additional bits for nsRuleNode's mNoneBits:
|
||||
#define NS_RULE_NODE_HAS_ANIMATION_DATA 0x80000000
|
||||
|
||||
// The lifetime of these objects is managed by the presshell's arena.
|
||||
|
||||
struct nsStyleFont {
|
||||
|
Loading…
Reference in New Issue
Block a user