Bug 1386864 - Part 2. Implement CompareLayers to reuse the code in AddAndRemoveImageAssociations. r=heycam
authorcku <cku@mozilla.com>
Fri, 04 Aug 2017 17:01:21 +0800
changeset 373163 7f21a31de9faa0ba282c541efdf1017e86a74c69
parent 373162 2dc62e1b19a9802ce958066629522b46f6f4d19a
child 373164 347ea0d06092d7fcd6c34e2c7ade389b0b71ae31
push id48126
push usercku@mozilla.com
push dateMon, 07 Aug 2017 05:30:09 +0000
treeherderautoland@7f21a31de9fa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1386864
milestone57.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 1386864 - Part 2. Implement CompareLayers to reuse the code in AddAndRemoveImageAssociations. r=heycam MozReview-Commit-ID: Aw9uJ8UFipj
layout/generic/nsFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -823,71 +823,66 @@ nsFrame::DestroyFrom(nsIFrame* aDestruct
 nsresult
 nsFrame::GetOffsets(int32_t &aStart, int32_t &aEnd) const
 {
   aStart = 0;
   aEnd = 0;
   return NS_OK;
 }
 
-static
-void
+static void
+CompareLayers(const nsStyleImageLayers* aFirstLayers,
+              const nsStyleImageLayers* aSecondLayers,
+              const std::function<void(imgRequestProxy* aReq)>& aCallback)
+{
+  NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, (*aFirstLayers)) {
+    const nsStyleImage& image = aFirstLayers->mLayers[i].mImage;
+    if (image.GetType() != eStyleImageType_Image || !image.IsResolved()) {
+      continue;
+    }
+
+    // aCallback is called when the style image in aFirstLayers is thought to
+    // be different with the corresponded one in aSecondLayers
+    if (!aSecondLayers || i >= aSecondLayers->mImageCount ||
+        (!aSecondLayers->mLayers[i].mImage.IsResolved() ||
+         !image.ImageDataEquals(aSecondLayers->mLayers[i].mImage))) {
+      if (imgRequestProxy* req = image.GetImageData()) {
+        aCallback(req);
+      }
+    }
+  }
+}
+
+static void
 AddAndRemoveImageAssociations(nsFrame* aFrame,
                               const nsStyleImageLayers* aOldLayers,
                               const nsStyleImageLayers* aNewLayers)
 {
    ImageLoader* imageLoader =
      aFrame->PresContext()->Document()->StyleImageLoader();
 
   // If the old context had a background-image image, or mask-image image,
   // and new context does not have the same image, clear the image load
   // notifier (which keeps the image loading, if it still is) for the frame.
   // We want to do this conservatively because some frames paint their
   // backgrounds from some other frame's style data, and we don't want
   // to clear those notifiers unless we have to.  (They'll be reset
   // when we paint, although we could miss a notification in that
   // interval.)
-
   if (aOldLayers) {
-    NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, (*aOldLayers)) {
-      const nsStyleImage& oldImage = aOldLayers->mLayers[i].mImage;
-      if (oldImage.GetType() != eStyleImageType_Image ||
-          !oldImage.IsResolved()) {
-        continue;
-      }
-
-      // If there is an image in oldBG that's not in newBG, drop it.
-      if (i >= aNewLayers->mImageCount ||
-          (!aNewLayers->mLayers[i].mImage.IsResolved() ||
-           !oldImage.ImageDataEquals(aNewLayers->mLayers[i].mImage))) {
-        if (aFrame->HasImageRequest()) {
-          if (imgRequestProxy* req = oldImage.GetImageData()) {
-            imageLoader->DisassociateRequestFromFrame(req, aFrame);
-          }
-        }
-      }
-    }
-  }
-
-  NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, (*aNewLayers)) {
-    const nsStyleImage& newImage = aNewLayers->mLayers[i].mImage;
-    if (newImage.GetType() != eStyleImageType_Image ||
-        !newImage.IsResolved()) {
-      continue;
-    }
-
-    // If there is an image in newBG that's not in oldBG, add it.
-    if (!aOldLayers || i >= aOldLayers->mImageCount ||
-        (!aOldLayers->mLayers[i].mImage.IsResolved() ||
-         !newImage.ImageDataEquals(aOldLayers->mLayers[i].mImage))) {
-      if (imgRequestProxy* req = newImage.GetImageData()) {
-        imageLoader->AssociateRequestToFrame(req, aFrame);
-      }
-    }
-  }
+    CompareLayers(aOldLayers, aNewLayers,
+      [&imageLoader, aFrame](imgRequestProxy* aReq)
+      { imageLoader->DisassociateRequestFromFrame(aReq, aFrame); }
+    );
+  }
+
+  CompareLayers(aNewLayers, aOldLayers,
+    [&imageLoader, aFrame](imgRequestProxy* aReq)
+    { imageLoader->AssociateRequestToFrame(aReq, aFrame); }
+  );
 }
 
 // Subclass hook for style post processing
 /* virtual */ void
 nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   if (nsSVGUtils::IsInSVGTextSubtree(this)) {
     SVGTextFrame* svgTextFrame = static_cast<SVGTextFrame*>(