зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1798581 - Add optional page name argument to Servo_ComputedValues_GetForAnonymousBox and ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle r=emilio
This needs to bypass the cache on ServoStyleSet when looking up styles with named pages. We could possibly cache the last used named page style, which would avoid extra style calculations for multiple sequential pages with the same page name, but for now the cache is just ignored. Differential Revision: https://phabricator.services.mozilla.com/D160976
This commit is contained in:
Родитель
624091d13e
Коммит
f697f06790
|
@ -515,7 +515,7 @@ ServoStyleSet::ResolveInheritingAnonymousBoxStyle(PseudoStyleType aType,
|
|||
|
||||
if (!style) {
|
||||
style = Servo_ComputedValues_GetForAnonymousBox(aParentStyle, aType,
|
||||
mRawSet.get())
|
||||
mRawSet.get(), nullptr)
|
||||
.Consume();
|
||||
MOZ_ASSERT(style);
|
||||
if (aParentStyle) {
|
||||
|
@ -527,14 +527,29 @@ ServoStyleSet::ResolveInheritingAnonymousBoxStyle(PseudoStyleType aType,
|
|||
}
|
||||
|
||||
already_AddRefed<ComputedStyle>
|
||||
ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType) {
|
||||
ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType,
|
||||
const nsAtom* aPageName) {
|
||||
MOZ_ASSERT(PseudoStyle::IsNonInheritingAnonBox(aType));
|
||||
MOZ_ASSERT(!aPageName || aType == PseudoStyleType::pageContent,
|
||||
"page name should only be specified for pageContent");
|
||||
nsCSSAnonBoxes::NonInheriting type =
|
||||
nsCSSAnonBoxes::NonInheritingTypeForPseudoType(aType);
|
||||
RefPtr<ComputedStyle>& cache = mNonInheritingComputedStyles[type];
|
||||
if (cache) {
|
||||
RefPtr<ComputedStyle> retval = cache;
|
||||
return retval.forget();
|
||||
|
||||
// The empty atom is used to indicate no specified page name, and is not
|
||||
// usable as a page-rule selector. Changing this to null is a slight
|
||||
// optimization to avoid the Servo code from doing an unnecessary hashtable
|
||||
// lookup, and still use the style cache in this case.
|
||||
if (aPageName == nsGkAtoms::_empty) {
|
||||
aPageName = nullptr;
|
||||
}
|
||||
// Only use the cache if we are not doing a lookup for a named page style.
|
||||
RefPtr<ComputedStyle>* cache = nullptr;
|
||||
if (!aPageName) {
|
||||
cache = &mNonInheritingComputedStyles[type];
|
||||
if (*cache) {
|
||||
RefPtr<ComputedStyle> retval = *cache;
|
||||
return retval.forget();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateStylistIfNeeded();
|
||||
|
@ -547,11 +562,14 @@ ServoStyleSet::ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType aType) {
|
|||
"viewport needs fixup to handle blockifying it");
|
||||
|
||||
RefPtr<ComputedStyle> computedValues =
|
||||
Servo_ComputedValues_GetForAnonymousBox(nullptr, aType, mRawSet.get())
|
||||
Servo_ComputedValues_GetForAnonymousBox(nullptr, aType, mRawSet.get(),
|
||||
aPageName)
|
||||
.Consume();
|
||||
MOZ_ASSERT(computedValues);
|
||||
|
||||
cache = computedValues;
|
||||
if (cache) {
|
||||
*cache = computedValues;
|
||||
}
|
||||
return computedValues.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -236,7 +236,15 @@ class ServoStyleSet {
|
|||
// Get a ComputedStyle for an anonymous box. The pseudo type must be
|
||||
// a non-inheriting anon box.
|
||||
already_AddRefed<ComputedStyle> ResolveNonInheritingAnonymousBoxStyle(
|
||||
PseudoStyleType);
|
||||
PseudoStyleType aType) {
|
||||
return ResolveNonInheritingAnonymousBoxStyle(aType, nullptr);
|
||||
}
|
||||
|
||||
already_AddRefed<ComputedStyle> ResolvePageContentStyle(
|
||||
const nsAtom* aPageName) {
|
||||
return ResolveNonInheritingAnonymousBoxStyle(PseudoStyleType::pageContent,
|
||||
aPageName);
|
||||
}
|
||||
|
||||
already_AddRefed<ComputedStyle> ResolveXULTreePseudoStyle(
|
||||
dom::Element* aParentElement, nsCSSAnonBoxPseudoStaticAtom* aPseudoTag,
|
||||
|
@ -587,6 +595,9 @@ class ServoStyleSet {
|
|||
nsCSSAnonBoxes::NonInheriting::_Count, RefPtr<ComputedStyle>>
|
||||
mNonInheritingComputedStyles;
|
||||
|
||||
already_AddRefed<ComputedStyle> ResolveNonInheritingAnonymousBoxStyle(
|
||||
PseudoStyleType aType, const nsAtom* aPageName);
|
||||
|
||||
public:
|
||||
void PutCachedAnonymousContentStyles(
|
||||
AnonymousContentKey aKey, nsTArray<RefPtr<ComputedStyle>>&& aStyles) {
|
||||
|
|
|
@ -3902,6 +3902,7 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForAnonymousBox(
|
|||
parent_style_or_null: Option<&ComputedValues>,
|
||||
pseudo: PseudoStyleType,
|
||||
raw_data: &RawServoStyleSet,
|
||||
page_name: *const nsAtom,
|
||||
) -> Strong<ComputedValues> {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
|
@ -3912,9 +3913,6 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForAnonymousBox(
|
|||
|
||||
// If the pseudo element is PageContent, we should append @page rules to the
|
||||
// precomputed pseudo.
|
||||
//
|
||||
// TODO(emilio): We'll need a separate code path or extra arguments for
|
||||
// named pages, etc.
|
||||
let mut extra_declarations = vec![];
|
||||
if pseudo == PseudoElement::PageContent {
|
||||
let iter = data.stylist.iter_extra_data_origins_rev();
|
||||
|
@ -3924,14 +3922,28 @@ pub unsafe extern "C" fn Servo_ComputedValues_GetForAnonymousBox(
|
|||
Origin::User => CascadeLevel::UserNormal,
|
||||
Origin::Author => CascadeLevel::same_tree_author_normal(),
|
||||
};
|
||||
for &(ref rule, _layer_id) in data.pages.global.iter() {
|
||||
extra_declarations.reserve(data.pages.global.len());
|
||||
let mut add_rule = |rule: &Arc<Locked<PageRule>>| {
|
||||
extra_declarations.push(ApplicableDeclarationBlock::from_declarations(
|
||||
rule.0.read_with(level.guard(&guards)).block.clone(),
|
||||
rule.read_with(level.guard(&guards)).block.clone(),
|
||||
level,
|
||||
LayerOrder::root(),
|
||||
));
|
||||
};
|
||||
for &(ref rule, _layer_id) in data.pages.global.iter() {
|
||||
add_rule(&rule.0);
|
||||
}
|
||||
if !page_name.is_null() {
|
||||
Atom::with(page_name, |name| {
|
||||
if let Some(rules) = data.pages.named.get(name) {
|
||||
// Rules are already sorted by source order.
|
||||
rules.iter().for_each(|d| add_rule(&d.rule));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug_assert!(page_name_or_null.is_null());
|
||||
}
|
||||
|
||||
let rule_node =
|
||||
|
|
Загрузка…
Ссылка в новой задаче