Bug 719177 - Replace all NS_STYLE_HINT_VISUAL with nsChangeHint_RepaintFrame except for 'visibility' and 'z-index' which are the only ones that need SyncFrameView. r=roc
authorMats Palmgren <matspal@gmail.com>
Sat, 28 Jan 2012 04:35:58 +0100
changeset 86862 f222fbece9833a7a500bfb1408f0a346a898c567
parent 86861 8f11aaac24dcb1415e9684a632bf60d887b409e0
child 86863 0246973f2513b7d7d93b1d3e8bf03bcebb34fff6
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs719177
milestone12.0a1
Bug 719177 - Replace all NS_STYLE_HINT_VISUAL with nsChangeHint_RepaintFrame except for 'visibility' and 'z-index' which are the only ones that need SyncFrameView. r=roc
content/html/content/src/nsHTMLCanvasElement.cpp
layout/base/nsChangeHint.h
layout/doc/adding-style-props.html
layout/style/nsStyleContext.cpp
layout/style/nsStyleStruct.cpp
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -176,17 +176,17 @@ nsHTMLCanvasElement::GetAttributeChangeH
   nsChangeHint retval =
     nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
   if (aAttribute == nsGkAtoms::width ||
       aAttribute == nsGkAtoms::height)
   {
     NS_UpdateHint(retval, NS_STYLE_HINT_REFLOW);
   } else if (aAttribute == nsGkAtoms::moz_opaque)
   {
-    NS_UpdateHint(retval, NS_STYLE_HINT_VISUAL);
+    NS_UpdateHint(retval, nsChangeHint_RepaintFrame);
   }
   return retval;
 }
 
 bool
 nsHTMLCanvasElement::ParseAttribute(PRInt32 aNamespaceID,
                                     nsIAtom* aAttribute,
                                     const nsAString& aValue,
--- a/layout/base/nsChangeHint.h
+++ b/layout/base/nsChangeHint.h
@@ -132,25 +132,23 @@ inline bool NS_UpdateHint(nsChangeHint& 
 // Returns true iff the second hint contains all the hints of the first hint
 inline bool NS_IsHintSubset(nsChangeHint aSubset, nsChangeHint aSuperSet) {
   return (aSubset & aSuperSet) == aSubset;
 }
 
 // Redefine the old NS_STYLE_HINT constants in terms of the new hint structure
 #define NS_STYLE_HINT_NONE \
   nsChangeHint(0)
-#define NS_STYLE_HINT_VISUAL \
-  nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView)
 #define nsChangeHint_ReflowFrame                        \
   nsChangeHint(nsChangeHint_NeedReflow |                \
                nsChangeHint_ClearAncestorIntrinsics |   \
                nsChangeHint_ClearDescendantIntrinsics | \
                nsChangeHint_NeedDirtyReflow)
 #define NS_STYLE_HINT_REFLOW \
-  nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_ReflowFrame)
+  nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_ReflowFrame)
 #define NS_STYLE_HINT_FRAMECHANGE \
   nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_ReconstructFrame)
 
 /**
  * |nsRestyleHint| is a bitfield for the result of
  * |HasStateDependentStyle| and |HasAttributeDependentStyle|.  When no
  * restyling is necessary, use |nsRestyleHint(0)|.
  */
--- a/layout/doc/adding-style-props.html
+++ b/layout/doc/adding-style-props.html
@@ -322,19 +322,19 @@ is the CalcDifference change for our exa
  <b> if (mForceBrokenImageIcon == aOther.mForceBrokenImageIcon) {</b>
     if (mResizer == aOther.mResizer) {
       if (mUserSelect == aOther.mUserSelect) {
         if (mKeyEquivalent == aOther.mKeyEquivalent) {
           return NS_STYLE_HINT_NONE;
         }
         return NS_STYLE_HINT_CONTENT;
       }
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
     }
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
   }
   <b>return NS_STYLE_HINT_FRAMECHANGE;
 </b>}
 </pre>
   <h3>CSSStyleRule</h3>
 The nsCSSStyleRule must be updated to manage mapping the declaration to the
 style struct. In the file <a href="http://lxr.mozilla.org/seamonkey/source/content/html/style/src/nsCSSStyleRule.cpp">
 nsCSSStyleRule.cpp</a>
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -436,61 +436,70 @@ nsStyleContext::CalcStyleDifference(nsSt
   // causing the maximal difference, a FRAMECHANGE.
   // FRAMECHANGE Structs: Display, XUL, Content, UserInterface,
   // Visibility, Outline, TableBorder, Table, Text, UIReset, Quotes
   nsChangeHint maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
       nsChangeHint_UpdateTransformLayer | nsChangeHint_UpdateOpacityLayer |
       nsChangeHint_UpdateOverflow);
   DO_STRUCT_DIFFERENCE(Display);
 
+  // Changes to 'visibility' cause SyncFrameView.
   maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
-      nsChangeHint_UpdateCursor);
+      nsChangeHint_SyncFrameView);
+  DO_STRUCT_DIFFERENCE(Visibility);
+
+  maxHint = nsChangeHint(NS_STYLE_HINT_FRAMECHANGE |
+      nsChangeHint_UpdateOverflow | nsChangeHint_UpdateCursor);
   DO_STRUCT_DIFFERENCE(XUL);
   DO_STRUCT_DIFFERENCE(Column);
   DO_STRUCT_DIFFERENCE(Content);
   DO_STRUCT_DIFFERENCE(UserInterface);
-  DO_STRUCT_DIFFERENCE(Visibility);
   DO_STRUCT_DIFFERENCE(TableBorder);
   DO_STRUCT_DIFFERENCE(Table);
   DO_STRUCT_DIFFERENCE(UIReset);
   DO_STRUCT_DIFFERENCE(Text);
   DO_STRUCT_DIFFERENCE(List);
   // If the quotes implementation is ever going to change we might not need
   // a framechange here and a reflow should be sufficient.  See bug 35768.
   DO_STRUCT_DIFFERENCE(Quotes);
 
   maxHint = nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_UpdateEffects);
   DO_STRUCT_DIFFERENCE(SVGReset);
   DO_STRUCT_DIFFERENCE(SVG);
 
+  maxHint = nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_UpdateOverflow);
+  DO_STRUCT_DIFFERENCE(Border);
+      
+  // Changes to 'z-index' cause SyncFrameView.
+  maxHint = nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_SyncFrameView);
+  DO_STRUCT_DIFFERENCE(Position);
+
   // At this point, we know that the worst kind of damage we could do is
   // a reflow.
   maxHint = NS_STYLE_HINT_REFLOW;
-      
+
   // The following structs cause (as their maximal difference) a reflow
-  // to occur.  REFLOW Structs: Font, Margin, Padding, Border, List,
-  // Position, Text, TextReset
+  // to occur.  REFLOW Structs: Font, Margin, Padding, List, Position,
+  // TextReset
   DO_STRUCT_DIFFERENCE(Font);
   DO_STRUCT_DIFFERENCE(Margin);
   DO_STRUCT_DIFFERENCE(Padding);
-  DO_STRUCT_DIFFERENCE(Border);
-  DO_STRUCT_DIFFERENCE(Position);
   DO_STRUCT_DIFFERENCE(TextReset);
 
   // Outline needs to update the overflow and repaint.
-  maxHint = nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_UpdateOverflow);
+  maxHint = nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_UpdateOverflow);
   DO_STRUCT_DIFFERENCE(Outline);
 
-  // Most backgrounds only require a re-render (i.e., a VISUAL change), but
-  // backgrounds using -moz-element need to reset SVG effects, too.
-  maxHint = nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_UpdateEffects);
+  // Most backgrounds only require a repaint, but backgrounds using -moz-element
+  // need to reset SVG effects, too.
+  maxHint = nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects);
   DO_STRUCT_DIFFERENCE(Background);
 
   // Color only needs a repaint.
-  maxHint = NS_STYLE_HINT_VISUAL;
+  maxHint = nsChangeHint_RepaintFrame;
   DO_STRUCT_DIFFERENCE(Color);
 
 #undef DO_STRUCT_DIFFERENCE
 
   // Note that we do not check whether this->RelevantLinkVisited() !=
   // aOther->RelevantLinkVisited(); we don't need to since
   // nsCSSFrameConstructor::DoContentStateChanged always adds
   // nsChangeHint_RepaintFrame for NS_EVENT_STATE_VISITED changes (and
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -232,17 +232,17 @@ nsChangeHint nsStyleFont::CalcFontDiffer
       (aFont1.weight == aFont2.weight) &&
       (aFont1.stretch == aFont2.stretch) &&
       (aFont1.name == aFont2.name) &&
       (aFont1.featureSettings == aFont2.featureSettings) &&
       (aFont1.languageOverride == aFont2.languageOverride)) {
     if ((aFont1.decorations == aFont2.decorations)) {
       return NS_STYLE_HINT_NONE;
     }
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
   }
   return NS_STYLE_HINT_REFLOW;
 }
 
 static bool IsFixedData(const nsStyleSides& aSides, bool aEnumOK)
 {
   NS_FOR_CSS_SIDES(side) {
     if (!IsFixedUnit(aSides.Get(side), aEnumOK))
@@ -551,17 +551,17 @@ nsChangeHint nsStyleBorder::CalcDifferen
 
   nsChangeHint shadowDifference =
     CalcShadowDifference(mBoxShadow, aOther.mBoxShadow);
   if (NS_IsHintSubset(nsChangeHint_RepaintFrame, shadowDifference))
     return shadowDifference;
 
   // Note that mBorderStyle stores not only the border style but also
   // color-related flags.  Given that we've already done an mComputedBorder
-  // comparison, border-style differences can only lead to a VISUAL hint.  So
+  // comparison, border-style differences can only lead to a Repaint hint.  So
   // it's OK to just compare the values directly -- if either the actual
   // style or the color flags differ we want to repaint.
   NS_FOR_CSS_SIDES(ix) {
     if (mBorderStyle[ix] != aOther.mBorderStyle[ix] || 
         mBorderColor[ix] != aOther.mBorderColor[ix])
       return nsChangeHint_RepaintFrame;
   }
 
@@ -737,17 +737,17 @@ nsChangeHint nsStyleList::CalcDifference
   if (mListStylePosition != aOther.mListStylePosition)
     return NS_STYLE_HINT_FRAMECHANGE;
   if (EqualImages(mListStyleImage, aOther.mListStyleImage) &&
       mListStyleType == aOther.mListStyleType) {
     if (mImageRegion.IsEqualInterior(aOther.mImageRegion))
       return NS_STYLE_HINT_NONE;
     if (mImageRegion.width == aOther.mImageRegion.width &&
         mImageRegion.height == aOther.mImageRegion.height)
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
   }
   return NS_STYLE_HINT_REFLOW;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleList::MaxDifference()
 {
@@ -847,17 +847,17 @@ nsChangeHint nsStyleColumn::CalcDifferen
       mColumnGap != aOther.mColumnGap ||
       mColumnFill != aOther.mColumnFill)
     return NS_STYLE_HINT_REFLOW;
 
   if (GetComputedColumnRuleWidth() != aOther.GetComputedColumnRuleWidth() ||
       mColumnRuleStyle != aOther.mColumnRuleStyle ||
       mColumnRuleColor != aOther.mColumnRuleColor ||
       mColumnRuleColorIsForeground != aOther.mColumnRuleColorIsForeground)
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
 
   return NS_STYLE_HINT_NONE;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleColumn::MaxDifference()
 {
@@ -1174,17 +1174,18 @@ nsStylePosition::nsStylePosition(const n
 {
   MOZ_COUNT_CTOR(nsStylePosition);
   memcpy((nsStylePosition*)this, &aSource, sizeof(nsStylePosition));
 }
 
 nsChangeHint nsStylePosition::CalcDifference(const nsStylePosition& aOther) const
 {
   nsChangeHint hint =
-    (mZIndex == aOther.mZIndex) ? NS_STYLE_HINT_NONE : nsChangeHint_RepaintFrame;
+    mZIndex == aOther.mZIndex ? NS_STYLE_HINT_NONE :
+      nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_SyncFrameView);
 
   if (mBoxSizing != aOther.mBoxSizing) {
     // Can affect both widths and heights; just a bad scene.
     return NS_CombineHint(hint, nsChangeHint_ReflowFrame);
   }
 
   if (mHeight != aOther.mHeight ||
       mMinHeight != aOther.mMinHeight ||
@@ -1219,17 +1220,17 @@ nsChangeHint nsStylePosition::CalcDiffer
                                    NS_CombineHint(nsChangeHint_ClearDescendantIntrinsics,
                                                   nsChangeHint_NeedDirtyReflow)));
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStylePosition::MaxDifference()
 {
-  return NS_STYLE_HINT_REFLOW;
+  return nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_SyncFrameView);
 }
 #endif
 
 /* static */ bool
 nsStylePosition::WidthCoordDependsOnContainer(const nsStyleCoord &aCoord)
 {
   return aCoord.GetUnit() == eStyleUnit_Auto ||
          aCoord.HasPercent() ||
@@ -1323,17 +1324,17 @@ nsChangeHint nsStyleTableBorder::CalcDif
     return NS_STYLE_HINT_FRAMECHANGE;
   }
   
   if ((mCaptionSide == aOther.mCaptionSide) &&
       (mBorderSpacingX == aOther.mBorderSpacingX) &&
       (mBorderSpacingY == aOther.mBorderSpacingY)) {
     if (mEmptyCells == aOther.mEmptyCells)
       return NS_STYLE_HINT_NONE;
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
   }
   else
     return NS_STYLE_HINT_REFLOW;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleTableBorder::MaxDifference()
@@ -1357,24 +1358,24 @@ nsStyleColor::nsStyleColor(const nsStyle
   MOZ_COUNT_CTOR(nsStyleColor);
   mColor = aSource.mColor;
 }
 
 nsChangeHint nsStyleColor::CalcDifference(const nsStyleColor& aOther) const
 {
   if (mColor == aOther.mColor)
     return NS_STYLE_HINT_NONE;
-  return NS_STYLE_HINT_VISUAL;
+  return nsChangeHint_RepaintFrame;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleColor::MaxDifference()
 {
-  return NS_STYLE_HINT_VISUAL;
+  return nsChangeHint_RepaintFrame;
 }
 #endif
 
 // --------------------
 // nsStyleGradient
 //
 bool
 nsStyleGradient::operator==(const nsStyleGradient& aOther) const
@@ -1813,39 +1814,39 @@ nsChangeHint nsStyleBackground::CalcDiff
 
   bool hasVisualDifference = false;
 
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, moreLayers) {
     if (i < lessLayers->mImageCount) {
       if (moreLayers->mLayers[i] != lessLayers->mLayers[i]) {
         if ((moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
             (lessLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element))
-          return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
+          return NS_CombineHint(nsChangeHint_UpdateEffects, nsChangeHint_RepaintFrame);
         hasVisualDifference = true;
       }
     } else {
       if (moreLayers->mLayers[i].mImage.GetType() == eStyleImageType_Element)
-        return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
+        return NS_CombineHint(nsChangeHint_UpdateEffects, nsChangeHint_RepaintFrame);
       hasVisualDifference = true;
     }
   }
 
   if (hasVisualDifference ||
       mBackgroundColor != aOther.mBackgroundColor ||
       mBackgroundInlinePolicy != aOther.mBackgroundInlinePolicy)
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
 
   return NS_STYLE_HINT_NONE;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleBackground::MaxDifference()
 {
-  return NS_CombineHint(nsChangeHint_UpdateEffects, NS_STYLE_HINT_VISUAL);
+  return NS_CombineHint(nsChangeHint_UpdateEffects, nsChangeHint_RepaintFrame);
 }
 #endif
 
 bool nsStyleBackground::HasFixedBackground() const
 {
   NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, this) {
     const Layer &layer = mLayers[i];
     if (layer.mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
@@ -2340,38 +2341,40 @@ nsStyleVisibility::nsStyleVisibility(nsP
 nsStyleVisibility::nsStyleVisibility(const nsStyleVisibility& aSource)
 {
   MOZ_COUNT_CTOR(nsStyleVisibility);
   mDirection = aSource.mDirection;
   mVisible = aSource.mVisible;
   mPointerEvents = aSource.mPointerEvents;
 } 
 
-nsChangeHint nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
+nsChangeHint
+nsStyleVisibility::CalcDifference(const nsStyleVisibility& aOther) const
 {
-  nsChangeHint hint = nsChangeHint(0);
-
   if (mDirection != aOther.mDirection) {
-    NS_UpdateHint(hint, nsChangeHint_ReconstructFrame);
-  } else if (mVisible != aOther.mVisible) {
+    return nsChangeHint_ReconstructFrame;
+  }
+  nsChangeHint hint = NS_STYLE_HINT_NONE;
+  if (mVisible != aOther.mVisible) {
+    NS_UpdateHint(hint, nsChangeHint_SyncFrameView);
     if ((NS_STYLE_VISIBILITY_COLLAPSE == mVisible) ||
         (NS_STYLE_VISIBILITY_COLLAPSE == aOther.mVisible)) {
       NS_UpdateHint(hint, NS_STYLE_HINT_REFLOW);
     } else {
-      NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
+      NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
     }
   }
   return hint;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleVisibility::MaxDifference()
 {
-  return NS_STYLE_HINT_FRAMECHANGE;
+  return nsChangeHint(NS_STYLE_HINT_FRAMECHANGE | nsChangeHint_SyncFrameView);
 }
 #endif
 
 nsStyleContentData::~nsStyleContentData()
 {
   NS_ABORT_IF_FALSE(!mImageTracked,
                     "nsStyleContentData being destroyed while still tracking image!");
   if (mType == eStyleContentType_Image) {
@@ -2752,30 +2755,30 @@ nsChangeHint nsStyleTextReset::CalcDiffe
       if (lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
           lineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY ||
           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE ||
           otherLineStyle == NS_STYLE_TEXT_DECORATION_STYLE_WAVY) {
         return NS_STYLE_HINT_REFLOW;
       }
       // Repaint for other style decoration lines because they must be in
       // default overflow rect
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
     }
 
     // Repaint for decoration color changes
     nscolor decColor, otherDecColor;
     bool isFG, otherIsFG;
     GetDecorationColor(decColor, isFG);
     aOther.GetDecorationColor(otherDecColor, otherIsFG);
     if (isFG != otherIsFG || (!isFG && decColor != otherDecColor)) {
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
     }
 
     if (mTextOverflow != aOther.mTextOverflow) {
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
     }
     return NS_STYLE_HINT_NONE;
   }
   return NS_STYLE_HINT_REFLOW;
 }
 
 #ifdef DEBUG
 /* static */
@@ -2957,17 +2960,17 @@ nsChangeHint nsStyleUserInterface::CalcD
     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
 
   // We could do better. But it wouldn't be worth it, URL-specified cursors are
   // rare.
   if (mCursorArrayLength > 0 || aOther.mCursorArrayLength > 0)
     NS_UpdateHint(hint, nsChangeHint_UpdateCursor);
 
   if (mUserModify != aOther.mUserModify)
-    NS_UpdateHint(hint, NS_STYLE_HINT_VISUAL);
+    NS_UpdateHint(hint, nsChangeHint_RepaintFrame);
   
   if ((mUserInput != aOther.mUserInput) &&
       ((NS_STYLE_USER_INPUT_NONE == mUserInput) || 
        (NS_STYLE_USER_INPUT_NONE == aOther.mUserInput))) {
     NS_UpdateHint(hint, NS_STYLE_HINT_FRAMECHANGE);
   }
 
   // ignore mUserFocus
@@ -3032,17 +3035,17 @@ nsChangeHint nsStyleUIReset::CalcDiffere
     return NS_STYLE_HINT_FRAMECHANGE;
   if (mWindowShadow != aOther.mWindowShadow) {
     // We really need just an nsChangeHint_SyncFrameView, except
     // on an ancestor of the frame, so we get that by doing a
     // reflow.
     return NS_STYLE_HINT_REFLOW;
   }
   if (mUserSelect != aOther.mUserSelect)
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
   return NS_STYLE_HINT_NONE;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleUIReset::MaxDifference()
 {
   return NS_STYLE_HINT_FRAMECHANGE;