diff --git a/mozilla/content/html/style/src/nsCSSParser.cpp b/mozilla/content/html/style/src/nsCSSParser.cpp index fb3ea116644..c7151c28d87 100644 --- a/mozilla/content/html/style/src/nsCSSParser.cpp +++ b/mozilla/content/html/style/src/nsCSSParser.cpp @@ -3330,6 +3330,34 @@ done: return found; } +static PRInt32 ComputeChangeHint(nsCSSProperty aPropID, + const nsCSSValue& aOldValue, + const nsCSSValue& aValue) +{ + NS_ASSERTION(aOldValue != aValue, + "ComputeChangeHint should not be called with equal values"); + + switch (aPropID) { + case eCSSProperty_opacity: + // If the opacity is changing to or from 1.0, then reframe to (possibly) + // cause a view to be created or eliminated + // Otherwise we just need a visual change. This is important because + // opacity is frequently used for fade effects, and we don't want to reframe + // for every step of the fade. + if (aOldValue.GetUnit() == eCSSUnit_Number && aValue.GetUnit() == eCSSUnit_Number) { + if (aOldValue.GetFloatValue() == 1.0 || aValue.GetFloatValue() == 1.0) { + // XXX: it would be better to pass out a hint NS_STYLE_HINT_VIEWCHANGE, + // but it does not exist + return NS_STYLE_HINT_FRAMECHANGE; + } else { + return NS_STYLE_HINT_VISUAL; + } + } + } + + return nsCSSProps::kHintTable[aPropID]; +} + nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSProperty aPropID, const nsCSSValue& aValue, PRInt32& aChangeHint) { @@ -3339,8 +3367,10 @@ nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSPropert if (aValue != oldValue) { result = aDeclaration->AppendValue(aPropID, aValue); - if (aChangeHint < nsCSSProps::kHintTable[aPropID]) { - aChangeHint = nsCSSProps::kHintTable[aPropID]; + + PRInt32 newHint = ComputeChangeHint(aPropID, oldValue, aValue); + if (aChangeHint < newHint) { + aChangeHint = newHint; } } return result; diff --git a/mozilla/content/shared/public/nsCSSPropList.h b/mozilla/content/shared/public/nsCSSPropList.h index ca415b05f5d..ce14a5df95e 100644 --- a/mozilla/content/shared/public/nsCSSPropList.h +++ b/mozilla/content/shared/public/nsCSSPropList.h @@ -89,7 +89,7 @@ CSS_PROP(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, VISUAL) CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, VISUAL) CSS_PROP(azimuth, azimuth, AURAL) CSS_PROP(background, background, VISUAL) -CSS_PROP(background-attachment, background_attachment, VISUAL) +CSS_PROP(background-attachment, background_attachment, FRAMECHANGE) CSS_PROP(background-color, background_color, VISUAL) CSS_PROP(background-image, background_image, VISUAL) CSS_PROP(background-position, background_position, VISUAL) @@ -188,7 +188,7 @@ CSS_PROP(max-height, max_height, REFLOW) CSS_PROP(max-width, max_width, REFLOW) CSS_PROP(min-height, min_height, REFLOW) CSS_PROP(min-width, min_width, REFLOW) -CSS_PROP(-moz-opacity, opacity, VISUAL) // XXX bug 3935 +CSS_PROP(-moz-opacity, opacity, FRAMECHANGE) // XXX bug 3935 CSS_PROP(orphans, orphans, REFLOW) CSS_PROP(-moz-outline, outline, VISUAL) // XXX This is temporary fix for nsbeta3+ Bug 48973, turning outline into -moz-outline XXX bug 48973 CSS_PROP(-moz-outline-color, outline_color, VISUAL) // XXX bug 48973 diff --git a/mozilla/content/shared/src/nsStyleStruct.cpp b/mozilla/content/shared/src/nsStyleStruct.cpp index 665d6bf4378..5e9b21d6a08 100644 --- a/mozilla/content/shared/src/nsStyleStruct.cpp +++ b/mozilla/content/shared/src/nsStyleStruct.cpp @@ -978,6 +978,12 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const { + if (mBackgroundAttachment != aOther.mBackgroundAttachment + && (NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) || + (NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment)) + // this might require creation of a view + return NS_STYLE_HINT_FRAMECHANGE; + if ((mBackgroundAttachment == aOther.mBackgroundAttachment) && (mBackgroundFlags == aOther.mBackgroundFlags) && (mBackgroundRepeat == aOther.mBackgroundRepeat) && @@ -1075,13 +1081,18 @@ nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource) PRInt32 nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const { - if (mOpacity != aOther.mOpacity) - return NS_STYLE_HINT_VISUAL; + if (mOpacity != aOther.mOpacity + && ((mOpacity < 1.0) != (aOther.mOpacity < 1.0))) + // might need to create a view to handle change from 1.0 to partial opacity + return NS_STYLE_HINT_FRAMECHANGE; if ((mDirection == aOther.mDirection) && (mLanguage == aOther.mLanguage)) { if ((mVisible == aOther.mVisible)) { - return NS_STYLE_HINT_NONE; + if (mOpacity == aOther.mOpacity) + return NS_STYLE_HINT_NONE; + else + return NS_STYLE_HINT_VISUAL; } if ((mVisible != aOther.mVisible) && ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) || diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index fb3ea116644..c7151c28d87 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -3330,6 +3330,34 @@ done: return found; } +static PRInt32 ComputeChangeHint(nsCSSProperty aPropID, + const nsCSSValue& aOldValue, + const nsCSSValue& aValue) +{ + NS_ASSERTION(aOldValue != aValue, + "ComputeChangeHint should not be called with equal values"); + + switch (aPropID) { + case eCSSProperty_opacity: + // If the opacity is changing to or from 1.0, then reframe to (possibly) + // cause a view to be created or eliminated + // Otherwise we just need a visual change. This is important because + // opacity is frequently used for fade effects, and we don't want to reframe + // for every step of the fade. + if (aOldValue.GetUnit() == eCSSUnit_Number && aValue.GetUnit() == eCSSUnit_Number) { + if (aOldValue.GetFloatValue() == 1.0 || aValue.GetFloatValue() == 1.0) { + // XXX: it would be better to pass out a hint NS_STYLE_HINT_VIEWCHANGE, + // but it does not exist + return NS_STYLE_HINT_FRAMECHANGE; + } else { + return NS_STYLE_HINT_VISUAL; + } + } + } + + return nsCSSProps::kHintTable[aPropID]; +} + nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSProperty aPropID, const nsCSSValue& aValue, PRInt32& aChangeHint) { @@ -3339,8 +3367,10 @@ nsresult CSSParserImpl::AppendValue(nsCSSDeclaration* aDeclaration, nsCSSPropert if (aValue != oldValue) { result = aDeclaration->AppendValue(aPropID, aValue); - if (aChangeHint < nsCSSProps::kHintTable[aPropID]) { - aChangeHint = nsCSSProps::kHintTable[aPropID]; + + PRInt32 newHint = ComputeChangeHint(aPropID, oldValue, aValue); + if (aChangeHint < newHint) { + aChangeHint = newHint; } } return result; diff --git a/mozilla/layout/style/nsCSSPropList.h b/mozilla/layout/style/nsCSSPropList.h index ca415b05f5d..ce14a5df95e 100644 --- a/mozilla/layout/style/nsCSSPropList.h +++ b/mozilla/layout/style/nsCSSPropList.h @@ -89,7 +89,7 @@ CSS_PROP(-moz-outline-radius-bottomleft, _moz_outline_radius_bottomLeft, VISUAL) CSS_PROP(-moz-outline-radius-bottomright, _moz_outline_radius_bottomRight, VISUAL) CSS_PROP(azimuth, azimuth, AURAL) CSS_PROP(background, background, VISUAL) -CSS_PROP(background-attachment, background_attachment, VISUAL) +CSS_PROP(background-attachment, background_attachment, FRAMECHANGE) CSS_PROP(background-color, background_color, VISUAL) CSS_PROP(background-image, background_image, VISUAL) CSS_PROP(background-position, background_position, VISUAL) @@ -188,7 +188,7 @@ CSS_PROP(max-height, max_height, REFLOW) CSS_PROP(max-width, max_width, REFLOW) CSS_PROP(min-height, min_height, REFLOW) CSS_PROP(min-width, min_width, REFLOW) -CSS_PROP(-moz-opacity, opacity, VISUAL) // XXX bug 3935 +CSS_PROP(-moz-opacity, opacity, FRAMECHANGE) // XXX bug 3935 CSS_PROP(orphans, orphans, REFLOW) CSS_PROP(-moz-outline, outline, VISUAL) // XXX This is temporary fix for nsbeta3+ Bug 48973, turning outline into -moz-outline XXX bug 48973 CSS_PROP(-moz-outline-color, outline_color, VISUAL) // XXX bug 48973 diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp index 665d6bf4378..5e9b21d6a08 100644 --- a/mozilla/layout/style/nsStyleStruct.cpp +++ b/mozilla/layout/style/nsStyleStruct.cpp @@ -978,6 +978,12 @@ nsStyleBackground::nsStyleBackground(const nsStyleBackground& aSource) PRInt32 nsStyleBackground::CalcDifference(const nsStyleBackground& aOther) const { + if (mBackgroundAttachment != aOther.mBackgroundAttachment + && (NS_STYLE_BG_ATTACHMENT_FIXED == mBackgroundAttachment) || + (NS_STYLE_BG_ATTACHMENT_FIXED == aOther.mBackgroundAttachment)) + // this might require creation of a view + return NS_STYLE_HINT_FRAMECHANGE; + if ((mBackgroundAttachment == aOther.mBackgroundAttachment) && (mBackgroundFlags == aOther.mBackgroundFlags) && (mBackgroundRepeat == aOther.mBackgroundRepeat) && @@ -1075,13 +1081,18 @@ nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource) PRInt32 nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const { - if (mOpacity != aOther.mOpacity) - return NS_STYLE_HINT_VISUAL; + if (mOpacity != aOther.mOpacity + && ((mOpacity < 1.0) != (aOther.mOpacity < 1.0))) + // might need to create a view to handle change from 1.0 to partial opacity + return NS_STYLE_HINT_FRAMECHANGE; if ((mDirection == aOther.mDirection) && (mLanguage == aOther.mLanguage)) { if ((mVisible == aOther.mVisible)) { - return NS_STYLE_HINT_NONE; + if (mOpacity == aOther.mOpacity) + return NS_STYLE_HINT_NONE; + else + return NS_STYLE_HINT_VISUAL; } if ((mVisible != aOther.mVisible) && ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||