Bug 1464060: Make the general setup for computed style bits nicer. r?xidorn
This patch:
* Makes StyleStructID an enum class, and moves it to the mozilla namespaces.
* Introduces StyleStructConstants with some constants scattered through the
codebase.
* Makes the computed style bits an enum class, and splits mPseudoType and mBits
into their own members, since we were using a uint64_t when we have only a
couple flags and CSSPseudoElementType is a byte. We statically assert that
the number of style structs is less or equal to 32.
* Makes mPseudoTag, mPseudoType and mBits const, since we don't want them to be
mutated from C++, and we still need a few more refactorings (mostly getting
rid of FinishStyle) to avoid mutating ComputedStyle instead.
MozReview-Commit-ID: 7qsTtASGcYB
--- a/layout/style/ComputedStyle.cpp
+++ b/layout/style/ComputedStyle.cpp
@@ -38,70 +38,36 @@
// Ensure the binding function declarations in ComputedStyle.h matches
// those in ServoBindings.h.
#include "mozilla/ServoBindings.h"
namespace mozilla {
//----------------------------------------------------------------------
-#ifdef DEBUG
-
-// Check that the style struct IDs are in the same order as they are
-// in nsStyleStructList.h, since when we set up the IDs, we include
-// the inherited and reset structs spearately from nsStyleStructList.h
-enum DebugStyleStruct {
-#define STYLE_STRUCT(name) eDebugStyleStruct_##name,
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
-};
-
-#define STYLE_STRUCT(name) \
- static_assert(static_cast<int>(eDebugStyleStruct_##name) == \
- static_cast<int>(eStyleStruct_##name), \
- "Style struct IDs are not declared in order?");
-#include "nsStyleStructList.h"
-#undef STYLE_STRUCT
-
-#endif
-
-
ComputedStyle::ComputedStyle(nsPresContext* aPresContext,
nsAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
ServoComputedDataForgotten aComputedValues)
: mPresContext(aPresContext)
, mSource(aComputedValues)
, mPseudoTag(aPseudoTag)
- , mBits(((uint64_t)aPseudoType) << NS_STYLE_CONTEXT_TYPE_SHIFT)
+ , mBits(static_cast<Bit>(Servo_ComputedValues_GetStyleBits(this)))
+ , mPseudoType(aPseudoType)
{
- AddStyleBit(Servo_ComputedValues_GetStyleBits(this));
MOZ_ASSERT(ComputedData());
-
- // This check has to be done "backward", because if it were written the
- // more natural way it wouldn't fail even when it needed to.
- static_assert((UINT64_MAX >> NS_STYLE_CONTEXT_TYPE_SHIFT) >=
- static_cast<CSSPseudoElementTypeBase>(
- CSSPseudoElementType::MAX),
- "pseudo element bits no longer fit in a uint64_t");
-
-#define eStyleStruct_LastItem (nsStyleStructID_Length - 1)
- static_assert(NS_STYLE_INHERIT_MASK & NS_STYLE_INHERIT_BIT(LastItem),
- "NS_STYLE_INHERIT_MASK must be bigger, and other bits shifted");
-#undef eStyleStruct_LastItem
}
nsChangeHint
ComputedStyle::CalcStyleDifference(ComputedStyle* aNewContext,
uint32_t* aEqualStructs)
{
MOZ_ASSERT(aNewContext);
AUTO_PROFILER_LABEL("ComputedStyle::CalcStyleDifference", CSS);
-
- static_assert(nsStyleStructID_Length <= 32,
+ static_assert(StyleStructConstants::kStyleStructCount <= 32,
"aEqualStructs is not big enough");
*aEqualStructs = 0;
nsChangeHint hint = nsChangeHint(0);
// 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
@@ -127,34 +93,34 @@ ComputedStyle::CalcStyleDifference(Compu
#define PEEK(struct_) \
ComputedData()->GetStyle##struct_()
#define EXPAND(...) __VA_ARGS__
#define DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, extra_args_) \
PR_BEGIN_MACRO \
const nsStyle##struct_* this##struct_ = PEEK(struct_); \
if (this##struct_) { \
- structsFound |= NS_STYLE_INHERIT_BIT(struct_); \
+ structsFound |= STYLE_STRUCT_BIT(struct_); \
\
const nsStyle##struct_* other##struct_ = \
aNewContext->ThreadsafeStyle##struct_(); \
if (this##struct_ == other##struct_) { \
/* The very same struct, so we know that there will be no */ \
/* differences. */ \
- *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
+ *aEqualStructs |= STYLE_STRUCT_BIT(struct_); \
} else { \
nsChangeHint difference = \
this##struct_->CalcDifference(*other##struct_ EXPAND extra_args_); \
hint |= difference; \
if (!difference) { \
- *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
+ *aEqualStructs |= STYLE_STRUCT_BIT(struct_); \
} \
} \
} else { \
- *aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
+ *aEqualStructs |= STYLE_STRUCT_BIT(struct_); \
} \
styleStructCount++; \
PR_END_MACRO
#define DO_STRUCT_DIFFERENCE(struct_) \
DO_STRUCT_DIFFERENCE_WITH_ARGS(struct_, ())
// FIXME: The order of these DO_STRUCT_DIFFERENCE calls is no longer
// significant. With a small amount of effort, we could replace them with a
@@ -182,22 +148,22 @@ ComputedStyle::CalcStyleDifference(Compu
DO_STRUCT_DIFFERENCE(Effects);
DO_STRUCT_DIFFERENCE(Background);
DO_STRUCT_DIFFERENCE(Color);
#undef DO_STRUCT_DIFFERENCE
#undef DO_STRUCT_DIFFERENCE_WITH_ARGS
#undef EXPAND
- MOZ_ASSERT(styleStructCount == nsStyleStructID_Length,
+ MOZ_ASSERT(styleStructCount == StyleStructConstants::kStyleStructCount,
"missing a call to DO_STRUCT_DIFFERENCE");
#ifdef DEBUG
#define STYLE_STRUCT(name_) \
- MOZ_ASSERT(!!(structsFound & NS_STYLE_INHERIT_BIT(name_)) == \
+ MOZ_ASSERT(!!(structsFound & STYLE_STRUCT_BIT(name_)) == \
(PEEK(name_) != nullptr), \
"PeekStyleData results must not change in the middle of " \
"difference calculation.");
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
#endif
// Note that we do not check whether this->RelevantLinkVisited() !=
@@ -217,17 +183,17 @@ ComputedStyle::CalcStyleDifference(Compu
// things that can depend on :visited) for the properties on which we
// call GetVisitedDependentColor.
ComputedStyle* thisVis = GetStyleIfVisited();
ComputedStyle* otherVis = aNewContext->GetStyleIfVisited();
if (!thisVis != !otherVis) {
// One style has a style-if-visited and the other doesn't.
// Presume a difference.
#define STYLE_STRUCT(name_, fields_) \
- *aEqualStructs &= ~NS_STYLE_INHERIT_BIT(name_);
+ *aEqualStructs &= ~STYLE_STRUCT_BIT(name_);
#include "nsCSSVisitedDependentPropList.h"
#undef STYLE_STRUCT
hint |= nsChangeHint_RepaintFrame;
} else if (thisVis) {
// Both styles have a style-if-visited.
bool change = false;
// NB: Calling Peek on |this|, not |thisVis|, since callers may look
@@ -238,17 +204,17 @@ ComputedStyle::CalcStyleDifference(Compu
#define STYLE_FIELD(name_) thisVisStruct->name_ != otherVisStruct->name_
#define STYLE_STRUCT(name_, fields_) \
if (PEEK(name_)) { \
const nsStyle##name_* thisVisStruct = \
thisVis->ThreadsafeStyle##name_(); \
const nsStyle##name_* otherVisStruct = \
otherVis->ThreadsafeStyle##name_(); \
if (MOZ_FOR_EACH_SEPARATED(STYLE_FIELD, (||), (), fields_)) { \
- *aEqualStructs &= ~NS_STYLE_INHERIT_BIT(name_); \
+ *aEqualStructs &= ~STYLE_STRUCT_BIT(name_); \
change = true; \
} \
}
#include "nsCSSVisitedDependentPropList.h"
#undef STYLE_STRUCT
#undef STYLE_FIELD
if (change) {
@@ -394,42 +360,38 @@ ComputedStyle::CombineVisitedColors(nsco
nscolor colorColor = aColors[set.colorIndex];
nscolor alphaColor = aColors[set.alphaIndex];
return NS_RGBA(NS_GET_R(colorColor), NS_GET_G(colorColor),
NS_GET_B(colorColor), NS_GET_A(alphaColor));
}
#ifdef DEBUG
/* static */ const char*
-ComputedStyle::StructName(nsStyleStructID aSID)
+ComputedStyle::StructName(StyleStructID aSID)
{
switch (aSID) {
#define STYLE_STRUCT(name_) \
- case eStyleStruct_##name_: \
+ case StyleStructID::name_: \
return #name_;
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
default:
return "Unknown";
}
}
-/* static */ bool
-ComputedStyle::LookupStruct(const nsACString& aName, nsStyleStructID& aResult)
+/* static */ Maybe<StyleStructID>
+ComputedStyle::LookupStruct(const nsACString& aName)
{
- if (false)
- ;
#define STYLE_STRUCT(name_) \
- else if (aName.EqualsLiteral(#name_)) \
- aResult = eStyleStruct_##name_;
+ if (aName.EqualsLiteral(#name_)) \
+ return Some(StyleStructID::name_);
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
- else
- return false;
- return true;
+ return Nothing();
}
#endif // DEBUG
ComputedStyle*
ComputedStyle::GetCachedLazyPseudoStyle(CSSPseudoElementType aPseudo) const
{
MOZ_ASSERT(aPseudo != CSSPseudoElementType::NotPseudo &&
aPseudo != CSSPseudoElementType::InheritingAnonBox &&
--- a/layout/style/ComputedStyle.h
+++ b/layout/style/ComputedStyle.h
@@ -16,48 +16,18 @@
#include "mozilla/ServoComputedData.h"
#include "mozilla/ServoTypes.h"
#include "mozilla/ServoUtils.h"
#include "mozilla/StyleComplexColor.h"
#include "mozilla/CachedInheritingStyles.h"
#include "nsCSSAnonBoxes.h"
#include "nsCSSPseudoElements.h"
-// Includes nsStyleStructID.
#include "nsStyleStructFwd.h"
-// Bits for each struct.
-// NS_STYLE_INHERIT_BIT defined in nsStyleStructFwd.h
-#define NS_STYLE_INHERIT_MASK 0x0007fffff
-
-// Bits for inherited structs.
-#define NS_STYLE_INHERITED_STRUCT_MASK \
- ((nsStyleStructID_size_t(1) << nsStyleStructID_Inherited_Count) - 1)
-// Bits for reset structs.
-#define NS_STYLE_RESET_STRUCT_MASK \
- (((nsStyleStructID_size_t(1) << nsStyleStructID_Reset_Count) - 1) \
- << nsStyleStructID_Inherited_Count)
-
-// Additional bits for ComputedStyle's mBits:
-// (free bit) 0x000800000
-// See ComputedStyle::HasTextDecorationLines
-#define NS_STYLE_HAS_TEXT_DECORATION_LINES 0x001000000
-// See ComputedStyle::HasPseudoElementData.
-#define NS_STYLE_HAS_PSEUDO_ELEMENT_DATA 0x002000000
-// See ComputedStyle::RelevantLinkIsVisited
-#define NS_STYLE_RELEVANT_LINK_VISITED 0x004000000
-// See ComputedStyle::IsStyleIfVisited
-#define NS_STYLE_IS_STYLE_IF_VISITED 0x008000000
-// See ComputedStyle::ShouldSuppressLineBreak
-#define NS_STYLE_SUPPRESS_LINEBREAK 0x080000000
-// See ComputedStyle::IsTextCombined
-#define NS_STYLE_IS_TEXT_COMBINED 0x800000000
-// See ComputedStyle::GetPseudoEnum
-#define NS_STYLE_CONTEXT_TYPE_SHIFT 37
-
class nsAtom;
enum nsChangeHint : uint32_t;
class nsIPresShell;
class nsPresContext;
class nsWindowSizes;
#define STYLE_STRUCT(name_) struct nsStyle##name_;
#include "nsStyleStructList.h"
@@ -88,18 +58,30 @@ class ComputedStyle;
* ComputedStyles are reference counted. References are generally held by:
* 1. the |nsIFrame|s that are using the ComputedStyle and
* 2. any *child* ComputedStyle (this might be the reverse of
* expectation, but it makes sense in this case)
*
* FIXME(emilio): This comment is somewhat outdated now.
*/
+enum class ComputedStyleBit : uint8_t
+{
+ HasTextDecorationLines = 1 << 0,
+ HasPseudoElementData = 1 << 1,
+ SuppressLineBreak = 1 << 2,
+ IsTextCombined = 1 << 3,
+ RelevantLinkVisited = 1 << 4,
+};
+
+MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ComputedStyleBit)
+
class ComputedStyle
{
+ using Bit = ComputedStyleBit;
public:
ComputedStyle(nsPresContext* aPresContext,
nsAtom* aPseudoTag,
CSSPseudoElementType aPseudoType,
ServoComputedDataForgotten aComputedValues);
// FIXME(emilio, bug 548397): This will need to go away. Don't add new callers
// of this methed.
@@ -139,19 +121,19 @@ public:
bool IsLazilyCascadedPseudoElement() const
{
return IsPseudoElement() &&
!nsCSSPseudoElements::IsEagerlyCascadedInServo(GetPseudoType());
}
nsAtom* GetPseudo() const { return mPseudoTag; }
- mozilla::CSSPseudoElementType GetPseudoType() const {
- return static_cast<mozilla::CSSPseudoElementType>(
- mBits >> NS_STYLE_CONTEXT_TYPE_SHIFT);
+ mozilla::CSSPseudoElementType GetPseudoType() const
+ {
+ return mPseudoType;
}
bool IsInheritingAnonBox() const {
return GetPseudoType() == mozilla::CSSPseudoElementType::InheritingAnonBox;
}
bool IsNonInheritingAnonBox() const {
return GetPseudoType() == mozilla::CSSPseudoElementType::NonInheritingAnonBox;
@@ -171,50 +153,55 @@ public:
bool IsPseudoElement() const { return mPseudoTag && !IsAnonBox(); }
// Does this ComputedStyle or any of its ancestors have text
// decoration lines?
// Differs from nsStyleTextReset::HasTextDecorationLines, which tests
// only the data for a single context.
bool HasTextDecorationLines() const
- { return !!(mBits & NS_STYLE_HAS_TEXT_DECORATION_LINES); }
+ {
+ return bool(mBits & Bit::HasTextDecorationLines);
+ }
// Whether any line break inside should be suppressed? If this returns
// true, the line should not be broken inside, which means inlines act
// as if nowrap is set, <br> is suppressed, and blocks are inlinized.
// This bit is propogated to all children of line partitipants. It is
// currently used by ruby to make its content frames unbreakable.
// NOTE: for nsTextFrame, use nsTextFrame::ShouldSuppressLineBreak()
// instead of this method.
bool ShouldSuppressLineBreak() const
- { return !!(mBits & NS_STYLE_SUPPRESS_LINEBREAK); }
+ {
+ return bool(mBits & Bit::SuppressLineBreak);
+ }
// Is this horizontal-in-vertical (tate-chu-yoko) text? This flag is
// only set on ComputedStyles whose pseudo is nsCSSAnonBoxes::mozText.
bool IsTextCombined() const
- { return !!(mBits & NS_STYLE_IS_TEXT_COMBINED); }
+ {
+ return bool(mBits & Bit::IsTextCombined);
+ }
// Does this ComputedStyle represent the style for a pseudo-element or
// inherit data from such a ComputedStyle? Whether this returns true
// is equivalent to whether it or any of its ancestors returns
// non-null for IsPseudoElement().
bool HasPseudoElementData() const
- { return !!(mBits & NS_STYLE_HAS_PSEUDO_ELEMENT_DATA); }
+ {
+ return bool(mBits & Bit::HasPseudoElementData);
+ }
// Is the only link whose visitedness is allowed to influence the
// style of the node this ComputedStyle is for (which is that element
// or its nearest ancestor that is a link) visited?
bool RelevantLinkVisited() const
- { return !!(mBits & NS_STYLE_RELEVANT_LINK_VISITED); }
-
- // Is this ComputedStyle the GetStyleIfVisited() for some other style
- // context?
- bool IsStyleIfVisited() const
- { return !!(mBits & NS_STYLE_IS_STYLE_IF_VISITED); }
+ {
+ return bool(mBits & Bit::RelevantLinkVisited);
+ }
ComputedStyle* GetCachedInheritingAnonBoxStyle(nsAtom* aAnonBox) const
{
MOZ_ASSERT(nsCSSAnonBoxes::IsInheritingAnonBox(aAnonBox));
return mCachedInheritingStyles.Lookup(aAnonBox);
}
void SetCachedInheritedAnonBoxStyle(nsAtom* aAnonBox, ComputedStyle* aStyle)
@@ -243,18 +230,16 @@ public:
// support state (like :hover). So we just avoid sharing in those cases.
if (nsCSSPseudoElements::PseudoElementSupportsUserActionState(aStyle->GetPseudoType())) {
return;
}
mCachedInheritingStyles.Insert(aStyle);
}
- void AddStyleBit(const uint64_t& aBit) { mBits |= aBit; }
-
/**
* Define typesafe getter functions for each style struct by
* preprocessing the list of style structs. These functions are the
* preferred way to get style data. The macro creates functions like:
* const nsStyleBorder* StyleBorder();
* const nsStyleColor* StyleColor();
*/
#define STYLE_STRUCT(name_) \
@@ -321,51 +306,58 @@ public:
/**
* aColors should be a two element array of nscolor in which the first
* color is the unvisited color and the second is the visited color.
*
* Combine the R, G, and B components of whichever of aColors should
* be used based on aLinkIsVisited with the A component of aColors[0].
*/
- static nscolor CombineVisitedColors(nscolor *aColors,
- bool aLinkIsVisited);
+ static nscolor CombineVisitedColors(nscolor* aColors, bool aLinkIsVisited);
/**
* Start the background image loads for this ComputedStyle.
*/
inline void StartBackgroundImageLoads();
- static uint32_t GetBitForSID(const nsStyleStructID aSID) { return 1 << aSID; }
-
#ifdef DEBUG
void List(FILE* out, int32_t aIndent);
- static const char* StructName(nsStyleStructID aSID);
- static bool LookupStruct(const nsACString& aName, nsStyleStructID& aResult);
+ static const char* StructName(StyleStructID aSID);
+ static Maybe<StyleStructID> LookupStruct(const nsACString& aName);
#endif
/**
* Makes this context match |aOther| in terms of which style structs have
* been resolved.
*/
inline void ResolveSameStructsAs(const ComputedStyle* aOther);
// The |aCVsSize| outparam on this function is where the actual CVs size
// value is added. It's done that way because the callers know which value
// the size should be added to.
void AddSizeOfIncludingThis(nsWindowSizes& aSizes, size_t* aCVsSize) const;
protected:
+ bool HasRequestedStruct(StyleStructID aID) const
+ {
+ return mStructsRequested & StyleStructConstants::BitFor(aID);
+ }
+
+ void SetRequestedStruct(StyleStructID aID)
+ {
+ mStructsRequested |= StyleStructConstants::BitFor(aID);
+ }
+
// Needs to be friend so that it can call the destructor without making it
// public.
friend void ::Gecko_ComputedStyle_Destroy(ComputedStyle*);
~ComputedStyle() = default;
- nsPresContext* mPresContext;
+ nsPresContext* const mPresContext;
ServoComputedData mSource;
// A cache of anonymous box and lazy pseudo styles inheriting from this style.
CachedInheritingStyles mCachedInheritingStyles;
// Helper functions for GetStyle* and PeekStyle*
#define STYLE_STRUCT_INHERITED(name_) \
@@ -376,21 +368,19 @@ protected:
const nsStyle##name_ * DoGetStyle##name_();
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
// If this ComputedStyle is for a pseudo-element or anonymous box,
// the relevant atom.
- RefPtr<nsAtom> mPseudoTag;
+ const RefPtr<nsAtom> mPseudoTag;
- // mBits stores a number of things:
- // - It records (using the style struct bits) which structs have
- // been requested on this ComputedStyle.
- // - It also stores the additional bits listed at the top of
- // nsStyleStruct.h.
- uint64_t mBits;
+ // A bitfield with the structs that have been requested so far.
+ uint32_t mStructsRequested = 0;
+ const Bit mBits;
+ const CSSPseudoElementType mPseudoType;
};
} // namespace mozilla
#endif
--- a/layout/style/ComputedStyleInlines.h
+++ b/layout/style/ComputedStyleInlines.h
@@ -36,48 +36,48 @@ const nsStyle##name_ * ComputedStyle::Pe
return DoGetStyle##name_<false>(); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
// Helper functions for GetStyle* and PeekStyle*
#define STYLE_STRUCT_INHERITED(name_) \
template<bool aComputeData> \
-const nsStyle##name_ * ComputedStyle::DoGetStyle##name_() { \
- const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_)); \
+const nsStyle##name_* ComputedStyle::DoGetStyle##name_() { \
+ const auto kStructID = StyleStructID::name_; \
+ const bool needToCompute = !HasRequestedStruct(kStructID); \
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
- \
const nsStyle##name_* data = ComputedData()->GetStyle##name_(); \
- \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
MOZ_ASSERT(NS_IsMainThread()); \
MOZ_ASSERT(!mozilla::IsInServoTraversal()); \
const_cast<nsStyle##name_*>(data)->FinishStyle(mPresContext, nullptr); \
/* the ComputedStyle owns the struct */ \
- AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
+ SetRequestedStruct(kStructID); \
} \
return data; \
}
#define STYLE_STRUCT_RESET(name_) \
template<bool aComputeData> \
const nsStyle##name_ * ComputedStyle::DoGetStyle##name_() { \
- const bool needToCompute = !(mBits & NS_STYLE_INHERIT_BIT(name_)); \
+ const auto kStructID = StyleStructID::name_; \
+ const bool needToCompute = !HasRequestedStruct(kStructID); \
if (!aComputeData && needToCompute) { \
return nullptr; \
} \
const nsStyle##name_* data = ComputedData()->GetStyle##name_(); \
/* perform any remaining main thread work on the struct */ \
if (needToCompute) { \
const_cast<nsStyle##name_*>(data)->FinishStyle(mPresContext, nullptr); \
/* the ComputedStyle owns the struct */ \
- AddStyleBit(NS_STYLE_INHERIT_BIT(name_)); \
+ SetRequestedStruct(kStructID); \
} \
return data; \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_RESET
#undef STYLE_STRUCT_INHERITED
void
@@ -86,29 +86,27 @@ ComputedStyle::StartBackgroundImageLoads
// Just get our background struct; that should do the trick
StyleBackground();
}
void
ComputedStyle::ResolveSameStructsAs(const ComputedStyle* aOther)
{
// Only resolve structs that are not already resolved in this struct.
- uint64_t ourBits = mBits & NS_STYLE_INHERIT_MASK;
- uint64_t otherBits = aOther->mBits & NS_STYLE_INHERIT_MASK;
- uint64_t newBits = otherBits & ~ourBits & NS_STYLE_INHERIT_MASK;
+ auto newBits = aOther->mStructsRequested & ~mStructsRequested;
#define STYLE_STRUCT(name_) \
if (nsStyle##name_::kHasFinishStyle && \
- (newBits & NS_STYLE_INHERIT_BIT(name_))) { \
+ (newBits & STYLE_STRUCT_BIT(name_))) { \
const nsStyle##name_* data = ComputedData()->GetStyle##name_(); \
const nsStyle##name_* oldData = aOther->ComputedData()->GetStyle##name_(); \
const_cast<nsStyle##name_*>(data)->FinishStyle(mPresContext, oldData); \
}
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
- mBits |= newBits;
+ mStructsRequested |= newBits;
}
} // namespace mozilla
#endif // ComputedStyleInlines_h
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -688,17 +688,17 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_
ComputedStyleBorrowedOrNull parent_style_or_null,
nsAtom* pseudo_tag,
RawServoStyleSetBorrowed set)
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ComputedStyleStrong,
RawServoStyleSetBorrowed set,
nsAtom* pseudo_tag,
ComputedStyleBorrowedOrNull parent_style,
mozilla::InheritTarget target)
-SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint64_t,
+SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleBits, uint8_t,
ComputedStyleBorrowed values)
SERVO_BINDING_FUNC(Servo_ComputedValues_EqualCustomProperties, bool,
ServoComputedDataBorrowed first,
ServoComputedDataBorrowed second)
// Gets the source style rules for the computed values. This returns
// the result via rules, which would include a list of unowned pointers
// to RawServoStyleRule.
SERVO_BINDING_FUNC(Servo_ComputedValues_GetStyleRuleList, void,
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -345,28 +345,25 @@ Gecko_CalcStyleDifference(ComputedStyleB
ComputedStyleBorrowed aNewStyle,
bool* aAnyStyleStructChanged,
bool* aOnlyResetStructsChanged)
{
MOZ_ASSERT(aOldStyle);
MOZ_ASSERT(aNewStyle);
uint32_t equalStructs;
- nsChangeHint result = const_cast<mozilla::ComputedStyle*>(aOldStyle)->
- CalcStyleDifference(
- const_cast<mozilla::ComputedStyle*>(aNewStyle),
- &equalStructs);
-
- *aAnyStyleStructChanged = equalStructs != NS_STYLE_INHERIT_MASK;
-
- const uint32_t kInheritStructsMask =
- NS_STYLE_INHERIT_MASK & ~NS_STYLE_RESET_STRUCT_MASK;
-
+ nsChangeHint result = const_cast<ComputedStyle*>(aOldStyle)->
+ CalcStyleDifference(const_cast<ComputedStyle*>(aNewStyle), &equalStructs);
+
+ *aAnyStyleStructChanged =
+ equalStructs != StyleStructConstants::kAllStructsMask;
+
+ const auto kInheritedStructsMask = StyleStructConstants::kInheritedStructsMask;
*aOnlyResetStructsChanged =
- (equalStructs & kInheritStructsMask) == kInheritStructsMask;
+ (equalStructs & kInheritedStructsMask) == kInheritedStructsMask;
return result;
}
const ServoElementSnapshot*
Gecko_GetElementSnapshot(const ServoElementSnapshotTable* aTable,
const Element* aElement)
{
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -40,20 +40,16 @@
#include "nsIURI.h"
#include "nsIDocument.h"
#include <algorithm>
#include "ImageLoader.h"
using namespace mozilla;
using namespace mozilla::dom;
-static_assert((((1 << nsStyleStructID_Length) - 1) &
- ~(NS_STYLE_INHERIT_MASK)) == 0,
- "Not enough bits in NS_STYLE_INHERIT_MASK");
-
/* static */ const int32_t nsStyleGridLine::kMinLine;
/* static */ const int32_t nsStyleGridLine::kMaxLine;
// We set the size limit of style structs to 504 bytes so that when they
// are allocated by Servo side with Arc, the total size doesn't exceed
// 512 bytes, which minimizes allocator slop.
static constexpr size_t kStyleStructSizeLimit = 504;
#define STYLE_STRUCT(name_) \
--- a/layout/style/nsStyleStructFwd.h
+++ b/layout/style/nsStyleStructFwd.h
@@ -6,58 +6,78 @@
/*
* Forward declarations to avoid including all of nsStyleStruct.h.
*/
#ifndef nsStyleStructFwd_h_
#define nsStyleStructFwd_h_
-enum nsStyleStructID {
+namespace mozilla {
+enum class StyleStructID : uint32_t {
/*
* Define the constants eStyleStruct_Font, etc.
*
* The C++ standard, section 7.2, guarantees that enums begin with 0 and
* increase by 1.
*
- * We separate the IDs of Reset and Inherited structs so that we can use
- * the IDs as indices (offset by nsStyleStructID_*_Start) into arrays of
- * one type or the other.
+ * Note that we rely on the inherited structs being before the rest in
+ * ComputedStyle.
*/
-
-nsStyleStructID_None = -1,
-nsStyleStructID_Inherited_Start = 0,
-// a dummy value so the value after it is the same as ..._Inherited_Start
-nsStyleStructID_DUMMY1 = nsStyleStructID_Inherited_Start - 1,
-
-#define STYLE_STRUCT_INHERITED(name) eStyleStruct_##name,
+#define STYLE_STRUCT_INHERITED(name) name,
#define STYLE_STRUCT_RESET(name)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_INHERITED
#undef STYLE_STRUCT_RESET
-nsStyleStructID_Reset_Start,
-// a dummy value so the value after it is the same as ..._Reset_Start
-nsStyleStructID_DUMMY2 = nsStyleStructID_Reset_Start - 1,
-
-#define STYLE_STRUCT_RESET(name) eStyleStruct_##name,
+#define STYLE_STRUCT_RESET(name) name,
#define STYLE_STRUCT_INHERITED(name)
#include "nsStyleStructList.h"
#undef STYLE_STRUCT_INHERITED
#undef STYLE_STRUCT_RESET
-
-// one past the end; length of 0-based list
-nsStyleStructID_Length,
-
-nsStyleStructID_Inherited_Count =
- nsStyleStructID_Reset_Start - nsStyleStructID_Inherited_Start,
-nsStyleStructID_Reset_Count =
- nsStyleStructID_Length - nsStyleStructID_Reset_Start,
-
};
+struct StyleStructConstants
+{
+ static const uint32_t kStyleStructCount =
+#define STYLE_STRUCT_RESET(name) 1 +
+#define STYLE_STRUCT_INHERITED(name) 1 +
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT_INHERITED
+#undef STYLE_STRUCT_RESET
+ 0;
+
+ static const uint32_t kInheritedStyleStructCount =
+#define STYLE_STRUCT_RESET(name)
+#define STYLE_STRUCT_INHERITED(name) 1 +
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT_INHERITED
+#undef STYLE_STRUCT_RESET
+ 0;
+
+ static const uint32_t kResetStyleStructCount =
+#define STYLE_STRUCT_RESET(name) 1 +
+#define STYLE_STRUCT_INHERITED(name)
+#include "nsStyleStructList.h"
+#undef STYLE_STRUCT_INHERITED
+#undef STYLE_STRUCT_RESET
+ 0;
+
+ static_assert(kStyleStructCount <= 32, "Bitmasks must be bigger!");
+
+ static const uint32_t kAllStructsMask = (1 << kStyleStructCount) - 1;
+ static const uint32_t kInheritedStructsMask = (1 << kInheritedStyleStructCount) - 1;
+ static const uint32_t kResetStructsMask = kAllStructsMask & (~kInheritedStructsMask);
+
+ static uint32_t BitFor(StyleStructID aID)
+ {
+ return 1 << static_cast<uint32_t>(aID);
+ }
+};
+
+} // namespace mozilla
+
// A bit corresponding to each struct ID
-#define NS_STYLE_INHERIT_BIT(sid_) (1 << uint64_t(eStyleStruct_##sid_))
-
-typedef decltype(nsStyleStructID(0) + nsStyleStructID(0)) nsStyleStructID_size_t;
+#define STYLE_STRUCT_BIT(name_) \
+ mozilla::StyleStructConstants::BitFor(mozilla::StyleStructID::name_)
#endif /* nsStyleStructFwd_h_ */
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -36,17 +36,16 @@ use gecko_bindings::bindings::Gecko_SetL
use gecko_bindings::bindings::Gecko_SetListStyleImageImageValue;
use gecko_bindings::bindings::Gecko_SetNullImageValue;
use gecko_bindings::bindings::{Gecko_ResetFilters, Gecko_CopyFiltersFrom};
use gecko_bindings::bindings::RawGeckoPresContextBorrowed;
use gecko_bindings::structs;
use gecko_bindings::structs::nsCSSPropertyID;
use gecko_bindings::structs::mozilla::CSSPseudoElementType;
use gecko_bindings::structs::mozilla::CSSPseudoElementType_InheritingAnonBox;
-use gecko_bindings::structs::root::NS_STYLE_CONTEXT_TYPE_SHIFT;
use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut};
use gecko_bindings::sugar::refptr::RefPtr;
use gecko::values::convert_nscolor_to_rgba;
use gecko::values::convert_rgba_to_nscolor;
use gecko::values::GeckoStyleCoordConvertible;
use gecko::values::round_border_to_device_pixels;
use logical_geometry::WritingMode;
use media_queries::Device;
@@ -132,22 +131,22 @@ impl ComputedValues {
if atom.is_null() {
return None;
}
let atom = unsafe { Atom::from_raw(atom) };
PseudoElement::from_atom(&atom)
}
+ #[inline]
fn get_pseudo_type(&self) -> CSSPseudoElementType {
- let bits = (self.0).mBits;
- let our_type = bits >> NS_STYLE_CONTEXT_TYPE_SHIFT;
- unsafe { transmute(our_type as u8) }
- }
-
+ self.0.mPseudoType
+ }
+
+ #[inline]
pub fn is_anon_box(&self) -> bool {
let our_type = self.get_pseudo_type();
return our_type == CSSPseudoElementType_InheritingAnonBox ||
our_type == CSSPseudoElementType::NonInheritingAnonBox;
}
/// Returns true if the display property is changed from 'none' to others.
pub fn is_display_property_changed_from_none(
@@ -2980,17 +2979,16 @@ fn static_assert() {
<%def name="impl_animation_keyword(ident, gecko_ffi_name, keyword, cast_type='u8')">
#[allow(non_snake_case)]
pub fn set_animation_${ident}<I>(&mut self, v: I)
where I: IntoIterator<Item = longhands::animation_${ident}::computed_value::single_value::T>,
I::IntoIter: ExactSizeIterator + Clone
{
use properties::longhands::animation_${ident}::single_value::computed_value::T as Keyword;
- use gecko_bindings::structs;
let v = v.into_iter();
debug_assert_ne!(v.len(), 0);
let input_len = v.len();
self.gecko.mAnimations.ensure_len(input_len);
self.gecko.mAnimation${gecko_ffi_name}Count = input_len as u32;
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -3092,35 +3092,35 @@ pub unsafe extern "C" fn Servo_ComputedV
if for_text {
StyleAdjuster::new(&mut style).adjust_for_text();
}
style.build().into()
}
#[no_mangle]
-pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ComputedStyleBorrowed) -> u64 {
+pub extern "C" fn Servo_ComputedValues_GetStyleBits(values: ComputedStyleBorrowed) -> u8 {
use style::properties::computed_value_flags::ComputedValueFlags;
// FIXME(emilio): We could do this more efficiently I'm quite sure.
let flags = values.flags;
let mut result = 0;
if flags.contains(ComputedValueFlags::IS_RELEVANT_LINK_VISITED) {
- result |= structs::NS_STYLE_RELEVANT_LINK_VISITED as u64;
+ result |= structs::ComputedStyleBit_RelevantLinkVisited;
}
if flags.contains(ComputedValueFlags::HAS_TEXT_DECORATION_LINES) {
- result |= structs::NS_STYLE_HAS_TEXT_DECORATION_LINES as u64;
+ result |= structs::ComputedStyleBit_HasTextDecorationLines;
}
if flags.contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK) {
- result |= structs::NS_STYLE_SUPPRESS_LINEBREAK as u64;
+ result |= structs::ComputedStyleBit_SuppressLineBreak;
}
if flags.contains(ComputedValueFlags::IS_TEXT_COMBINED) {
- result |= structs::NS_STYLE_IS_TEXT_COMBINED as u64;
+ result |= structs::ComputedStyleBit_IsTextCombined;
}
if flags.contains(ComputedValueFlags::IS_IN_PSEUDO_ELEMENT_SUBTREE) {
- result |= structs::NS_STYLE_HAS_PSEUDO_ELEMENT_DATA as u64;
+ result |= structs::ComputedStyleBit_HasPseudoElementData;
}
result
}
#[no_mangle]
pub extern "C" fn Servo_ComputedValues_SpecifiesAnimationsOrTransitions(
values: ComputedStyleBorrowed,
) -> bool {