Bug 1079627 (Part 6) - Lock the image during decoding. r=tn a=lmandel
authorSeth Fowler <seth@mozilla.com>
Thu, 15 Jan 2015 15:11:36 -0800
changeset 249809 3aa609c00599f68a6465e6ced57e8ebe28e551f6
parent 249808 5586653fe1255091a0a5a0b41673f990321d1619
child 249810 fca7fcc6ab86dd65377f65f0cce614593199d820
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn, lmandel
bugs1079627
milestone37.0a2
Bug 1079627 (Part 6) - Lock the image during decoding. r=tn a=lmandel
image/src/RasterImage.cpp
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -1438,22 +1438,26 @@ RasterImage::Decode(DecodeStrategy aStra
   }
 
   // Create a decoder.
   nsRefPtr<Decoder> decoder = CreateDecoder(aDoSizeDecode, aFlags);
   if (!decoder) {
     return NS_ERROR_FAILURE;
   }
 
-  // Send out early notifications right away. (Unless this is a size decode,
-  // which doesn't send out any notifications until the end.)
   if (!aDoSizeDecode) {
+    // Send out early notifications right away.
     NotifyProgress(decoder->TakeProgress(),
                    decoder->TakeInvalidRect(),
                    decoder->GetDecodeFlags());
+
+    // Lock the image while we're decoding, so that it doesn't get evicted from
+    // the SurfaceCache before we have a chance to realize that it's animated.
+    // The corresponding unlock happens in FinalizeDecoder.
+    LockImage();
   }
 
   if (mHasSourceData) {
     // If we have all the data, we can sync decode if requested.
     if (aStrategy == DecodeStrategy::SYNC_FOR_SMALL_IMAGES) {
       PROFILER_LABEL_PRINTF("DecodePool", "SyncDecodeIfSmall",
         js::ProfileEntry::Category::GRAPHICS, "%s", GetURIString().get());
       DecodePool::Singleton()->SyncDecodeIfSmall(decoder);
@@ -1900,16 +1904,21 @@ RasterImage::FinalizeDecoder(Decoder* aD
     // Detect errors.
     if (aDecoder->HasError() && !aDecoder->WasAborted()) {
       DoError();
     } else if (wasSize && !mHasSize) {
       DoError();
     }
   }
 
+  if (!wasSize) {
+    // Unlock the image, balancing the LockImage call we made in Decode().
+    UnlockImage();
+  }
+
   // If we were a size decode and a full decode was requested, now's the time.
   if (done && wasSize && mWantFullDecode) {
     mWantFullDecode = false;
     RequestDecode();
   }
 }
 
 already_AddRefed<imgIContainer>