зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1383650 - Optimize attribute mapping by not parsing same thing twice r=longsonr
Geometry properties are the most used SVG attributes. When authors specify them as attributes, we have to parse them in SVG side. So we don't want to parse them in CSS side again, otherwise the introduced performance loss is relatively high. With this optimization, this feature implementation doesn't slow down overall performace even if there are thousands of geometry elements. Differential Revision: https://phabricator.services.mozilla.com/D30778 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a5f610a05c
Коммит
99366154e3
|
@ -1072,6 +1072,9 @@ class MOZ_STACK_CLASS MappedAttrParser {
|
|||
void ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
||||
const nsAString& aMappedAttrValue);
|
||||
|
||||
void TellStyleAlreadyParsedResult(nsAtom const* aAtom,
|
||||
SVGAnimatedLength const& aLength);
|
||||
|
||||
// If we've parsed any values for mapped attributes, this method returns the
|
||||
// already_AddRefed css::Declaration that incorporates the parsed
|
||||
// values. Otherwise, this method returns null.
|
||||
|
@ -1159,6 +1162,18 @@ void MappedAttrParser::ParseMappedAttrValue(nsAtom* aMappedAttrName,
|
|||
}
|
||||
}
|
||||
|
||||
void MappedAttrParser::TellStyleAlreadyParsedResult(
|
||||
nsAtom const* aAtom, SVGAnimatedLength const& aLength) {
|
||||
if (!mDecl) {
|
||||
mDecl = new DeclarationBlock();
|
||||
}
|
||||
nsCSSPropertyID propertyID =
|
||||
nsCSSProps::LookupProperty(nsDependentAtomString(aAtom));
|
||||
|
||||
SVGElement::UpdateDeclarationBlockFromLength(*mDecl, propertyID, aLength,
|
||||
SVGElement::ValToUse::Base);
|
||||
}
|
||||
|
||||
already_AddRefed<DeclarationBlock> MappedAttrParser::GetDeclarationBlock() {
|
||||
return mDecl.forget();
|
||||
}
|
||||
|
@ -1182,6 +1197,9 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
|||
MappedAttrParser mappedAttrParser(doc->CSSLoader(), doc->GetDocumentURI(),
|
||||
GetBaseURI(), this);
|
||||
|
||||
bool lengthAffectsStyle =
|
||||
SVGGeometryProperty::ElementMapsLengthsToStyle(this);
|
||||
|
||||
for (uint32_t i = 0; i < attrCount; ++i) {
|
||||
const nsAttrName* attrName = mAttrs.AttrNameAt(i);
|
||||
if (!attrName->IsAtom() || !IsAttributeMapped(attrName->Atom())) continue;
|
||||
|
@ -1214,6 +1232,20 @@ void SVGElement::UpdateContentDeclarationBlock() {
|
|||
}
|
||||
}
|
||||
|
||||
if (lengthAffectsStyle) {
|
||||
auto const* length = GetAnimatedLength(attrName->Atom());
|
||||
|
||||
if (length && length->HasBaseVal()) {
|
||||
// This is an element with geometry property set via SVG attribute,
|
||||
// and the attribute is already successfully parsed. We want to go
|
||||
// through the optimized path to tell the style system the result
|
||||
// directly, rather than let it parse the same thing again.
|
||||
mappedAttrParser.TellStyleAlreadyParsedResult(attrName->Atom(),
|
||||
*length);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoString value;
|
||||
mAttrs.AttrAt(i)->ToString(value);
|
||||
mappedAttrParser.ParseMappedAttrValue(attrName->Atom(), value);
|
||||
|
@ -1457,7 +1489,6 @@ SVGAnimatedLength* SVGElement::GetAnimatedLength(const nsAtom* aAttrName) {
|
|||
return &lengthInfo.mLengths[i];
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(false, "no matching length found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче