Bug 1438207 - Finalize the current frame of an ICO decoder correctly. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 16 Feb 2018 06:27:36 -0500
changeset 404212 4cba9e37198385b69d473e9d7bec14795013c8c9
parent 404145 8cf35a5cc0773e4c0ff0a67f6685dbbbe6b97105
child 404213 42eb9bb1033e11e2f3c8c8cdbaaced162bdb2f59
push id33457
push userrgurzau@mozilla.com
push dateFri, 16 Feb 2018 22:09:48 +0000
treeherdermozilla-central@c4d818c13868 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1438207
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1438207 - Finalize the current frame of an ICO decoder correctly. r=tnikkel Originally we attempted to finalize the current frame from the contained decoder in nsICODecoder::FinishResource. This is wrong because we haven't acquired the frame from the contained decoder yet. This happens in nsICODecoder::GetFinalStateFromContainedDecoder, and so imgFrame::Finalize call should be moved there. This was causing us to use fallback image sharing with WebRender after a GPU process crash, instead of shared surfaces, because it can't get a new file handle for the surface data until we have finished writing all of the image data.
image/decoders/nsICODecoder.cpp
--- a/image/decoders/nsICODecoder.cpp
+++ b/image/decoders/nsICODecoder.cpp
@@ -95,16 +95,23 @@ nsICODecoder::GetFinalStateFromContained
   FlushContainedDecoder();
 
   // Make our state the same as the state of the contained decoder.
   mDecodeDone = mContainedDecoder->GetDecodeDone();
   mProgress |= mContainedDecoder->TakeProgress();
   mInvalidRect.UnionRect(mInvalidRect, mContainedDecoder->TakeInvalidRect());
   mCurrentFrame = mContainedDecoder->GetCurrentFrameRef();
 
+  // Finalize the frame which we deferred to ensure we could modify the final
+  // result (e.g. to apply the BMP mask).
+  MOZ_ASSERT(!mContainedDecoder->GetFinalizeFrames());
+  if (mCurrentFrame) {
+    mCurrentFrame->FinalizeSurface();
+  }
+
   // Propagate errors.
   nsresult rv = HasError() || mContainedDecoder->HasError()
               ? NS_ERROR_FAILURE
               : NS_OK;
 
   MOZ_ASSERT(NS_FAILED(rv) || !mCurrentFrame || mCurrentFrame->IsFinished());
   return rv;
 }
@@ -659,23 +666,16 @@ nsICODecoder::FinishResource()
   if (!mContainedDecoder->IsValidICOResource()) {
     return Transition::TerminateFailure();
   }
 
   // This size from the resource should match that from the dir entry.
   MOZ_ASSERT_IF(mContainedDecoder->HasSize(),
                 mContainedDecoder->Size() == mDirEntry->mSize);
 
-  // Finalize the frame which we deferred to ensure we could modify the final
-  // result (e.g. to apply the BMP mask).
-  MOZ_ASSERT(!mContainedDecoder->GetFinalizeFrames());
-  if (mCurrentFrame) {
-    mCurrentFrame->FinalizeSurface();
-  }
-
   return Transition::TerminateSuccess();
 }
 
 LexerResult
 nsICODecoder::DoDecode(SourceBufferIterator& aIterator, IResumable* aOnResume)
 {
   MOZ_ASSERT(!HasError(), "Shouldn't call DoDecode after error!");