Bug 853564 - Deal with outstanding decoding-done notifications from within RequestDecode so we don't have to wait for the event loop. r=seth

--HG--
extra : rebase_source : 256eb11410196dd09319b02b20111ea87c4b57d6
This commit is contained in:
Joe Drew 2013-04-26 16:43:17 -04:00
parent 7b10404a7a
commit b3bfc6dce1

View File

@ -2748,11 +2748,9 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
if (mError)
return NS_ERROR_FAILURE;
// If we've already got a full decoder running, and have already
// decoded some bytes, we have nothing to do
if (mDecoder && !mDecoder->IsSizeDecode() && mBytesDecoded) {
// If we're already decoded, there's nothing to do.
if (mDecoded)
return NS_OK;
}
// mFinishing protects against the case when we enter RequestDecode from
// ShutdownDecoder -- in that case, we're done with the decode, we're just
@ -2760,6 +2758,11 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
if (mFinishing)
return NS_OK;
// If we're currently waiting for a new frame, we can't do anything until
// that frame is allocated.
if (mDecoder && mDecoder->NeedsNewFrame())
return NS_OK;
// If our callstack goes through a size decoder, we have a problem.
// We need to shutdown the size decode and replace it with a full
// decoder, but can't do that from within the decoder itself. Thus, we post
@ -2784,14 +2787,29 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
}
}
// If we're fully decoded, we have nothing to do. This has to be after
// DecodeUntilSizeAvailable because it can result in a synchronous decode if
// we're already waiting on a full decode.
if (mDecoded)
return NS_OK;
MutexAutoLock lock(mDecodingMutex);
// If the image is waiting for decode work to be notified, go ahead and do that.
if (mDecodeRequest &&
mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
nsresult rv = FinishedSomeDecoding();
CONTAINER_ENSURE_SUCCESS(rv);
}
// If we're fully decoded, we have nothing to do. We need this check after
// DecodeUntilSizeAvailable and FinishedSomeDecoding because they can result
// in us finishing an in-progress decode (or kicking off and finishing a
// synchronous decode if we're already waiting on a full decode).
if (mDecoded) {
return NS_OK;
}
// If we've already got a full decoder running, and have already
// decoded some bytes, we have nothing to do
if (mDecoder && !mDecoder->IsSizeDecode() && mBytesDecoded) {
return NS_OK;
}
// If we have a size decode open, interrupt it and shut it down; or if
// the decoder has different flags than what we need
if (mDecoder && mDecoder->GetDecodeFlags() != mFrameDecodeFlags) {
@ -2810,13 +2828,6 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
MOZ_ASSERT(mDecoder);
}
// If we're waiting for decode work to be notified, go ahead and do that.
if (mDecodeRequest &&
mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
nsresult rv = FinishedSomeDecoding();
CONTAINER_ENSURE_SUCCESS(rv);
}
// If we've read all the data we have, we're done
if (mHasSourceData && mBytesDecoded == mSourceData.Length())
return NS_OK;