From 7ac8c49b89a46bb85913b04a1ffb2f46d00e5260 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Wed, 19 Jul 2017 17:50:35 +0800 Subject: [PATCH] Bug 1380133 - Part 5: Call CalcStyleDifference with ServoStyleContexts instead of a FakeStyleContext wrapping a ServoComputedValues. r=emilio MozReview-Commit-ID: 6JhMas1EiM7 --HG-- extra : rebase_source : 22d94de05a300bd3d696db94b6999821c0af0b11 --- layout/style/ServoBindings.cpp | 21 ++++++++---- layout/style/ServoBindings.h | 3 +- layout/style/nsStyleContext.cpp | 58 +++++++++++++++++---------------- layout/style/nsStyleContext.h | 29 +++++++++++------ 4 files changed, 65 insertions(+), 46 deletions(-) diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 55d751b9e105..b761de78c150 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -398,18 +398,25 @@ Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement) } nsChangeHint -Gecko_CalcStyleDifference(nsStyleContext* aOldStyleFromFrame, +Gecko_CalcStyleDifference(const ServoStyleContext* aOldStyle, const ServoStyleContext* aNewStyle, + uint64_t aOldStyleBits, bool* aAnyStyleChanged) { - MOZ_ASSERT(aOldStyleFromFrame); + MOZ_ASSERT(aOldStyle); MOZ_ASSERT(aNewStyle); - uint32_t equalStructs, samePointerStructs; - nsChangeHint result = - aOldStyleFromFrame->CalcStyleDifference(aNewStyle->ComputedValues(), - &equalStructs, - &samePointerStructs); + uint32_t relevantStructs = aOldStyleBits & NS_STYLE_INHERIT_MASK; + + uint32_t equalStructs; + uint32_t samePointerStructs; // unused + nsChangeHint result = const_cast(aOldStyle)-> + CalcStyleDifference( + const_cast(aNewStyle), + &equalStructs, + &samePointerStructs, + relevantStructs); + *aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK; return result; } diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index c163ea9fe1c8..b8f86dce5878 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -378,8 +378,9 @@ void Gecko_SetOwnerDocumentNeedsStyleFlush(RawGeckoElementBorrowed element); nsStyleContext* Gecko_GetStyleContext(RawGeckoElementBorrowed element, nsIAtom* aPseudoTagOrNull); mozilla::CSSPseudoElementType Gecko_GetImplementedPseudo(RawGeckoElementBorrowed element); -nsChangeHint Gecko_CalcStyleDifference(nsStyleContext* old_style_from_frame, +nsChangeHint Gecko_CalcStyleDifference(const mozilla::ServoStyleContext* old_style, const mozilla::ServoStyleContext* new_style, + uint64_t old_style_bits, bool* any_style_changed); nsChangeHint Gecko_HintsHandledForDescendants(nsChangeHint aHint); diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index d8317d61a899..2cd62f8d59b1 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -189,13 +189,21 @@ template nsChangeHint nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs) + uint32_t* aSamePointerStructs, + uint32_t aRelevantStructs) { AUTO_PROFILER_LABEL("nsStyleContext::CalcStyleDifferenceInternal", CSS); static_assert(nsStyleStructID_Length <= 32, "aEqualStructs is not big enough"); + MOZ_ASSERT(aRelevantStructs == kAllResolvedStructs || IsServo(), + "aRelevantStructs must be kAllResolvedStructs for Gecko contexts"); + + if (aRelevantStructs == kAllResolvedStructs) { + aRelevantStructs = mBits & NS_STYLE_INHERIT_MASK; + } + *aEqualStructs = 0; nsChangeHint hint = nsChangeHint(0); @@ -242,10 +250,21 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, // any change hints for those structs. bool checkUnrequestedServoStructs = IsServo(); + // For Gecko structs, we just defer to PeekStyleXXX. But for Servo structs, + // we need to use the aRelevantStructs bitfield passed in to determine + // whether to return a struct or not, since this->mBits might not yet + // be correct (due to not calling ResolveSameStructsAs on it yet). +#define PEEK(struct_) \ + (IsGecko() \ + ? PeekStyle##struct_() \ + : ((aRelevantStructs & NS_STYLE_INHERIT_BIT(struct_)) \ + ? AsServo()->ComputedValues()->GetStyle##struct_() \ + : nullptr)) + #define EXPAND(...) __VA_ARGS__ #define DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, extra_args_) \ PR_BEGIN_MACRO \ - const nsStyle##struct_* this##struct_ = PeekStyle##struct_(); \ + const nsStyle##struct_* this##struct_ = PEEK(struct_); \ bool unrequestedStruct; \ if (this##struct_) { \ unrequestedStruct = false; \ @@ -296,10 +315,10 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, DO_STRUCT_DIFFERENCE(Table); DO_STRUCT_DIFFERENCE(UIReset); DO_STRUCT_DIFFERENCE(Text); - DO_STRUCT_DIFFERENCE_WITH_ARGS(List, (, PeekStyleDisplay())); + DO_STRUCT_DIFFERENCE_WITH_ARGS(List, (, PEEK(Display))); DO_STRUCT_DIFFERENCE(SVGReset); DO_STRUCT_DIFFERENCE(SVG); - DO_STRUCT_DIFFERENCE_WITH_ARGS(Position, (, PeekStyleVisibility())); + DO_STRUCT_DIFFERENCE_WITH_ARGS(Position, (, PEEK(Visibility))); DO_STRUCT_DIFFERENCE(Font); DO_STRUCT_DIFFERENCE(Margin); DO_STRUCT_DIFFERENCE(Padding); @@ -319,7 +338,7 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, #ifdef DEBUG #define STYLE_STRUCT(name_, callback_) \ MOZ_ASSERT(!!(structsFound & NS_STYLE_INHERIT_BIT(name_)) == \ - !!PeekStyle##name_(), \ + !!PEEK(name_), \ "PeekStyleData results must not change in the middle of " \ "difference calculation."); #include "nsStyleStructList.h" @@ -338,7 +357,7 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, #define STYLE_STRUCT(name_, callback_) \ { \ - const nsStyle##name_* data = PeekStyle##name_(); \ + const nsStyle##name_* data = PEEK(name_); \ if (!data || data == aNewContext->ThreadsafeStyle##name_()) { \ *aSamePointerStructs |= NS_STYLE_INHERIT_BIT(name_); \ } \ @@ -369,14 +388,6 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, // Presume a difference. hint |= nsChangeHint_RepaintFrame; } else if (thisVis && !NS_IsHintSubset(nsChangeHint_RepaintFrame, hint)) { - // Bug 1364484: Update comments here and potentially remove the assertion - // below once we return a non-null visited context in CalcStyleDifference - // using Servo values. The approach is becoming quite similar to Gecko. - // We'll handle visited style differently in servo. Assert against being - // in the parallel traversal to avoid static analysis hazards when calling - // StyleFoo() below. - MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal()); - // Both style contexts have a style-if-visited. bool change = false; @@ -387,7 +398,7 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, // not having a style-if-visited), but not the other way around. #define STYLE_FIELD(name_) thisVisStruct->name_ != otherVisStruct->name_ #define STYLE_STRUCT(name_, fields_) \ - if (!change && PeekStyle##name_()) { \ + if (!change && PEEK(name_)) { \ const nsStyle##name_* thisVisStruct = \ thisVis->ThreadsafeStyle##name_(); \ const nsStyle##name_* otherVisStruct = \ @@ -439,11 +450,13 @@ nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext, nsChangeHint nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext, uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs) + uint32_t* aSamePointerStructs, + uint32_t aRelevantStructs) { return CalcStyleDifferenceInternal(aNewContext, aEqualStructs, - aSamePointerStructs); + aSamePointerStructs, + aRelevantStructs); } class MOZ_STACK_CLASS FakeStyleContext @@ -477,17 +490,6 @@ private: const ServoComputedValues* MOZ_NON_OWNING_REF mComputedValues; }; -nsChangeHint -nsStyleContext::CalcStyleDifference(const ServoComputedValues* aNewComputedValues, - uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs) -{ - FakeStyleContext newContext(aNewComputedValues); - return CalcStyleDifferenceInternal(&newContext, - aEqualStructs, - aSamePointerStructs); -} - namespace mozilla { void diff --git a/layout/style/nsStyleContext.h b/layout/style/nsStyleContext.h index 7c811aa7035c..a9b8dbf88bc9 100644 --- a/layout/style/nsStyleContext.h +++ b/layout/style/nsStyleContext.h @@ -253,6 +253,14 @@ public: #include "nsStyleStructList.h" #undef STYLE_STRUCT + // Value that can be passed as CalcStyleDifference's aRelevantStructs + // argument to indicate that all structs that are currently resolved on the + // old style context should be compared. This is only relevant for + // ServoStyleContexts. + enum { kAllResolvedStructs = 0xffffffff }; + static_assert(kAllResolvedStructs != NS_STYLE_INHERIT_MASK, + "uint32_t not big enough for special kAllResolvedStructs value"); + /** * Compute the style changes needed during restyling when this style * context is being replaced by aNewContext. (This is nonsymmetric since @@ -266,24 +274,25 @@ public: * * aEqualStructs must not be null. Into it will be stored a bitfield * representing which structs were compared to be non-equal. + * + * aRelevantStructs must be kAllResolvedStructs for GeckoStyleContexts. + * For ServoStyleContexts, it controls which structs will be compared. + * This is needed because in some cases, we can't rely on mBits in the + * old style context to accurately reflect which are the relevant + * structs to be compared. */ nsChangeHint CalcStyleDifference(nsStyleContext* aNewContext, uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs); - - /** - * Like the above, but allows comparing ServoComputedValues instead of needing - * a full-fledged style context. - */ - nsChangeHint CalcStyleDifference(const ServoComputedValues* aNewComputedValues, - uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs); + uint32_t* aSamePointerStructs, + uint32_t aRelevantStructs = + kAllResolvedStructs); private: template nsChangeHint CalcStyleDifferenceInternal(StyleContextLike* aNewContext, uint32_t* aEqualStructs, - uint32_t* aSamePointerStructs); + uint32_t* aSamePointerStructs, + uint32_t aRelevantStructs); public: /**