Bug 1386864 - Part 2. Implement CompareLayers to reuse the code in AddAndRemoveImageAssociations. draft
authorcku <cku@mozilla.com>
Fri, 04 Aug 2017 17:01:21 +0800
changeset 621072 cb2be8307f78b4ecdeaa90ad4cb9daf902ee2af7
parent 621071 74bd6d449a48e819f61660aef707f946508b71c6
child 640887 ab2c16b207dc0b79e36dcea7d1b0a2b64fce319a
push id72244
push userbmo:cku@mozilla.com
push dateFri, 04 Aug 2017 09:08:25 +0000
bugs1386864
milestone57.0a1
Bug 1386864 - Part 2. Implement CompareLayers to reuse the code in AddAndRemoveImageAssociations. MozReview-Commit-ID: Aw9uJ8UFipj
layout/generic/nsFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -825,69 +825,66 @@ nsFrame::GetOffsets(int32_t &aStart, int
 {
   aStart = 0;
   aEnd = 0;
   return NS_OK;
 }
 
 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*>(