Bug 1126038 - Finish decoding off-main-thread. r=tn

This commit is contained in:
Seth Fowler 2015-01-26 22:53:20 -08:00
Родитель 6932daf12e
Коммит 407444f3a3
2 изменённых файлов: 43 добавлений и 24 удалений

Просмотреть файл

@ -35,6 +35,7 @@ Decoder::Decoder(RasterImage* aImage)
, mDecodeDone(false)
, mDataError(false)
, mDecodeAborted(false)
, mShouldReportError(false)
, mImageIsTransient(false)
, mImageIsLocked(false)
, mFrameCount(0)
@ -146,6 +147,7 @@ Decoder::Decode()
PostDataError();
}
CompleteDecode();
return finalStatus;
}
@ -154,6 +156,7 @@ Decoder::Decode()
Write(mIterator->Data(), mIterator->Length());
}
CompleteDecode();
return HasError() ? NS_ERROR_FAILURE : NS_OK;
}
@ -241,10 +244,8 @@ Decoder::Write(const char* aBuffer, uint32_t aCount)
}
void
Decoder::Finish()
Decoder::CompleteDecode()
{
MOZ_ASSERT(NS_IsMainThread());
// Implementation-specific finalization
if (!HasError())
FinishInternal();
@ -255,10 +256,39 @@ Decoder::Finish()
// If PostDecodeDone() has not been called, and this decoder wasn't aborted
// early because of low-memory conditions or losing a race with another
// decoder, we need to send teardown notifications.
// decoder, we need to send teardown notifications (and report an error to the
// console later).
if (!IsSizeDecode() && !mDecodeDone && !WasAborted()) {
mShouldReportError = true;
// Log data errors to the error console
// If we only have a data error, we're usable if we have at least one
// complete frame.
if (!HasDecoderError() && GetCompleteFrameCount() > 0) {
// We're usable, so do exactly what we should have when the decoder
// completed.
if (mInFrame) {
PostFrameStop();
}
PostDecodeDone();
} else {
// We're not usable. Record some final progress indicating the error.
if (!IsSizeDecode()) {
mProgress |= FLAG_DECODE_COMPLETE | FLAG_ONLOAD_UNBLOCKED;
}
mProgress |= FLAG_HAS_ERROR;
}
}
}
void
Decoder::Finish()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(HasError() || !mInFrame, "Finishing while we're still in a frame");
// If we detected an error in CompleteDecode(), log it to the error console.
if (mShouldReportError && !WasAborted()) {
nsCOMPtr<nsIConsoleService> consoleService =
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
nsCOMPtr<nsIScriptError> errorObject =
@ -277,23 +307,6 @@ Decoder::Finish()
consoleService->LogMessage(errorObject);
}
}
// If we only have a data error, we're usable if we have at least one
// complete frame.
if (!HasDecoderError() && GetCompleteFrameCount() > 0) {
// We're usable, so do exactly what we should have when the decoder
// completed.
if (mInFrame) {
PostFrameStop();
}
PostDecodeDone();
} else {
// We're not usable. Record some final progress indicating the error.
if (!IsSizeDecode()) {
mProgress |= FLAG_DECODE_COMPLETE | FLAG_ONLOAD_UNBLOCKED;
}
mProgress |= FLAG_HAS_ERROR;
}
}
// Set image metadata before calling DecodingComplete, because
@ -321,8 +334,6 @@ Decoder::Finish()
void
Decoder::FinishSharedDecoder()
{
MOZ_ASSERT(NS_IsMainThread());
if (!HasError()) {
FinishInternal();
}

Просмотреть файл

@ -402,6 +402,13 @@ protected:
// flush the data; see the documentation for that method.
bool NeedsToFlushData() const { return mNeedsToFlushData; }
/**
* CompleteDecode() finishes up the decoding process after Decode() determines
* that we're finished. It records final progress and does all the cleanup
* that's possible off-main-thread.
*/
void CompleteDecode();
/**
* Ensures that a given frame number exists with the given parameters, and
* returns a RawAccessFrameRef for that frame.
@ -457,6 +464,7 @@ protected:
bool mDecodeDone;
bool mDataError;
bool mDecodeAborted;
bool mShouldReportError;
bool mImageIsTransient;
bool mImageIsLocked;