Bug 1339629 Part 9: Uplift EnsureUniqueInnerOnCSSSheets and SetNeedsRestyleAfterEnsureUniqueInner into StyleSetHandle, and eliminate CSSStyleSheet::EnsureUniqueInner.
MozReview-Commit-ID: LH7vTKUmuv8
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2376,24 +2376,17 @@ nsPresContext::NotifyMissingFonts()
if (mMissingFonts) {
mMissingFonts->Flush();
}
}
void
nsPresContext::EnsureSafeToHandOutCSSRules()
{
- nsStyleSet* styleSet = mShell->StyleSet()->GetAsGecko();
- if (!styleSet) {
- // ServoStyleSets do not need to handle copy-on-write style sheet
- // innards like with CSSStyleSheets.
- return;
- }
-
- if (!styleSet->EnsureUniqueInnerOnCSSSheets()) {
+ if (!mShell->StyleSet()->EnsureUniqueInnerOnCSSSheets()) {
// Nothing to do.
return;
}
RebuildAllStyleData(nsChangeHint(0), eRestyle_Subtree);
}
void
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -564,29 +564,16 @@ css::Rule*
CSSStyleSheet::GetStyleRuleAt(int32_t aIndex) const
{
// Important: If this function is ever made scriptable, we must add
// a security check here. See GetCssRules below for an example.
return Inner()->mOrderedRules.SafeObjectAt(aIndex);
}
void
-CSSStyleSheet::EnsureUniqueInner()
-{
- StyleSheet::EnsureUniqueInner();
-
- // let our containing style sets know that if we call
- // nsPresContext::EnsureSafeToHandOutCSSRules we will need to restyle the
- // document
- for (StyleSetHandle setHandle : mStyleSets) {
- setHandle->AsGecko()->SetNeedsRestyleAfterEnsureUniqueInner();
- }
-}
-
-void
CSSStyleSheet::AppendAllChildSheets(nsTArray<CSSStyleSheet*>& aArray)
{
for (StyleSheet* child = GetFirstChild(); child;
child = child->mNext) {
aArray.AppendElement(child->AsGecko());
}
}
--- a/layout/style/CSSStyleSheet.h
+++ b/layout/style/CSSStyleSheet.h
@@ -135,18 +135,16 @@ public:
nsresult AddRuleProcessor(nsCSSRuleProcessor* aProcessor);
nsresult DropRuleProcessor(nsCSSRuleProcessor* aProcessor);
// nsICSSLoaderObserver interface
NS_IMETHOD StyleSheetLoaded(StyleSheet* aSheet, bool aWasAlternate,
nsresult aStatus) override;
- void EnsureUniqueInner() override;
-
// Append all of this sheet's child sheets to aArray.
void AppendAllChildSheets(nsTArray<CSSStyleSheet*>& aArray);
bool UseForPresentation(nsPresContext* aPresContext,
nsMediaQueryResultCacheKey& aKey) const;
nsresult ReparseSheet(const nsAString& aInput);
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -38,16 +38,17 @@ static inline uint64_t UniqueIDForSheet(
return reinterpret_cast<uint64_t>(aSheet);
}
ServoStyleSet::ServoStyleSet()
: mPresContext(nullptr)
, mAllowResolveStaleStyles(false)
, mAuthorStyleDisabled(false)
, mStylistState(StylistState::NotDirty)
+ , mNeedsRestyleAfterEnsureUniqueInner(false)
{
}
ServoStyleSet::~ServoStyleSet()
{
for (auto& sheetArray : mSheets) {
for (auto& sheet : sheetArray) {
sheet->DropStyleSet(this);
@@ -978,16 +979,27 @@ ServoStyleSet::ComputeAnimationValue(
const ServoComputedValuesWithParent& aComputedValues)
{
return Servo_AnimationValue_Compute(aDeclarations,
aComputedValues.mCurrentStyle,
aComputedValues.mParentStyle,
mRawSet.get()).Consume();
}
+bool
+ServoStyleSet::EnsureUniqueInnerOnCSSSheets()
+{
+ // This is a stub until more of the functionality of nsStyleSet is
+ // replicated for Servo here.
+
+ bool res = mNeedsRestyleAfterEnsureUniqueInner;
+ mNeedsRestyleAfterEnsureUniqueInner = false;
+ return res;
+}
+
void
ServoStyleSet::RebuildData()
{
ClearNonInheritingStyleContexts();
Servo_StyleSet_RebuildData(mRawSet.get());
mStylistState = StylistState::NotDirty;
}
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -350,16 +350,26 @@ public:
// mutex is locked. If we need to use them in other situations during
// a traversal, we should assert that we've taken appropriate
// synchronization measures.
AssertIsMainThreadOrServoFontMetricsLocked();
mPostTraversalTasks.AppendElement(aTask);
}
+ // Returns true if a restyle of the document is needed due to cloning
+ // sheet inners.
+ bool EnsureUniqueInnerOnCSSSheets();
+
+ // Called by StyleSheet::EnsureUniqueInner to let us know it cloned
+ // its inner.
+ void SetNeedsRestyleAfterEnsureUniqueInner() {
+ mNeedsRestyleAfterEnsureUniqueInner = true;
+ }
+
private:
// On construction, sets sInServoTraversal to the given ServoStyleSet.
// On destruction, clears sInServoTraversal and calls RunPostTraversalTasks.
class MOZ_STACK_CLASS AutoSetInServoTraversal
{
public:
explicit AutoSetInServoTraversal(ServoStyleSet* aSet)
: mSet(aSet)
@@ -501,16 +511,18 @@ private:
nsPresContext* mPresContext;
UniquePtr<RawServoStyleSet> mRawSet;
EnumeratedArray<SheetType, SheetType::Count,
nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
bool mAllowResolveStaleStyles;
bool mAuthorStyleDisabled;
StylistState mStylistState;
+ bool mNeedsRestyleAfterEnsureUniqueInner;
+
// Stores pointers to our cached style contexts for non-inheriting anonymous
// boxes.
EnumeratedArray<nsCSSAnonBoxes::NonInheriting,
nsCSSAnonBoxes::NonInheriting::_Count,
RefPtr<nsStyleContext>> mNonInheritingStyleContexts;
// Tasks to perform after a traversal, back on the main thread.
//
--- a/layout/style/StyleSetHandle.h
+++ b/layout/style/StyleSetHandle.h
@@ -172,16 +172,19 @@ public:
EventStates aStateMask);
inline void RootStyleContextAdded();
inline void RootStyleContextRemoved();
inline bool AppendFontFaceRules(nsTArray<nsFontFaceRuleContainer>& aArray);
inline nsCSSCounterStyleRule* CounterStyleRuleForName(nsIAtom* aName);
+ inline bool EnsureUniqueInnerOnCSSSheets();
+ inline void SetNeedsRestyleAfterEnsureUniqueInner();
+
private:
// Stores a pointer to an nsStyleSet or a ServoStyleSet. The least
// significant bit is 0 for the former, 1 for the latter. This is
// valid as the least significant bit will never be used for a pointer
// value on platforms we care about.
uintptr_t mValue;
};
--- a/layout/style/StyleSetHandleInlines.h
+++ b/layout/style/StyleSetHandleInlines.h
@@ -291,13 +291,25 @@ AppendFontFaceRules(nsTArray<nsFontFaceR
}
nsCSSCounterStyleRule*
StyleSetHandle::Ptr::CounterStyleRuleForName(nsIAtom* aName)
{
FORWARD(CounterStyleRuleForName, (aName));
}
+bool
+StyleSetHandle::Ptr::EnsureUniqueInnerOnCSSSheets()
+{
+ FORWARD(EnsureUniqueInnerOnCSSSheets, ());
+}
+
+void
+StyleSetHandle::Ptr::SetNeedsRestyleAfterEnsureUniqueInner()
+{
+ FORWARD(SetNeedsRestyleAfterEnsureUniqueInner, ());
+}
+
} // namespace mozilla
#undef FORWARD
#endif // mozilla_StyleSetHandleInlines_h
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -444,16 +444,23 @@ StyleSheet::EnsureUniqueInner()
StyleSheetInfo* clone = mInner->CloneFor(this);
MOZ_ASSERT(clone);
mInner->RemoveSheet(this);
mInner = clone;
// Ensure we're using the new rules.
ClearRuleCascades();
+
+ // let our containing style sets know that if we call
+ // nsPresContext::EnsureSafeToHandOutCSSRules we will need to restyle the
+ // document
+ for (StyleSetHandle& setHandle : mStyleSets) {
+ setHandle->SetNeedsRestyleAfterEnsureUniqueInner();
+ }
}
// WebIDL CSSStyleSheet API
#define FORWARD_INTERNAL(method_, args_) \
if (IsServo()) { \
return AsServo()->method_ args_; \
} \
--- a/layout/style/StyleSheet.h
+++ b/layout/style/StyleSheet.h
@@ -117,17 +117,17 @@ public:
virtual already_AddRefed<StyleSheet> Clone(StyleSheet* aCloneParent,
css::ImportRule* aCloneOwnerRule,
nsIDocument* aCloneDocument,
nsINode* aCloneOwningNode) const = 0;
bool IsModified() const { return mDirty; }
- virtual void EnsureUniqueInner();
+ void EnsureUniqueInner();
// style sheet owner info
enum DocumentAssociationMode {
// OwnedByDocument means mDocument owns us (possibly via a chain of other
// stylesheets).
OwnedByDocument,
// NotOwnedByDocument means we're owned by something that might have a
// different lifetime than mDocument.
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -458,17 +458,17 @@ class nsStyleSet final
--mUnusedRuleNodeCount;
aNode->removeFrom(mUnusedRuleNodeList);
}
// Returns true if a restyle of the document is needed due to cloning
// sheet inners.
bool EnsureUniqueInnerOnCSSSheets();
- // Called by CSSStyleSheet::EnsureUniqueInner to let us know it cloned
+ // Called by StyleSheet::EnsureUniqueInner to let us know it cloned
// its inner.
void SetNeedsRestyleAfterEnsureUniqueInner() {
mNeedsRestyleAfterEnsureUniqueInner = true;
}
nsIStyleRule* InitialStyleRule();
bool HasRuleProcessorUsedByMultipleStyleSets(mozilla::SheetType aSheetType);