Bug 1304437 - Part 1. Return nsChangeHint_UpdateEffects when the length of the mask-image property has changed. a=ritu
authorcku <cku@mozilla.com>
Mon, 26 Sep 2016 11:06:32 +0800
changeset 350422 d1baa416e1b9c1a3729153301b4b3ef1786236ba
parent 350421 2704e305065955cf0f5e448202fa3df1014c0bae
child 350423 583b7822b8b87ed781e9a21b58551442713892c5
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersritu
bugs1304437
milestone50.0
Bug 1304437 - Part 1. Return nsChangeHint_UpdateEffects when the length of the mask-image property has changed. a=ritu MozReview-Commit-ID: DN42OJLcAHo
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -1304,17 +1304,18 @@ nsStyleSVGReset::CalcDifference(const ns
              mFloodColor    != aNewData.mFloodColor    ||
              mLightingColor != aNewData.mLightingColor ||
              mStopOpacity   != aNewData.mStopOpacity   ||
              mFloodOpacity  != aNewData.mFloodOpacity  ||
              mMaskType      != aNewData.mMaskType) {
     hint |= nsChangeHint_RepaintFrame;
   }
 
-  hint |= mMask.CalcDifference(aNewData.mMask, nsChangeHint_RepaintFrame);
+  hint |= mMask.CalcDifference(aNewData.mMask,
+                               nsStyleImageLayers::LayerType::Mask);
 
   return hint;
 }
 
 // nsStyleSVGPaint implementation
 nsStyleSVGPaint::nsStyleSVGPaint(nsStyleSVGPaintType aType)
   : mType(nsStyleSVGPaintType(0))
   , mFallbackColor(NS_RGB(0, 0, 0))
@@ -2415,46 +2416,56 @@ nsStyleImageLayers::nsStyleImageLayers(c
     mMaskModeCount = std::max(mMaskModeCount, count);
     mBlendModeCount = std::max(mBlendModeCount, count);
     mCompositeCount = std::max(mCompositeCount, count);
   }
 }
 
 nsChangeHint
 nsStyleImageLayers::CalcDifference(const nsStyleImageLayers& aNewLayers,
-                                   nsChangeHint aPositionChangeHint) const
+                                   nsStyleImageLayers::LayerType aType) const
 {
+  nsChangeHint positionChangeHint =
+    (aType == nsStyleImageLayers::LayerType::Background)
+    ? nsChangeHint_UpdateBackgroundPosition
+    : nsChangeHint_RepaintFrame;
+
   nsChangeHint hint = nsChangeHint(0);
 
   const nsStyleImageLayers& moreLayers =
     mImageCount > aNewLayers.mImageCount ?
       *this : aNewLayers;
   const nsStyleImageLayers& lessLayers =
     mImageCount > aNewLayers.mImageCount ?
       aNewLayers : *this;
 
   NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, moreLayers) {
     if (i < lessLayers.mImageCount) {
       nsChangeHint layerDifference =
         moreLayers.mLayers[i].CalcDifference(lessLayers.mLayers[i],
-                                             aPositionChangeHint);
+                                             positionChangeHint);
       hint |= layerDifference;
       if (layerDifference &&
           ((moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) ||
            (lessLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element))) {
         hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
       }
     } else {
       hint |= nsChangeHint_RepaintFrame;
       if (moreLayers.mLayers[i].mImage.GetType() == eStyleImageType_Element) {
         hint |= nsChangeHint_UpdateEffects | nsChangeHint_RepaintFrame;
       }
     }
   }
 
+  if (aType == nsStyleImageLayers::LayerType::Mask &&
+      mImageCount != aNewLayers.mImageCount) {
+    hint |= nsChangeHint_UpdateEffects;
+  }
+
   if (hint) {
     return hint;
   }
 
   if (mAttachmentCount != aNewLayers.mAttachmentCount ||
       mBlendModeCount != aNewLayers.mBlendModeCount ||
       mClipCount != aNewLayers.mClipCount ||
       mCompositeCount != aNewLayers.mCompositeCount ||
@@ -2710,17 +2721,17 @@ nsStyleImageLayers::Layer::operator==(co
 }
 
 nsChangeHint
 nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewLayer,
                                           nsChangeHint aPositionChangeHint) const
 {
   nsChangeHint hint = nsChangeHint(0);
   if (!EqualURIs(mSourceURI, aNewLayer.mSourceURI)) {
-    hint |= nsChangeHint_RepaintFrame;
+    hint |= nsChangeHint_RepaintFrame | nsChangeHint_UpdateEffects;
 
     // If Layer::mSourceURI links to a SVG mask, it has a fragment. Not vice
     // versa. Here are examples of URI contains a fragment, two of them link
     // to a SVG mask:
     //   mask:url(a.svg#maskID); // The fragment of this URI is an ID of a mask
     //                           // element in a.svg.
     //   mask:url(#localMaskID); // The fragment of this URI is an ID of a mask
     //                           // element in local document.
@@ -2731,20 +2742,19 @@ nsStyleImageLayers::Layer::CalcDifferenc
     bool maybeSVGMask = false;
     if (mSourceURI) {
       mSourceURI->GetHasRef(&maybeSVGMask);
     }
     if (!maybeSVGMask && aNewLayer.mSourceURI) {
       aNewLayer.mSourceURI->GetHasRef(&maybeSVGMask);
     }
 
-    // Return nsChangeHint_UpdateEffects and nsChangeHint_UpdateOverflow if
-    // either URI might link to an SVG mask.
+    // Return nsChangeHint_UpdateOverflow if either URI might link to an SVG
+    // mask.
     if (maybeSVGMask) {
-      hint |= nsChangeHint_UpdateEffects;
       // Mask changes require that we update the PreEffectsBBoxProperty,
       // which is done during overflow computation.
       hint |= nsChangeHint_UpdateOverflow;
     }
   } else if (mAttachment != aNewLayer.mAttachment ||
              mClip != aNewLayer.mClip ||
              mOrigin != aNewLayer.mOrigin ||
              mRepeat != aNewLayer.mRepeat ||
@@ -2801,17 +2811,17 @@ nsChangeHint
 nsStyleBackground::CalcDifference(const nsStyleBackground& aNewData) const
 {
   nsChangeHint hint = nsChangeHint(0);
   if (mBackgroundColor != aNewData.mBackgroundColor) {
     hint |= nsChangeHint_RepaintFrame;
   }
 
   hint |= mImage.CalcDifference(aNewData.mImage,
-                                nsChangeHint_UpdateBackgroundPosition);
+                                nsStyleImageLayers::LayerType::Background);
 
   return hint;
 }
 
 bool
 nsStyleBackground::HasFixedBackground(nsIFrame* aFrame) const
 {
   NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, mImage) {
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -765,17 +765,17 @@ struct nsStyleImageLayers {
     }
   }
   void UntrackImages(nsPresContext* aContext) {
     for (uint32_t i = 0; i < mImageCount; ++i)
       mLayers[i].UntrackImages(aContext);
   }
 
   nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
-                              nsChangeHint aPositionChangeHint) const;
+                              nsStyleImageLayers::LayerType aType) const;
 
   bool HasLayerWithImage() const;
 
   static const nsCSSProperty kBackgroundLayerTable[];
   static const nsCSSProperty kMaskLayerTable[];
 
   #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
     for (uint32_t var_ = (layers_).mImageCount; var_-- != 0; )