Bug 1285474: stylo: Add dirtiness-tracking hooks for Servo and convenient methods. r=bholley

Also, guard with asserts the access to the new shared flags.

MozReview-Commit-ID: H9UFFHRPmiu
This commit is contained in:
Emilio Cobos Álvarez
2016-07-08 00:07:06 -07:00
parent 6fdfeb30ce
commit 948a479bad
9 changed files with 77 additions and 36 deletions

View File

@@ -1526,7 +1526,7 @@ Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
ClearSubtreeRootPointer(); ClearSubtreeRootPointer();
// Being added to a document. // Being added to a document.
SetInDocument(); SetIsInDocument();
// Unset this flag since we now really are in a document. // Unset this flag since we now really are in a document.
UnsetFlags(NODE_FORCE_XBL_BINDINGS | UnsetFlags(NODE_FORCE_XBL_BINDINGS |

View File

@@ -1450,6 +1450,13 @@ inline const mozilla::dom::Element* nsINode::AsElement() const
return static_cast<const mozilla::dom::Element*>(this); return static_cast<const mozilla::dom::Element*>(this);
} }
inline void nsINode::UnsetRestyleFlagsIfGecko()
{
if (IsElement() && !IsStyledByServo()) {
UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
}
}
/** /**
* Macros to implement Clone(). _elementName is the class for which to implement * Macros to implement Clone(). _elementName is the class for which to implement
* Clone. * Clone.

View File

@@ -1460,7 +1460,10 @@ nsIDocument::nsIDocument()
mHasScrollLinkedEffect(false), mHasScrollLinkedEffect(false),
mUserHasInteracted(false) mUserHasInteracted(false)
{ {
SetInDocument(); SetIsDocument();
if (IsStyledByServo()) {
SetFlags(NODE_IS_DIRTY_FOR_SERVO | NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
}
PR_INIT_CLIST(&mDOMMediaQueryLists); PR_INIT_CLIST(&mDOMMediaQueryLists);
} }

View File

@@ -540,7 +540,7 @@ nsGenericDOMDataNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
ClearSubtreeRootPointer(); ClearSubtreeRootPointer();
// XXX See the comment in Element::BindToTree // XXX See the comment in Element::BindToTree
SetInDocument(); SetIsInDocument();
if (mText.IsBidi()) { if (mText.IsBidi()) {
aDocument->SetBidiEnabled(); aDocument->SetBidiEnabled();
} }

View File

@@ -1003,6 +1003,7 @@ public:
SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO | NODE_IS_DIRTY_FOR_SERVO); SetFlags(NODE_HAS_DIRTY_DESCENDANTS_FOR_SERVO | NODE_IS_DIRTY_FOR_SERVO);
} }
inline void UnsetRestyleFlagsIfGecko();
/** /**
* Adds a mutation observer to be notified when this node, or any of its * Adds a mutation observer to be notified when this node, or any of its
@@ -1726,7 +1727,17 @@ public:
} }
protected: protected:
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); } void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
void SetInDocument() { SetBoolFlag(IsInDocument); } /**
* This is a special case of SetIsInDocument used to special-case it for the
* document constructor (which can't do the IsStyledByServo() check).
*/
void SetIsDocument() { SetBoolFlag(IsInDocument); }
void SetIsInDocument() {
if (IsStyledByServo()) {
SetIsDirtyAndHasDirtyDescendantsForServo();
}
SetBoolFlag(IsInDocument);
}
void SetNodeIsContent() { SetBoolFlag(NodeIsContent); } void SetNodeIsContent() { SetBoolFlag(NodeIsContent); }
void ClearInDocument() { ClearBoolFlag(IsInDocument); } void ClearInDocument() { ClearBoolFlag(IsInDocument); }
void SetIsElement() { SetBoolFlag(NodeIsElement); } void SetIsElement() { SetBoolFlag(NodeIsElement); }

View File

@@ -2430,7 +2430,7 @@ nsCSSFrameConstructor::ConstructDocElementFrame(Element* aDocEle
// this document. Unlike in AddFrameConstructionItems, it's safe to // this document. Unlike in AddFrameConstructionItems, it's safe to
// unset all element restyle flags, since we don't have any // unset all element restyle flags, since we don't have any
// siblings. // siblings.
aDocElement->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS); aDocElement->UnsetRestyleFlagsIfGecko();
// --------- CREATE AREA OR BOX FRAME ------- // --------- CREATE AREA OR BOX FRAME -------
// FIXME: Should this use ResolveStyleContext? (The calls in this // FIXME: Should this use ResolveStyleContext? (The calls in this
@@ -5513,7 +5513,7 @@ nsCSSFrameConstructor::ShouldCreateItemsForChild(nsFrameConstructorState& aState
nsContainerFrame* aParentFrame) nsContainerFrame* aParentFrame)
{ {
aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); aContent->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
if (aContent->IsElement()) { if (aContent->IsElement() && !aContent->IsStyledByServo()) {
// We can't just remove our pending restyle flags, since we may // We can't just remove our pending restyle flags, since we may
// have restyle-later-siblings set on us. But we _can_ remove the // have restyle-later-siblings set on us. But we _can_ remove the
// "is possible restyle root" flags, and need to. Otherwise we can // "is possible restyle root" flags, and need to. Otherwise we can
@@ -10542,13 +10542,16 @@ nsCSSFrameConstructor::AddFCItemsForAnonymousContent(
"CreateAnonymousFrames manually and not follow the standard " "CreateAnonymousFrames manually and not follow the standard "
"ProcessChildren() codepath for this frame"); "ProcessChildren() codepath for this frame");
#endif #endif
// Anything restyled by servo should already have the style data.
MOZ_ASSERT_IF(content->IsStyledByServo(), !!content->GetServoNodeData());
// Gecko-styled nodes should have no pending restyle flags.
MOZ_ASSERT_IF(!content->IsStyledByServo(),
!content->IsElement() ||
!(content->GetFlags() & ELEMENT_ALL_RESTYLE_FLAGS));
// Assert some things about this content // Assert some things about this content
MOZ_ASSERT(!(content->GetFlags() & MOZ_ASSERT(!(content->GetFlags() &
(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME)), (NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME)),
"Should not be marked as needing frames"); "Should not be marked as needing frames");
MOZ_ASSERT(!content->IsElement() ||
!(content->GetFlags() & ELEMENT_ALL_RESTYLE_FLAGS),
"Should have no pending restyle flags");
MOZ_ASSERT(!content->GetPrimaryFrame(), MOZ_ASSERT(!content->GetPrimaryFrame(),
"Should have no existing frame"); "Should have no existing frame");
MOZ_ASSERT(!content->IsNodeOfType(nsINode::eCOMMENT) && MOZ_ASSERT(!content->IsNodeOfType(nsINode::eCOMMENT) &&
@@ -10696,9 +10699,7 @@ nsCSSFrameConstructor::ProcessChildren(nsFrameConstructorState& aState,
// Frame construction item construction should not post // Frame construction item construction should not post
// restyles, so removing restyle flags here is safe. // restyles, so removing restyle flags here is safe.
if (child->IsElement()) { child->UnsetRestyleFlagsIfGecko();
child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
}
if (addChildItems) { if (addChildItems) {
AddFrameConstructionItems(aState, child, iter.XBLInvolved(), insertion, AddFrameConstructionItems(aState, child, iter.XBLInvolved(), insertion,
itemsToConstruct); itemsToConstruct);
@@ -12008,13 +12009,12 @@ nsCSSFrameConstructor::BuildInlineChildItems(nsFrameConstructorState& aState,
content->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) { content->IsNodeOfType(nsINode::ePROCESSING_INSTRUCTION)) {
continue; continue;
} }
if (content->IsElement()) {
// See comment explaining why we need to remove the "is possible // See comment explaining why we need to remove the "is possible
// restyle root" flags in AddFrameConstructionItems. But note // restyle root" flags in AddFrameConstructionItems. But note
// that we can remove all restyle flags, just like in // that we can remove all restyle flags, just like in
// ProcessChildren and for the same reason. // ProcessChildren and for the same reason.
content->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS); content->UnsetRestyleFlagsIfGecko();
}
RefPtr<nsStyleContext> childContext = RefPtr<nsStyleContext> childContext =
ResolveStyleContext(parentStyleContext, content, &aState); ResolveStyleContext(parentStyleContext, content, &aState);

View File

@@ -279,9 +279,7 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
for (uint32_t i = childX; i < numChildren; i++) { for (uint32_t i = childX; i < numChildren; i++) {
nsIContent *child = mContent->GetChildAt(i); nsIContent *child = mContent->GetChildAt(i);
child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
if (child->IsElement()) { child->UnsetRestyleFlagsIfGecko();
child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
}
} }
break; break;
} }
@@ -289,9 +287,7 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME); child->UnsetFlags(NODE_DESCENDANTS_NEED_FRAMES | NODE_NEEDS_FRAME);
// Also clear the restyle flags in the child like // Also clear the restyle flags in the child like
// nsCSSFrameConstructor::ProcessChildren does. // nsCSSFrameConstructor::ProcessChildren does.
if (child->IsElement()) { child->UnsetRestyleFlagsIfGecko();
child->UnsetFlags(ELEMENT_ALL_RESTYLE_FLAGS);
}
// IMPORTANT: This must match the conditions in // IMPORTANT: This must match the conditions in
// nsCSSFrameConstructor::ContentAppended/Inserted/Removed // nsCSSFrameConstructor::ContentAppended/Inserted/Removed

View File

@@ -164,6 +164,25 @@ Gecko_GetElementId(RawGeckoElement* aElement)
return attr ? attr->GetAtomValue() : nullptr; return attr ? attr->GetAtomValue() : nullptr;
} }
// Dirtiness tracking.
uint32_t
Gecko_GetNodeFlags(RawGeckoNode* aNode)
{
return aNode->GetFlags();
}
void
Gecko_SetNodeFlags(RawGeckoNode* aNode, uint32_t aFlags)
{
aNode->SetFlags(aFlags);
}
void
Gecko_UnsetNodeFlags(RawGeckoNode* aNode, uint32_t aFlags)
{
aNode->UnsetFlags(aFlags);
}
template<class MatchFn> template<class MatchFn>
bool bool
DoMatch(RawGeckoElement* aElement, nsIAtom* aNS, nsIAtom* aName, MatchFn aMatch) DoMatch(RawGeckoElement* aElement, nsIAtom* aNS, nsIAtom* aName, MatchFn aMatch)

View File

@@ -176,6 +176,11 @@ void Gecko_SetMozBinding(nsStyleDisplay* style_struct,
ThreadSafePrincipalHolder* principal); ThreadSafePrincipalHolder* principal);
void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src); void Gecko_CopyMozBindingFrom(nsStyleDisplay* des, const nsStyleDisplay* src);
// Dirtiness tracking.
uint32_t Gecko_GetNodeFlags(RawGeckoNode* node);
void Gecko_SetNodeFlags(RawGeckoNode* node, uint32_t flags);
void Gecko_UnsetNodeFlags(RawGeckoNode* node, uint32_t flags);
// Styleset and Stylesheet management. // Styleset and Stylesheet management.
// //
// TODO: Make these return already_AddRefed and UniquePtr when the binding // TODO: Make these return already_AddRefed and UniquePtr when the binding