Bug 1291280 - Part 2. Declare nsStyleImageLayers::Layer::mSourceURI as FragmentOrURI r=heycam
authorcku <cku@mozilla.com>
Sat, 06 Aug 2016 06:38:44 +0800
changeset 308534 b2d3fed9052a69a6646618e8a564a2891a4282cd
parent 308533 a854669c61035ad381f60c2b61dd935956abdcad
child 308535 2f4de63ff19e8b7f031d4d711d76f2b82d3fc0a3
push id31135
push usercku@mozilla.com
push dateMon, 08 Aug 2016 06:24:32 +0000
treeherderautoland@2f4de63ff19e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1291280
milestone51.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 1291280 - Part 2. Declare nsStyleImageLayers::Layer::mSourceURI as FragmentOrURI r=heycam MozReview-Commit-ID: 6KFb7MjlLqj
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleNode.cpp
layout/style/nsStyleStruct.cpp
layout/style/nsStyleStruct.h
layout/svg/nsSVGEffects.cpp
layout/svg/nsSVGEffects.h
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2140,22 +2140,20 @@ nsComputedDOMStyle::DoGetImageLayerImage
     //    Since this layer does not refer to any source, Layer::mSourceURI must
     //    be nullptr too.
     // 2. This layer refers to a local resource, e.g. mask-image:url(#mymask).
     //    For local references, there is no need to download any external
     //    resource, so Layer::mImage is not used.
     //    Instead, we store the local URI in one place -- on Layer::mSourceURI.
     //    Hence, we must serialize using mSourceURI (instead of
     //    SetValueToStyleImage()/mImage) in this case.
-    bool isLocalURI = image.GetType() == eStyleImageType_Null &&
-                      aLayers.mLayers[i].mSourceURI;
-    if (isLocalURI) {
+    if (aLayers.mLayers[i].mSourceURI.IsLocalRef()) {
       // This is how we represent a 'mask-image' reference for a local URI,
       // such as 'mask-image:url(#mymask)' or 'mask:url(#mymask)'
-      val->SetURI(aLayers.mLayers[i].mSourceURI);
+      val->SetURI(aLayers.mLayers[i].mSourceURI.GetSourceURL());
     } else {
       SetValueToStyleImage(image, val);
     }
 
     valueList->AppendCSSValue(val.forget());
   }
 
   return valueList.forget();
@@ -6142,18 +6140,18 @@ nsComputedDOMStyle::DoGetMask()
       !firstLayer.mSize.IsInitialValue() ||
       !(firstLayer.mImage.GetType() == eStyleImageType_Null ||
         firstLayer.mImage.GetType() == eStyleImageType_Image)) {
     return nullptr;
   }
 
   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
 
-  if (firstLayer.mSourceURI) {
-    val->SetURI(firstLayer.mSourceURI);
+  if (firstLayer.mSourceURI.GetSourceURL()) {
+    val->SetURI(firstLayer.mSourceURI.GetSourceURL());
   } else {
     val->SetIdent(eCSSKeyword_none);
   }
 
   return val.forget();
 }
 
 #ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -6652,28 +6652,28 @@ struct BackgroundItemComputer<nsCSSValue
                            RuleNodeCacheConditions& aConditions)
   {
     SetStyleImage(aStyleContext, aSpecifiedValue->mValue, aComputedValue,
                   aConditions);
   }
 };
 
 template <>
-struct BackgroundItemComputer<nsCSSValueList, nsCOMPtr<nsIURI> >
+struct BackgroundItemComputer<nsCSSValueList, FragmentOrURL>
 {
   static void ComputeValue(nsStyleContext* aStyleContext,
                            const nsCSSValueList* aSpecifiedValue,
-                           nsCOMPtr<nsIURI>& aComputedValue,
+                           FragmentOrURL& aComputedValue,
                            RuleNodeCacheConditions& aConditions)
   {
     if (eCSSUnit_Image == aSpecifiedValue->mValue.GetUnit() ||
         eCSSUnit_URL == aSpecifiedValue->mValue.GetUnit()) {
-      aComputedValue = aSpecifiedValue->mValue.GetURLValue();
+      aComputedValue.SetValue(&aSpecifiedValue->mValue);
     } else if (eCSSUnit_Null != aSpecifiedValue->mValue.GetUnit()) {
-      aComputedValue = nullptr;
+      aComputedValue.SetNull();
     }
   }
 };
 
 /* Helper function for ComputePositionValue.
  * This function computes a single PositionCoord from two nsCSSValue objects,
  * which represent an edge and an offset from that edge.
  */
@@ -10077,21 +10077,21 @@ nsRuleNode::ComputeSVGResetData(void* aS
     FillBackgroundList(svgReset->mMask.mLayers,
                        &nsStyleImageLayers::Layer::mComposite,
                        svgReset->mMask.mCompositeCount, fillCount);
   }
 #else
   // mask: none | <url>
   const nsCSSValue* maskValue = aRuleData->ValueForMask();
   if (eCSSUnit_URL == maskValue->GetUnit()) {
-    svgReset->mMask.mLayers[0].mSourceURI = maskValue->GetURLValue();
+    svgReset->mMask.mLayers[0].mSourceURI.SetValue(maskValue);
   } else if (eCSSUnit_None == maskValue->GetUnit() ||
              eCSSUnit_Initial == maskValue->GetUnit() ||
              eCSSUnit_Unset == maskValue->GetUnit()) {
-    svgReset->mMask.mLayers[0].mSourceURI = nullptr;
+    svgReset->mMask.mLayers[0].mSourceURI.SetNull();
   } else if (eCSSUnit_Inherit == maskValue->GetUnit()) {
     conditions.SetUncacheable();
     svgReset->mMask.mLayers[0].mSourceURI =
       parentSVGReset->mMask.mLayers[0].mSourceURI;
   }
 #endif
 
   svgReset->mMask.TrackImages(aContext->PresContext());
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2602,17 +2602,17 @@ bool
 nsStyleImageLayers::HasLayerWithImage() const
 {
   for (uint32_t i = 0; i < mImageCount; i++) {
     // mLayers[i].mSourceURI can be nullptr if mask-image prop value is
     // <element-reference> or <gradient>
     // mLayers[i].mImage can be empty if mask-image prop value is a reference
     // to SVG mask element.
     // So we need to test both mSourceURI and mImage.
-    if (mLayers[i].mSourceURI || !mLayers[i].mImage.IsEmpty()) {
+    if (mLayers[i].mSourceURI.GetSourceURL() || !mLayers[i].mImage.IsEmpty()) {
       return true;
     }
   }
 
   return false;
 }
 
 bool
@@ -2829,44 +2829,51 @@ nsStyleImageLayers::Layer::operator==(co
          mOrigin == aOther.mOrigin &&
          mRepeat == aOther.mRepeat &&
          mBlendMode == aOther.mBlendMode &&
          mPosition == aOther.mPosition &&
          mSize == aOther.mSize &&
          mImage == aOther.mImage &&
          mMaskMode == aOther.mMaskMode &&
          mComposite == aOther.mComposite &&
-         EqualURIs(mSourceURI, aOther.mSourceURI);
+         mSourceURI == aOther.mSourceURI;
 }
 
 nsChangeHint
 nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewLayer,
                                           nsChangeHint aPositionChangeHint) const
 {
   nsChangeHint hint = nsChangeHint(0);
-  if (!EqualURIs(mSourceURI, aNewLayer.mSourceURI)) {
+  if (mSourceURI != aNewLayer.mSourceURI) {
     hint |= nsChangeHint_RepaintFrame;
 
     // 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.
     //   mask:url(b.svg#viewBoxID); // The fragment of this URI is an ID of a
     //                              // viewbox defined in b.svg.
     // That is, if mSourceURI has a fragment, it may link to a SVG mask; If
     // not, it "must" not link to a SVG mask.
     bool maybeSVGMask = false;
-    if (mSourceURI) {
-      mSourceURI->GetHasRef(&maybeSVGMask);
+    if (mSourceURI.IsLocalRef()) {
+      maybeSVGMask = true;
+    } else if (mSourceURI.GetSourceURL()) {
+      mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask);
     }
-    if (!maybeSVGMask && aNewLayer.mSourceURI) {
-      aNewLayer.mSourceURI->GetHasRef(&maybeSVGMask);
+
+    if (!maybeSVGMask) {
+      if (aNewLayer.mSourceURI.IsLocalRef()) {
+        maybeSVGMask = true;
+      } else if (aNewLayer.mSourceURI.GetSourceURL()) {
+        aNewLayer.mSourceURI.GetSourceURL()->GetHasRef(&maybeSVGMask);
+      }
     }
 
     // Return nsChangeHint_UpdateEffects and 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.
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -680,17 +680,17 @@ struct nsStyleImageLayers {
       return !(*this == aOther);
     }
   };
 
   struct Layer;
   friend struct Layer;
   struct Layer {
     nsStyleImage  mImage;         // [reset]
-    nsCOMPtr<nsIURI> mSourceURI;  // [reset]
+    FragmentOrURL mSourceURI;     // [reset]
                                   // mask-only property
                                   // This property is used for mask layer only.
                                   // For a background layer, it should always
                                   // be the initial value, which is nullptr.
                                   // Store mask-image URI so that we can resolve
                                   // SVG mask path later.
     Position      mPosition;      // [reset] See nsStyleConsts.h
     Size          mSize;          // [reset]
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -390,19 +390,19 @@ nsSVGMarkerProperty::DoUpdate()
 
 NS_IMPL_ISUPPORTS(nsSVGMaskProperty, nsISupports)
 
 nsSVGMaskProperty::nsSVGMaskProperty(nsIFrame* aFrame)
 {
   const nsStyleSVGReset *svgReset = aFrame->StyleSVGReset();
 
   for (uint32_t i = 0; i < svgReset->mMask.mImageCount; i++) {
-    nsSVGPaintingProperty* prop =
-      new nsSVGPaintingProperty(svgReset->mMask.mLayers[i].mSourceURI, aFrame,
-                                false);
+    nsCOMPtr<nsIURI> maskUri = nsSVGEffects::GetMaskURI(aFrame, i);
+    nsSVGPaintingProperty* prop = new nsSVGPaintingProperty(maskUri, aFrame,
+                                                            false);
     mProperties.AppendElement(prop);
   }
 }
 
 bool
 nsSVGTextPathProperty::TargetIsValid()
 {
   Element* target = GetTarget();
@@ -959,8 +959,18 @@ nsSVGEffects::GetPaintURI(nsIFrame* aFra
                           nsStyleSVGPaint nsStyleSVG::* aPaint)
 {
   const nsStyleSVG* svgStyle = aFrame->StyleSVG();
   MOZ_ASSERT((svgStyle->*aPaint).mType ==
              nsStyleSVGPaintType::eStyleSVGPaintType_Server);
 
   return ResolveFragmentOrURL(aFrame, (svgStyle->*aPaint).mPaint.mPaintServer);
 }
+
+already_AddRefed<nsIURI>
+nsSVGEffects::GetMaskURI(nsIFrame* aFrame, uint32_t aIndex)
+{
+  const nsStyleSVGReset* svgReset = aFrame->StyleSVGReset();
+  MOZ_ASSERT(svgReset->mMask.mLayers.Length() > aIndex);
+
+  return ResolveFragmentOrURL(aFrame,
+                              &svgReset->mMask.mLayers[aIndex].mSourceURI);
+}
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -619,11 +619,17 @@ public:
   static already_AddRefed<nsIURI>
   GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter);
 
   /**
    * A helper function to resolve paint-server URL.
    */
   static already_AddRefed<nsIURI>
   GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint);
+
+    /**
+   * A helper function to resolve SVG mask URL.
+   */
+  static already_AddRefed<nsIURI>
+  GetMaskURI(nsIFrame* aFrame, uint32_t aIndex);
 };
 
 #endif /*NSSVGEFFECTS_H_*/