Bug 721510 - Always decode at least one chunk in RasterImage::DecodeWorker::DecodeSomeOfImage. r=joe
authorJustin Lebar <justin.lebar@gmail.com>
Fri, 27 Jan 2012 12:09:01 -0500
changeset 86859 1583548890073075f9c57c80e48e7e9b0e376d4b
parent 86858 9dd8e5d526b829e8d4afeee46f121cd1dbab5839
child 86860 731208933852757138212cf2c2faf20371da8233
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs721510
milestone12.0a1
Bug 721510 - Always decode at least one chunk in RasterImage::DecodeWorker::DecodeSomeOfImage. r=joe
image/src/RasterImage.cpp
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -2964,62 +2964,60 @@ RasterImage::DecodeWorker::DecodeSomeOfI
   if (aDecodeType == DECODE_TYPE_UNTIL_SIZE && aImg->mHasSize)
     return NS_OK;
 
   // If an error is flagged, it probably happened while we were waiting
   // in the event queue.
   if (aImg->mError)
     return NS_OK;
 
-  // If we don't have a decoder, we must have finished already (for example,
-  // a synchronous decode request came while the worker was pending).
-  if (!aImg->mDecoder)
+  // If mDecoded or we don't have a decoder, we must have finished already (for
+  // example, a synchronous decode request came while the worker was pending).
+  if (!aImg->mDecoder || aImg->mDecoded)
     return NS_OK;
 
   nsRefPtr<Decoder> decoderKungFuDeathGrip = aImg->mDecoder;
 
   PRUint32 maxBytes;
   if (aImg->mDecoder->IsSizeDecode()) {
     // Decode all available data if we're a size decode; they're cheap, and we
     // want them to be more or less synchronous.
     maxBytes = aImg->mSourceData.Length();
   } else {
     // We're only guaranteed to decode this many bytes, so in particular,
     // gDecodeBytesAtATime should be set high enough for us to read the size
     // from most images.
     maxBytes = gDecodeBytesAtATime;
   }
 
-  // Loop control
   PRInt32 chunkCount = 0;
   TimeStamp start = TimeStamp::Now();
   TimeStamp deadline = start + TimeDuration::FromMilliseconds(gMaxMSBeforeYield);
 
-  // We keep decoding chunks until one of events occurs:
-  // 1) We don't have any data left to decode
-  // 2) The decode completes
-  // 3) We're an UNTIL_SIZE decode and we get the size
-  // 4) We hit the deadline and yield to keep the UI snappy
-  while (aImg->mSourceData.Length() > aImg->mBytesDecoded &&
-         !aImg->IsDecodeFinished() &&
-         TimeStamp::Now() < deadline) {
-
-    // Decode a chunk of data.
+  // Decode some chunks of data.
+  do {
     chunkCount++;
     nsresult rv = aImg->DecodeSomeData(maxBytes);
     if (NS_FAILED(rv)) {
       aImg->DoError();
       return rv;
     }
 
-    // If we're an UNTIL_SIZE decode and we got the image's size, we're done
-    // here.
+    // We keep decoding chunks until either:
+    //  * we're an UNTIL_SIZE decode and we get the size,
+    //  * we don't have any data left to decode,
+    //  * the decode completes, or
+    //  * we run out of time.
+
     if (aDecodeType == DECODE_TYPE_UNTIL_SIZE && aImg->mHasSize)
       break;
   }
+  while (aImg->mSourceData.Length() > aImg->mBytesDecoded &&
+         !aImg->IsDecodeFinished() &&
+         TimeStamp::Now() < deadline);
 
   aImg->mDecodeRequest.mDecodeTime += (TimeStamp::Now() - start);
 
   if (chunkCount && !aImg->mDecoder->IsSizeDecode()) {
     Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, chunkCount);
   }
 
   // Flush invalidations _after_ we've written everything we're going to.