--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -374,16 +374,34 @@ Gecko_CalcStyleDifference(nsStyleContext
aOldStyleContext->CalcStyleDifference(aComputedValues,
&equalStructs,
&samePointerStructs);
*aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK;
return result;
}
nsChangeHint
+Gecko_CalcComputedValuesDifference(ServoComputedValuesBorrowed aOldComputedValues,
+ ServoComputedValuesBorrowed aNewComputedValues,
+ bool* aAnyStyleChanged)
+{
+ MOZ_ASSERT(aOldComputedValues);
+ MOZ_ASSERT(aNewComputedValues);
+
+ uint32_t equalStructs, samePointerStructs;
+ nsChangeHint result =
+ nsStyleContext::CalcStyleDifference(aOldComputedValues,
+ aNewComputedValues,
+ &equalStructs,
+ &samePointerStructs);
+ *aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK;
+ return result;
+}
+
+nsChangeHint
Gecko_HintsHandledForDescendants(nsChangeHint aHint)
{
return aHint & ~NS_HintsNotHandledForDescendantsIn(aHint);
}
const ServoElementSnapshot*
Gecko_GetElementSnapshot(const ServoElementSnapshotTable* aTable,
const Element* aElement)
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -984,28 +984,31 @@ nsStyleContext::ApplyStyleFixups(bool aS
}
}
// Compute User Interface style, to trigger loads of cursors
StyleUserInterface();
#undef GET_UNIQUE_STYLE_DATA
}
-template<class StyleContextLike>
-nsChangeHint
-nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike* aNewContext,
+template<class StyleContextLike1, class StyleContextLike2>
+/* static */ nsChangeHint
+nsStyleContext::CalcStyleDifferenceInternal(StyleContextLike1* aOldContext,
+ StyleContextLike2* aNewContext,
uint32_t* aEqualStructs,
uint32_t* aSamePointerStructs)
{
PROFILER_LABEL("nsStyleContext", "CalcStyleDifference",
js::ProfileEntry::Category::CSS);
static_assert(nsStyleStructID_Length <= 32,
"aEqualStructs is not big enough");
+ MOZ_ASSERT(aOldContext, "What are we doing here?");
+
*aEqualStructs = 0;
nsChangeHint hint = nsChangeHint(0);
NS_ENSURE_TRUE(aNewContext, hint);
// We must always ensure that we populate the structs on the new style
// context that are filled in on the old context, so that if we get
// two style changes in succession, the second of which causes a real
// style change, the PeekStyleData doesn't return null (implying that
@@ -1014,17 +1017,17 @@ nsStyleContext::CalcStyleDifferenceInter
// we could later get a small change in one of those structs that we
// don't want to miss.
DebugOnly<uint32_t> structsFound = 0;
// FIXME(heycam): We should just do the comparison in
// nsStyleVariables::CalcDifference, returning NeutralChange if there are
// any Variables differences.
- const nsStyleVariables* thisVariables = PeekStyleVariables();
+ const nsStyleVariables* thisVariables = aOldContext->PeekStyleVariables();
if (thisVariables) {
structsFound |= NS_STYLE_INHERIT_BIT(Variables);
const nsStyleVariables* otherVariables = aNewContext->StyleVariables();
if (thisVariables->mVariables == otherVariables->mVariables) {
*aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
}
} else {
*aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
@@ -1032,28 +1035,30 @@ nsStyleContext::CalcStyleDifferenceInter
DebugOnly<int> styleStructCount = 1; // count Variables already
// Servo's optimization to stop the cascade when there are no style changes
// that children need to be recascade for relies on comparing all of the
// structs, not just those that are returned from PeekStyleData, although
// if PeekStyleData does return null we still don't want to accumulate
// any change hints for those structs.
- bool checkUnrequestedServoStructs = mSource.IsServoComputedValues();
+ bool checkUnrequestedServoStructs =
+ aOldContext->StyleSource().IsServoComputedValues();
#define DO_STRUCT_DIFFERENCE(struct_) \
PR_BEGIN_MACRO \
- const nsStyle##struct_* this##struct_ = PeekStyle##struct_(); \
+ const nsStyle##struct_* this##struct_ = aOldContext->PeekStyle##struct_();\
bool unrequestedStruct; \
if (this##struct_) { \
unrequestedStruct = false; \
structsFound |= NS_STYLE_INHERIT_BIT(struct_); \
} else if (checkUnrequestedServoStructs) { \
this##struct_ = \
- Servo_GetStyle##struct_(mSource.AsServoComputedValues()); \
+ Servo_GetStyle##struct_( \
+ aOldContext->StyleSource().AsServoComputedValues()); \
unrequestedStruct = true; \
} else { \
unrequestedStruct = false; \
} \
if (this##struct_) { \
const nsStyle##struct_* other##struct_ = aNewContext->Style##struct_(); \
if (this##struct_ == other##struct_) { \
/* The very same struct, so we know that there will be no */ \
@@ -1089,17 +1094,17 @@ nsStyleContext::CalcStyleDifferenceInter
DO_STRUCT_DIFFERENCE(TableBorder);
DO_STRUCT_DIFFERENCE(Table);
DO_STRUCT_DIFFERENCE(UIReset);
DO_STRUCT_DIFFERENCE(Text);
DO_STRUCT_DIFFERENCE(List);
DO_STRUCT_DIFFERENCE(SVGReset);
DO_STRUCT_DIFFERENCE(SVG);
#undef EXTRA_DIFF_ARGS
-#define EXTRA_DIFF_ARGS , PeekStyleVisibility()
+#define EXTRA_DIFF_ARGS , aOldContext->PeekStyleVisibility()
DO_STRUCT_DIFFERENCE(Position);
#undef EXTRA_DIFF_ARGS
#define EXTRA_DIFF_ARGS /* nothing */
DO_STRUCT_DIFFERENCE(Font);
DO_STRUCT_DIFFERENCE(Margin);
DO_STRUCT_DIFFERENCE(Padding);
DO_STRUCT_DIFFERENCE(Border);
DO_STRUCT_DIFFERENCE(TextReset);
@@ -1111,17 +1116,17 @@ nsStyleContext::CalcStyleDifferenceInter
#undef DO_STRUCT_DIFFERENCE
MOZ_ASSERT(styleStructCount == nsStyleStructID_Length,
"missing a call to DO_STRUCT_DIFFERENCE");
#ifdef DEBUG
#define STYLE_STRUCT(name_, callback_) \
MOZ_ASSERT(!!(structsFound & NS_STYLE_INHERIT_BIT(name_)) == \
- !!PeekStyle##name_(), \
+ !!aOldContext->PeekStyle##name_(), \
"PeekStyleData results must not change in the middle of " \
"difference calculation.");
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#endif
// We check for struct pointer equality here rather than as part of the
// DO_STRUCT_DIFFERENCE calls, since those calls can result in structs
@@ -1130,17 +1135,17 @@ nsStyleContext::CalcStyleDifferenceInter
// happen when the nsRuleNode::ComputeXXXData method looks up another
// struct.) This is important for callers in RestyleManager that
// need to know the equality or not of the final set of cached struct
// pointers.
*aSamePointerStructs = 0;
#define STYLE_STRUCT(name_, callback_) \
{ \
- const nsStyle##name_* data = PeekStyle##name_(); \
+ const nsStyle##name_* data = aOldContext->PeekStyle##name_(); \
if (!data || data == aNewContext->Style##name_()) { \
*aSamePointerStructs |= NS_STYLE_INHERIT_BIT(name_); \
} \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
// Note that we do not check whether this->RelevantLinkVisited() !=
@@ -1154,17 +1159,17 @@ nsStyleContext::CalcStyleDifferenceInter
// the page to measure.
// However, we do need to compute the larger of the changes that can
// happen depending on whether the link is visited or unvisited, since
// doing only the one that's currently appropriate would expose which
// links are in history to easy performance measurement. Therefore,
// here, we add nsChangeHint_RepaintFrame hints (the maximum for
// things that can depend on :visited) for the properties on which we
// call GetVisitedDependentColor.
- nsStyleContext *thisVis = GetStyleIfVisited(),
+ nsStyleContext *thisVis = aOldContext->GetStyleIfVisited(),
*otherVis = aNewContext->GetStyleIfVisited();
if (!thisVis != !otherVis) {
// One style context has a style-if-visited and the other doesn't.
// 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
@@ -1179,17 +1184,17 @@ nsStyleContext::CalcStyleDifferenceInter
// NB: Calling Peek on |this|, not |thisVis|, since callers may look
// at a struct on |this| without looking at the same struct on
// |thisVis| (including this function if we skip one of these checks
// due to change being true already or due to the old style context
// 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 && aOldContext->PeekStyle##name_()) { \
const nsStyle##name_* thisVisStruct = thisVis->Style##name_(); \
const nsStyle##name_* otherVisStruct = otherVis->Style##name_(); \
if (MOZ_FOR_EACH_SEPARATED(STYLE_FIELD, (||), (), fields_)) { \
change = true; \
} \
}
#include "nsCSSVisitedDependentPropList.h"
#undef STYLE_STRUCT
@@ -1209,20 +1214,22 @@ nsStyleContext::CalcStyleDifferenceInter
// This depends on data in nsStyleDisplay, nsStyleEffects and
// nsStyleSVGReset, so we do it here.
// Note that it's perhaps good for this test to be last because it
// doesn't use Peek* functions to get the structs on the old
// context. But this isn't a big concern because these struct
// getters should be called during frame construction anyway.
- if (ThreadsafeStyleDisplay()->IsAbsPosContainingBlockForAppropriateFrame(this) ==
+ if (aOldContext->ThreadsafeStyleDisplay()->
+ IsAbsPosContainingBlockForAppropriateFrame(aOldContext) ==
aNewContext->ThreadsafeStyleDisplay()->
IsAbsPosContainingBlockForAppropriateFrame(aNewContext) &&
- ThreadsafeStyleDisplay()->IsFixedPosContainingBlockForAppropriateFrame(this) ==
+ aOldContext->ThreadsafeStyleDisplay()->
+ IsFixedPosContainingBlockForAppropriateFrame(aOldContext) ==
aNewContext->ThreadsafeStyleDisplay()->
IsFixedPosContainingBlockForAppropriateFrame(aNewContext)) {
// While some styles that cause the frame to be a containing block
// has changed, the overall result hasn't.
hint &= ~nsChangeHint_UpdateContainingBlock;
}
}
@@ -1231,17 +1238,18 @@ nsStyleContext::CalcStyleDifferenceInter
return hint & ~nsChangeHint_NeutralChange;
}
nsChangeHint
nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext,
uint32_t* aEqualStructs,
uint32_t* aSamePointerStructs)
{
- return CalcStyleDifferenceInternal(aNewContext,
+ return CalcStyleDifferenceInternal(this,
+ aNewContext,
aEqualStructs,
aSamePointerStructs);
}
class MOZ_STACK_CLASS FakeStyleContext
{
public:
explicit FakeStyleContext(const ServoComputedValues* aComputedValues)
@@ -1261,31 +1269,49 @@ public:
}
#define STYLE_STRUCT(name_, checkdata_cb_) \
const nsStyle##name_ * Style##name_() { \
return Servo_GetStyle##name_(mComputedValues); \
} \
const nsStyle##name_ * ThreadsafeStyle##name_() { \
return Servo_GetStyle##name_(mComputedValues); \
+ } \
+ const nsStyle##name_ * PeekStyle##name_() { \
+ return Servo_GetStyle##name_(mComputedValues); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
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,
+ return CalcStyleDifferenceInternal(this,
+ &newContext,
+ aEqualStructs,
+ aSamePointerStructs);
+}
+
+/* static */ nsChangeHint
+nsStyleContext::CalcStyleDifference(const ServoComputedValues* aOldComputedValues,
+ const ServoComputedValues* aNewComputedValues,
+ uint32_t* aEqualStructs,
+ uint32_t* aSamePointerStructs)
+{
+ FakeStyleContext oldContext(aOldComputedValues);
+ FakeStyleContext newContext(aNewComputedValues);
+ return CalcStyleDifferenceInternal(&oldContext,
+ &newContext,
aEqualStructs,
aSamePointerStructs);
}
void
nsStyleContext::EnsureSameStructsCached(nsStyleContext* aOldContext)
{
// NOTE(emilio): We could do better here for stylo, where we only call
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -416,19 +416,30 @@ public:
/**
* 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);
+ /**
+ * Like the above, but compares two ServoComputedValues to each other.
+ */
+ static nsChangeHint CalcStyleDifference(
+ const ServoComputedValues* aOldComputedValues,
+ const ServoComputedValues* aNewComputedValues,
+ uint32_t* aEqualStructs,
+ uint32_t* aSamePointerStructs);
+
private:
- template<class StyleContextLike>
- nsChangeHint CalcStyleDifferenceInternal(StyleContextLike* aNewContext,
+ template<class StyleContextLike1, class StyleContextLike2>
+ static
+ nsChangeHint CalcStyleDifferenceInternal(StyleContextLike1* aOldContext,
+ StyleContextLike2* aNewContext,
uint32_t* aEqualStructs,
uint32_t* aSamePointerStructs);
public:
/**
* Ensures the same structs are cached on this style context as would be
* done if we called aOther->CalcDifference(this).
*/