Bug 1291071 (Part 5) - Pass the decoder's final status explicitly to FinalizeDecoder(). r=edwin

This commit is contained in:
Seth Fowler 2016-08-02 17:12:36 -07:00
parent 98a9fd7db6
commit 0403b4baba
5 changed files with 64 additions and 16 deletions

View File

@ -267,6 +267,16 @@ Decoder::TakeCompleteFrameCount()
return finishedNewFrame ? Some(GetCompleteFrameCount()) : Nothing();
}
DecoderFinalStatus
Decoder::FinalStatus() const
{
return DecoderFinalStatus(IsMetadataDecode(),
GetDecodeDone(),
WasAborted(),
HasError(),
ShouldReportError());
}
DecoderTelemetry
Decoder::Telemetry() const
{

View File

@ -28,6 +28,39 @@ namespace Telemetry {
namespace image {
struct DecoderFinalStatus final
{
DecoderFinalStatus(bool aWasMetadataDecode,
bool aFinished,
bool aWasAborted,
bool aHadError,
bool aShouldReportError)
: mWasMetadataDecode(aWasMetadataDecode)
, mFinished(aFinished)
, mWasAborted(aWasAborted)
, mHadError(aHadError)
, mShouldReportError(aShouldReportError)
{ }
/// True if this was a metadata decode.
const bool mWasMetadataDecode : 1;
/// True if this decoder finished, whether successfully or due to failure.
const bool mFinished : 1;
/// True if this decoder was asynchronously aborted. This normally happens
/// when a decoder fails to insert a surface into the surface cache, indicating
/// that another decoding beat it to the punch.
const bool mWasAborted : 1;
/// True if this decoder encountered an error.
const bool mHadError : 1;
/// True if this decoder encountered the kind of error that should be reported
/// to the console.
const bool mShouldReportError : 1;
};
struct DecoderTelemetry final
{
DecoderTelemetry(Maybe<Telemetry::ID> aSpeedHistogram,
@ -337,6 +370,10 @@ public:
return gfx::IntRect(gfx::IntPoint(), OutputSize());
}
/// @return final status information about this decoder. Should be called
/// after we decide we're not going to run the decoder anymore.
DecoderFinalStatus FinalStatus() const;
/// @return the metadata we collected about this image while decoding.
const ImageMetadata& GetImageMetadata() { return mImageMetadata; }

View File

@ -64,6 +64,7 @@ IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
"Decode complete in the middle of a frame?");
// Capture the decoder's state.
DecoderFinalStatus finalStatus = aDecoder->FinalStatus();
ImageMetadata metadata = aDecoder->GetImageMetadata();
DecoderTelemetry telemetry = aDecoder->Telemetry();
Progress progress = aDecoder->TakeProgress();
@ -74,7 +75,7 @@ IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
// Synchronously notify if we can.
if (NS_IsMainThread() &&
!(aDecoder->GetDecoderFlags() & DecoderFlags::ASYNC_NOTIFY)) {
aImage->FinalizeDecoder(aDecoder, metadata, telemetry, progress,
aImage->FinalizeDecoder(aDecoder, finalStatus, metadata, telemetry, progress,
invalidRect, frameCount, surfaceFlags);
return;
}
@ -83,8 +84,8 @@ IDecodingTask::NotifyDecodeComplete(NotNull<RasterImage*> aImage,
NotNull<RefPtr<RasterImage>> image = aImage;
NotNull<RefPtr<Decoder>> decoder = aDecoder;
NS_DispatchToMainThread(NS_NewRunnableFunction([=]() -> void {
image->FinalizeDecoder(decoder.get(), metadata, telemetry, progress,
invalidRect, frameCount, surfaceFlags);
image->FinalizeDecoder(decoder.get(), finalStatus, metadata, telemetry,
progress, invalidRect, frameCount, surfaceFlags);
}));
}

View File

@ -1563,6 +1563,7 @@ RasterImage::NotifyProgress(Progress aProgress,
void
RasterImage::FinalizeDecoder(Decoder* aDecoder,
const DecoderFinalStatus& aStatus,
const ImageMetadata& aMetadata,
const DecoderTelemetry& aTelemetry,
Progress aProgress,
@ -1573,16 +1574,13 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder,
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aDecoder);
bool wasMetadata = aDecoder->IsMetadataDecode();
bool done = aDecoder->GetDecodeDone();
// If the decoder detected an error, log it to the error console.
if (aDecoder->ShouldReportError() && !aDecoder->WasAborted()) {
if (aStatus.mShouldReportError && !aStatus.mWasAborted) {
ReportDecoderError(aDecoder);
}
// Record all the metadata the decoder gathered about this image.
bool metadataOK = SetMetadata(aMetadata, wasMetadata);
bool metadataOK = SetMetadata(aMetadata, aStatus.mWasMetadataDecode);
if (!metadataOK) {
// This indicates a serious error that requires us to discard all existing
// surfaces and redecode to recover. We'll drop the results from this
@ -1595,7 +1593,7 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder,
MOZ_ASSERT(mError || mHasSize || !aMetadata.HasSize(),
"SetMetadata should've gotten a size");
if (!wasMetadata && aDecoder->GetDecodeDone() && !aDecoder->WasAborted()) {
if (!aStatus.mWasMetadataDecode && aStatus.mFinished && !aStatus.mWasAborted) {
// Flag that we've been decoded before.
mHasBeenDecoded = true;
}
@ -1609,13 +1607,13 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder,
mAnimationState->SetDoneDecoding(true);
}
if (!wasMetadata && aTelemetry.mChunkCount) {
if (!aStatus.mWasMetadataDecode && aTelemetry.mChunkCount) {
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount);
}
if (done) {
if (aStatus.mFinished) {
// Do some telemetry if this isn't a metadata decode.
if (!wasMetadata) {
if (!aStatus.mWasMetadataDecode) {
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
int32_t(aTelemetry.mDecodeTime.ToMicroseconds()));
@ -1625,14 +1623,14 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder,
}
// Detect errors.
if (aDecoder->HasError() && !aDecoder->WasAborted()) {
if (aStatus.mHadError && !aStatus.mWasAborted) {
DoError();
} else if (wasMetadata && !mHasSize) {
} else if (aStatus.mWasMetadataDecode && !mHasSize) {
DoError();
}
// If we were waiting to fire the load event, go ahead and fire it now.
if (mLoadProgress && wasMetadata) {
if (mLoadProgress && aStatus.mWasMetadataDecode) {
NotifyForLoadEvent(*mLoadProgress);
mLoadProgress = Nothing();
NotifyProgress(FLAG_ONLOAD_UNBLOCKED);
@ -1640,7 +1638,7 @@ RasterImage::FinalizeDecoder(Decoder* aDecoder,
}
// If we were a metadata decode and a full decode was requested, do it.
if (done && wasMetadata && mWantFullDecode) {
if (aStatus.mFinished && aStatus.mWasMetadataDecode && mWantFullDecode) {
mWantFullDecode = false;
RequestDecodeForSize(mSize, DECODE_FLAGS_DEFAULT);
}

View File

@ -135,6 +135,7 @@ class Image;
namespace image {
class Decoder;
struct DecoderFinalStatus;
struct DecoderTelemetry;
class ImageMetadata;
class SourceBuffer;
@ -203,6 +204,7 @@ public:
* Main-thread only.
*/
void FinalizeDecoder(Decoder* aDecoder,
const DecoderFinalStatus& aStatus,
const ImageMetadata& aMetadata,
const DecoderTelemetry& aTelemetry,
Progress aProgress,