Bug 719177 - Changes to 'text-shadow' and 'box-shadow' only needs to update the overflow areas and repaint, not reflow. Changes to border style/color/etc only needs repaint, not SyncFrameView. r=roc
authorMats Palmgren <matspal@gmail.com>
Sat, 28 Jan 2012 04:35:58 +0100
changeset 85636 8f11aaac24dcb1415e9684a632bf60d887b409e0
parent 85635 731208933852757138212cf2c2faf20371da8233
child 85637 f222fbece9833a7a500bfb1408f0a346a898c567
push id21940
push userjdrew@mozilla.com
push dateSun, 29 Jan 2012 02:43:03 +0000
treeherdermozilla-central@ec666b4c8d84 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs719177
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 719177 - Changes to 'text-shadow' and 'box-shadow' only needs to update the overflow areas and repaint, not reflow. Changes to border style/color/etc only needs repaint, not SyncFrameView. r=roc
layout/style/nsStyleStruct.cpp
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -534,74 +534,76 @@ nsStyleBorder::Destroy(nsPresContext* aC
   if (mBorderImageSource)
     UntrackImage(aContext);
   this->~nsStyleBorder();
   aContext->FreeToShell(sizeof(nsStyleBorder), this);
 }
 
 nsChangeHint nsStyleBorder::CalcDifference(const nsStyleBorder& aOther) const
 {
-  nsChangeHint shadowDifference =
-    CalcShadowDifference(mBoxShadow, aOther.mBoxShadow);
-
   // Note that differences in mBorder don't affect rendering (which should only
   // use mComputedBorder), so don't need to be tested for here.
   // XXXbz we should be able to return a more specific change hint for
   // at least GetActualBorder() differences...
   if (mTwipsPerPixel != aOther.mTwipsPerPixel ||
       GetActualBorder() != aOther.GetActualBorder() ||
       mFloatEdge != aOther.mFloatEdge ||
-      mBorderImageOutset != aOther.mBorderImageOutset ||
-      (shadowDifference & nsChangeHint_ReflowFrame))
+      mBorderImageOutset != aOther.mBorderImageOutset)
     return NS_STYLE_HINT_REFLOW;
 
+  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
   // 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 NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
   }
 
   if (mBorderRadius != aOther.mBorderRadius ||
       !mBorderColors != !aOther.mBorderColors)
-    return NS_STYLE_HINT_VISUAL;
+    return nsChangeHint_RepaintFrame;
 
   if (IsBorderImageLoaded() || aOther.IsBorderImageLoaded()) {
     if (mBorderImageSource  != aOther.mBorderImageSource  ||
         mBorderImageRepeatH != aOther.mBorderImageRepeatH ||
         mBorderImageRepeatV != aOther.mBorderImageRepeatV ||
         mBorderImageSlice   != aOther.mBorderImageSlice   ||
         mBorderImageFill    != aOther.mBorderImageFill    ||
         mBorderImageWidth   != aOther.mBorderImageWidth   ||
         mBorderImageOutset  != aOther.mBorderImageOutset)
-      return NS_STYLE_HINT_VISUAL;
+      return nsChangeHint_RepaintFrame;
   }
 
   // Note that at this point if mBorderColors is non-null so is
   // aOther.mBorderColors
   if (mBorderColors) {
     NS_FOR_CSS_SIDES(ix) {
       if (!nsBorderColors::Equal(mBorderColors[ix],
                                  aOther.mBorderColors[ix]))
-        return NS_STYLE_HINT_VISUAL;
+        return nsChangeHint_RepaintFrame;
     }
   }
 
-  return shadowDifference;
+  return NS_STYLE_HINT_NONE;
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleBorder::MaxDifference()
 {
-  return NS_STYLE_HINT_REFLOW;
+  return NS_CombineHint(nsChangeHint_UpdateOverflow,
+                        NS_STYLE_HINT_REFLOW);
 }
 #endif
 
 void
 nsStyleBorder::TrackImage(nsPresContext* aContext)
 {
   // Sanity
   NS_ABORT_IF_FALSE(!mImageTracked, "Already tracking image!");
@@ -2778,33 +2780,31 @@ nsChangeHint nsStyleTextReset::CalcDiffe
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleTextReset::MaxDifference()
 {
   return NS_STYLE_HINT_REFLOW;
 }
 #endif
 
-// Allowed to return one of NS_STYLE_HINT_NONE, NS_STYLE_HINT_REFLOW
-// or NS_STYLE_HINT_VISUAL. Currently we just return NONE or REFLOW, though.
-// XXXbz can this not return a more specific hint?  If that's ever
-// changed, nsStyleBorder::CalcDifference will need changing too.
 static nsChangeHint
 CalcShadowDifference(nsCSSShadowArray* lhs,
                      nsCSSShadowArray* rhs)
 {
   if (lhs == rhs)
     return NS_STYLE_HINT_NONE;
 
+  const nsChangeHint kUpdateOverflowAndRepaintHint =
+    NS_CombineHint(nsChangeHint_UpdateOverflow, nsChangeHint_RepaintFrame);
   if (!lhs || !rhs || lhs->Length() != rhs->Length())
-    return NS_STYLE_HINT_REFLOW;
+    return kUpdateOverflowAndRepaintHint;
 
   for (PRUint32 i = 0; i < lhs->Length(); ++i) {
     if (*lhs->ShadowAt(i) != *rhs->ShadowAt(i))
-      return NS_STYLE_HINT_REFLOW;
+      return kUpdateOverflowAndRepaintHint;
   }
   return NS_STYLE_HINT_NONE;
 }
 
 // --------------------
 // nsStyleText
 //
 
@@ -2874,17 +2874,18 @@ nsChangeHint nsStyleText::CalcDifference
 
   return CalcShadowDifference(mTextShadow, aOther.mTextShadow);
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleText::MaxDifference()
 {
-  return NS_STYLE_HINT_FRAMECHANGE;
+  return NS_CombineHint(nsChangeHint_UpdateOverflow,
+                        NS_STYLE_HINT_FRAMECHANGE);
 }
 #endif
 
 //-----------------------
 // nsStyleUserInterface
 //
 
 nsCursorImage::nsCursorImage()