Bug 1402157 - Disassociate a frame with an image loader if that frame indeed has any image request. draft
authorcku <cku@mozilla.com>
Fri, 13 Oct 2017 14:03:44 +0800
changeset 682334 835239788497126e3be33a0dbbb0543e94fc9f18
parent 682254 a29052590fc6538b89641e690d11731ca8e78120
child 682335 75545316c72d9fe2081b7244c1e5c63222f40465
push id85073
push usercku@mozilla.com
push dateWed, 18 Oct 2017 13:29:05 +0000
bugs1402157
milestone58.0a1
Bug 1402157 - Disassociate a frame with an image loader if that frame indeed has any image request. Before enable stylo, an image request is always been resolved before the creation time of that request object[1]. As a result, in AddAndRemoveImageAssociations, we always associate the request objects of style images with the given frame(since they are resolved). After enable stylo, an image request is resolved after that object been created[2]. We may hit the assertion reported in this bug by the following senario: 1. AddAndRemoveImageAssociations is called. The image request is not resolved yet, so we do not associate that frame with that image request. 2. That image request is been resolved via nsStyleXXXX::FinishStyle. 3. Style changed. AddAndRemoveImageAssociations is called again. We try to dis-associate the frame with image request and hit this assertion since this frame is not associate with any image request at step #1. [1] We use this constructor if the backend is gecko https://hg.mozilla.org/mozilla-central/file/5ed2f3c94155/layout/style/nsStyleStruct.cpp#l2131 [2] We use this constructor if the backend is stylo https://hg.mozilla.org/mozilla-central/file/5ed2f3c94155/layout/style/nsStyleStruct.cpp#l2147 MozReview-Commit-ID: 22trSbdogUH
layout/generic/nsFrame.cpp
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -868,17 +868,17 @@ AddAndRemoveImageAssociations(nsFrame* a
   // 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) {
+  if (aOldLayers && aFrame->HasImageRequest()) {
     CompareLayers(aOldLayers, aNewLayers,
       [&imageLoader, aFrame](imgRequestProxy* aReq)
       { imageLoader->DisassociateRequestFromFrame(aReq, aFrame); }
     );
   }
 
   CompareLayers(aNewLayers, aOldLayers,
     [&imageLoader, aFrame](imgRequestProxy* aReq)