Bug 1457532 Part 2: Change ImageLoader::AssociateRequestToFrame to kickoff decode for images that block onload. draft
authorBrad Werth <bwerth@mozilla.com>
Tue, 08 May 2018 14:13:56 -0700
changeset 795481 8862da462be03265f55c4ee81a6a0e9ac17efbff
parent 795359 0c373e28eeb08ed993bbf40106c3328bfb0c8a13
push id109988
push userbwerth@mozilla.com
push dateTue, 15 May 2018 20:41:42 +0000
bugs1457532
milestone62.0a1
Bug 1457532 Part 2: Change ImageLoader::AssociateRequestToFrame to kickoff decode for images that block onload. MozReview-Commit-ID: DpBqTzMLQXo
layout/style/ImageLoader.cpp
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -110,16 +110,39 @@ ImageLoader::AssociateRequestToFrame(img
         mDocument->BlockOnload();
 
         // We need to stay blocked until we get a reflow. If the first frame
         // is not yet decoded, we'll trigger that reflow from onFrameComplete.
         // But if the first frame is already decoded, we need to trigger that
         // reflow now, because we'll never get a call to onFrameComplete.
         if(status & imgIRequest::STATUS_FRAME_COMPLETE) {
           RequestReflowOnFrame(fwfToModify, aRequest);
+        } else {
+          // If we don't already have a complete frame, kickoff decode. This
+          // will ensure that either onFrameComplete or onLoadComplete will
+          // unblock document onload.
+
+          // We want to request decode in such a way that avoids triggering
+          // sync decode. First, we attempt to convert the aRequest into
+          // a imgIContainer. If that succeeds, then aRequest has an image
+          // and we can request decoding for size at zero size, and that will
+          // trigger async decode. If the conversion to imgIContainer is
+          // unsuccessful, then that means aRequest doesn't have an image yet,
+          // which means we can safely call StartDecoding() on it without
+          // triggering any synchronous work.
+          nsCOMPtr<imgIContainer> imgContainer;
+          aRequest->GetImage(getter_AddRefs(imgContainer));
+          if (imgContainer) {
+            imgContainer->RequestDecodeForSize(gfx::IntSize(0, 0),
+              imgIContainer::DECODE_FLAGS_DEFAULT);
+          } else {
+            // It's safe to call StartDecoding directly, since it can't
+            // trigger synchronous decode without an image. Flags are ignored.
+            aRequest->StartDecoding(imgIContainer::FLAG_NONE);
+          }
         }
       }
     }
   }
 
   // Do some sanity checking to ensure that we only add to one mapping
   // iff we also add to the other mapping.
   DebugOnly<bool> didAddToFrameSet(false);