Bug 1414926 - Make -moz-font-smoothing-background-color changes only cause repaints, not reflows. r=emilio

This case is hit by hovering over menu items, so the optimization is somewhat worthwhile.
As a side-effect, not causing reflows also avoids a XUL <select> popup positioning bug.

MozReview-Commit-ID: AOrijytoHHL

--HG--
extra : rebase_source : c2156eb24171f6d0b0e5476c4a7dbc641a0b5301
This commit is contained in:
Markus Stange 2017-11-07 23:01:29 -05:00
parent 91932e97bd
commit 62e25a4903
4 changed files with 59 additions and 29 deletions

View File

@ -42,32 +42,42 @@ nsFont::~nsFont()
bool nsFont::Equals(const nsFont& aOther) const
{
if ((style == aOther.style) &&
(systemFont == aOther.systemFont) &&
(weight == aOther.weight) &&
(stretch == aOther.stretch) &&
(size == aOther.size) &&
(sizeAdjust == aOther.sizeAdjust) &&
(fontlist == aOther.fontlist) &&
(kerning == aOther.kerning) &&
(synthesis == aOther.synthesis) &&
(fontFeatureSettings == aOther.fontFeatureSettings) &&
(fontVariationSettings == aOther.fontVariationSettings) &&
(languageOverride == aOther.languageOverride) &&
(variantAlternates == aOther.variantAlternates) &&
(variantCaps == aOther.variantCaps) &&
(variantEastAsian == aOther.variantEastAsian) &&
(variantLigatures == aOther.variantLigatures) &&
(variantNumeric == aOther.variantNumeric) &&
(variantPosition == aOther.variantPosition) &&
(variantWidth == aOther.variantWidth) &&
(alternateValues == aOther.alternateValues) &&
(featureValueLookup == aOther.featureValueLookup) &&
(smoothing == aOther.smoothing) &&
(fontSmoothingBackgroundColor == aOther.fontSmoothingBackgroundColor)) {
return true;
return CalcDifference(aOther) == MaxDifference::eNone;
}
nsFont::MaxDifference
nsFont::CalcDifference(const nsFont& aOther) const
{
if ((style != aOther.style) ||
(systemFont != aOther.systemFont) ||
(weight != aOther.weight) ||
(stretch != aOther.stretch) ||
(size != aOther.size) ||
(sizeAdjust != aOther.sizeAdjust) ||
(fontlist != aOther.fontlist) ||
(kerning != aOther.kerning) ||
(synthesis != aOther.synthesis) ||
(fontFeatureSettings != aOther.fontFeatureSettings) ||
(fontVariationSettings != aOther.fontVariationSettings) ||
(languageOverride != aOther.languageOverride) ||
(variantAlternates != aOther.variantAlternates) ||
(variantCaps != aOther.variantCaps) ||
(variantEastAsian != aOther.variantEastAsian) ||
(variantLigatures != aOther.variantLigatures) ||
(variantNumeric != aOther.variantNumeric) ||
(variantPosition != aOther.variantPosition) ||
(variantWidth != aOther.variantWidth) ||
(alternateValues != aOther.alternateValues) ||
(featureValueLookup != aOther.featureValueLookup)) {
return MaxDifference::eLayoutAffecting;
}
return false;
if ((smoothing != aOther.smoothing) ||
(fontSmoothingBackgroundColor != aOther.fontSmoothingBackgroundColor)) {
return MaxDifference::eVisual;
}
return MaxDifference::eNone;
}
nsFont& nsFont::operator=(const nsFont& aOther) = default;

View File

@ -143,6 +143,14 @@ struct nsFont {
nsFont& operator=(const nsFont& aOther);
enum class MaxDifference : uint8_t {
eNone,
eVisual,
eLayoutAffecting
};
MaxDifference CalcDifference(const nsFont& aOther) const;
void CopyAlternates(const nsFont& aOther);
// Add featureSettings into style

View File

@ -446,6 +446,11 @@ operator==(const FontFamilyList& a, const FontFamilyList& b) {
return a.Equals(b);
}
inline bool
operator!=(const FontFamilyList& a, const FontFamilyList& b) {
return !a.Equals(b);
}
} // namespace mozilla
#endif /* GFX_FONT_FAMILY_LIST_H */

View File

@ -199,18 +199,25 @@ nsStyleFont::CalcDifference(const nsStyleFont& aNewData) const
MOZ_ASSERT(mAllowZoom == aNewData.mAllowZoom,
"expected mAllowZoom to be the same on both nsStyleFonts");
if (mSize != aNewData.mSize ||
mFont != aNewData.mFont ||
mLanguage != aNewData.mLanguage ||
mExplicitLanguage != aNewData.mExplicitLanguage ||
mMathVariant != aNewData.mMathVariant ||
mMathDisplay != aNewData.mMathDisplay ||
mMinFontSizeRatio != aNewData.mMinFontSizeRatio) {
// If only mFont.fontSmoothingBackgroundColor changes, we really only need
// a repaint hint rather than a reflow+repaint hint, but it's not worth
// worth optimizing.
return NS_STYLE_HINT_REFLOW;
}
switch (mFont.CalcDifference(aNewData.mFont)) {
case nsFont::MaxDifference::eLayoutAffecting:
return NS_STYLE_HINT_REFLOW;
case nsFont::MaxDifference::eVisual:
return NS_STYLE_HINT_VISUAL;
case nsFont::MaxDifference::eNone:
break;
}
// XXX Should any of these cause a non-nsChangeHint_NeutralChange change?
if (mGenericID != aNewData.mGenericID ||
mScriptLevel != aNewData.mScriptLevel ||