Bug 1116733 (Part 2) - Remove DecodeStrategy and frame allocation handling outside of Decoder. r=tn

This commit is contained in:
Seth Fowler 2015-01-08 00:04:31 -08:00
parent 954c87102c
commit 97e722b9e0
18 changed files with 88 additions and 234 deletions

View File

@ -199,8 +199,7 @@ nsBMPDecoder::CalcBitShift()
}
void
nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy)
nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
{
NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");

View File

@ -50,8 +50,8 @@ public:
// for 32BPP bitmaps. Only use after the bitmap has been processed.
bool HasAlphaData() const;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer,
uint32_t aCount) MOZ_OVERRIDE;
virtual void FinishInternal() MOZ_OVERRIDE;
private:

View File

@ -567,8 +567,7 @@ ConvertColormap(uint32_t* aColormap, uint32_t aColors)
}
void
nsGIFDecoder2::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy)
nsGIFDecoder2::WriteInternal(const char* aBuffer, uint32_t aCount)
{
NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");

View File

@ -26,8 +26,7 @@ public:
explicit nsGIFDecoder2(RasterImage& aImage);
~nsGIFDecoder2();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
virtual void FinishInternal() MOZ_OVERRIDE;
virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE;

View File

@ -214,14 +214,13 @@ nsICODecoder::SetHotSpotIfCursor()
}
void
nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy)
nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
{
NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");
if (!aCount) {
if (mContainedDecoder) {
WriteToContainedDecoder(aBuffer, aCount, aStrategy);
WriteToContainedDecoder(aBuffer, aCount);
}
return;
}
@ -346,7 +345,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
mContainedDecoder->InitSharedDecoder(mImageData, mImageDataLength,
mColormap, mColormapSize,
Move(mRefForContainedDecoder));
if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE, aStrategy)) {
if (!WriteToContainedDecoder(mSignature, PNGSIGNATURESIZE)) {
return;
}
}
@ -354,7 +353,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
// If we have a PNG, let the PNG decoder do all of the rest of the work
if (mIsPNG && mContainedDecoder && mPos >= mImageOffset + PNGSIGNATURESIZE) {
if (!WriteToContainedDecoder(aBuffer, aCount, aStrategy)) {
if (!WriteToContainedDecoder(aBuffer, aCount)) {
return;
}
@ -433,8 +432,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
PostDataError();
return;
}
if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer),
aStrategy)) {
if (!WriteToContainedDecoder((const char*)bfhBuffer, sizeof(bfhBuffer))) {
return;
}
@ -455,7 +453,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
}
// Write out the BMP's bitmap info header
if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw), aStrategy)) {
if (!WriteToContainedDecoder(mBIHraw, sizeof(mBIHraw))) {
return;
}
@ -505,7 +503,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
toFeed = aCount;
}
if (!WriteToContainedDecoder(aBuffer, toFeed, aStrategy)) {
if (!WriteToContainedDecoder(aBuffer, toFeed)) {
return;
}
@ -594,10 +592,9 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
}
bool
nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy)
nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount)
{
mContainedDecoder->Write(aBuffer, aCount, aStrategy);
mContainedDecoder->Write(aBuffer, aCount);
mProgress |= mContainedDecoder->TakeProgress();
mInvalidRect.Union(mContainedDecoder->TakeInvalidRect());
if (mContainedDecoder->HasDataError()) {

View File

@ -38,17 +38,17 @@ public:
return mDirEntry.mHeight == 0 ? 256 : mDirEntry.mHeight;
}
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
virtual void FinishInternal() MOZ_OVERRIDE;
virtual bool NeedsNewFrame() const MOZ_OVERRIDE;
virtual nsresult AllocateFrame() MOZ_OVERRIDE;
protected:
virtual bool NeedsNewFrame() const MOZ_OVERRIDE;
private:
// Writes to the contained decoder and sets the appropriate errors
// Returns true if there are no errors.
bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy);
bool WriteToContainedDecoder(const char* aBuffer, uint32_t aCount);
// Processes a single dir entry of the icon resource
void ProcessDirEntry(IconDirEntry& aTarget);

View File

@ -29,8 +29,7 @@ nsIconDecoder::~nsIconDecoder()
{ }
void
nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy)
nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
{
NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");

View File

@ -41,8 +41,7 @@ public:
explicit nsIconDecoder(RasterImage& aImage);
virtual ~nsIconDecoder();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
uint8_t mWidth;
uint8_t mHeight;

View File

@ -190,8 +190,7 @@ nsJPEGDecoder::FinishInternal()
}
void
nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy)
nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
{
mSegment = (const JOCTET*)aBuffer;
mSegmentLen = aCount;

View File

@ -56,8 +56,7 @@ public:
virtual ~nsJPEGDecoder();
virtual void InitInternal() MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
virtual void FinishInternal() MOZ_OVERRIDE;
virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE;

View File

@ -313,8 +313,7 @@ nsPNGDecoder::InitInternal()
}
void
nsPNGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy)
nsPNGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
{
NS_ABORT_IF_FALSE(!HasError(), "Shouldn't call WriteInternal after error!");

View File

@ -28,8 +28,7 @@ public:
virtual ~nsPNGDecoder();
virtual void InitInternal() MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy) MOZ_OVERRIDE;
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) MOZ_OVERRIDE;
virtual Telemetry::ID SpeedHistogram() MOZ_OVERRIDE;
void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,

View File

@ -66,49 +66,6 @@ private:
nsRefPtr<RasterImage> mImage;
};
class FrameNeededWorker : public nsRunnable
{
public:
/**
* Called when an off-main-thread decoder needs a new frame to be allocated on
* the main thread.
*
* After allocating the new frame, the worker will call RequestDecode to
* continue decoding.
*/
static void Dispatch(RasterImage* aImage)
{
nsCOMPtr<nsIRunnable> worker = new FrameNeededWorker(aImage);
NS_DispatchToMainThread(worker);
}
NS_IMETHOD Run() MOZ_OVERRIDE
{
ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
nsresult rv = NS_OK;
// If we got a synchronous decode in the mean time, we don't need to do
// anything.
if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) {
rv = mImage->mDecoder->AllocateFrame();
}
if (NS_SUCCEEDED(rv) && mImage->mDecoder) {
// By definition, we're not done decoding, so enqueue us for more decoding.
DecodePool::Singleton()->RequestDecode(mImage);
}
return NS_OK;
}
private:
explicit FrameNeededWorker(RasterImage* aImage)
: mImage(aImage)
{ }
nsRefPtr<RasterImage> mImage;
};
class DecodeWorker : public nsRunnable
{
public:
@ -132,13 +89,6 @@ public:
return NS_OK;
}
// If we're a decode job that's been enqueued since a previous decode that
// still needs a new frame, we can't do anything. Wait until the
// FrameNeededWorker enqueues another frame.
if (mImage->mDecoder->NeedsNewFrame()) {
return NS_OK;
}
mImage->mDecodeStatus = DecodeStatus::ACTIVE;
size_t oldByteCount = mImage->mDecoder->BytesDecoded();
@ -150,23 +100,18 @@ public:
size_t maxBytes = mImage->mSourceData.Length() -
mImage->mDecoder->BytesDecoded();
DecodePool::Singleton()->DecodeSomeOfImage(mImage, DecodeStrategy::ASYNC,
type, maxBytes);
DecodePool::Singleton()->DecodeSomeOfImage(mImage, type, maxBytes);
size_t bytesDecoded = mImage->mDecoder->BytesDecoded() - oldByteCount;
mImage->mDecodeStatus = DecodeStatus::WORK_DONE;
if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) {
// The decoder needs a new frame. Enqueue an event to get it; that event
// will enqueue another decode request when it's done.
FrameNeededWorker::Dispatch(mImage);
} else if (mImage->mDecoder &&
!mImage->mError &&
!mImage->mPendingError &&
!mImage->IsDecodeFinished() &&
bytesDecoded < maxBytes &&
bytesDecoded > 0) {
if (mImage->mDecoder &&
!mImage->mError &&
!mImage->mPendingError &&
!mImage->IsDecodeFinished() &&
bytesDecoded < maxBytes &&
bytesDecoded > 0) {
// We aren't finished decoding, and we have more data, so add this request
// to the back of the list.
DecodePool::Singleton()->RequestDecode(mImage);
@ -323,30 +268,26 @@ DecodePool::RequestDecode(RasterImage* aImage)
MOZ_ASSERT(aImage->mDecoder);
aImage->mDecodingMonitor.AssertCurrentThreadIn();
// If we're currently waiting on a new frame for this image, we can't do any
// decoding.
if (!aImage->mDecoder->NeedsNewFrame()) {
if (aImage->mDecodeStatus == DecodeStatus::PENDING ||
aImage->mDecodeStatus == DecodeStatus::ACTIVE) {
// The image is already in our list of images to decode, or currently being
// decoded, so we don't have to do anything else.
return;
}
if (aImage->mDecodeStatus == DecodeStatus::PENDING ||
aImage->mDecodeStatus == DecodeStatus::ACTIVE) {
// The image is already in our list of images to decode, or currently being
// decoded, so we don't have to do anything else.
return;
}
aImage->mDecodeStatus = DecodeStatus::PENDING;
nsCOMPtr<nsIRunnable> worker = new DecodeWorker(aImage);
aImage->mDecodeStatus = DecodeStatus::PENDING;
nsCOMPtr<nsIRunnable> worker = new DecodeWorker(aImage);
MutexAutoLock threadPoolLock(mThreadPoolMutex);
if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) {
NS_DispatchToMainThread(worker);
} else {
mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL);
}
MutexAutoLock threadPoolLock(mThreadPoolMutex);
if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) {
NS_DispatchToMainThread(worker);
} else {
mThreadPool->Dispatch(worker, nsIEventTarget::DISPATCH_NORMAL);
}
}
void
DecodePool::DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy)
DecodePool::DecodeABitOf(RasterImage* aImage)
{
MOZ_ASSERT(NS_IsMainThread());
aImage->mDecodingMonitor.AssertCurrentThreadIn();
@ -356,23 +297,17 @@ DecodePool::DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy)
aImage->FinishedSomeDecoding();
}
DecodeSomeOfImage(aImage, aStrategy);
DecodeSomeOfImage(aImage);
aImage->FinishedSomeDecoding();
// If the decoder needs a new frame, enqueue an event to get it; that event
// will enqueue another decode request when it's done.
if (aImage->mDecoder && aImage->mDecoder->NeedsNewFrame()) {
FrameNeededWorker::Dispatch(aImage);
} else {
// If we aren't yet finished decoding and we have more data in hand, add
// this request to the back of the priority list.
if (aImage->mDecoder &&
!aImage->mError &&
!aImage->IsDecodeFinished() &&
aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded()) {
RequestDecode(aImage);
}
// If we aren't yet finished decoding and we have more data in hand, add
// this request to the back of the priority list.
if (aImage->mDecoder &&
!aImage->mError &&
!aImage->IsDecodeFinished() &&
aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded()) {
RequestDecode(aImage);
}
}
@ -401,28 +336,16 @@ DecodePool::DecodeUntilSizeAvailable(RasterImage* aImage)
}
}
// We use DecodeStrategy::ASYNC here because we just want to get the size
// information here and defer the rest of the work.
nsresult rv =
DecodeSomeOfImage(aImage, DecodeStrategy::ASYNC, DecodeUntil::SIZE);
nsresult rv = DecodeSomeOfImage(aImage, DecodeUntil::SIZE);
if (NS_FAILED(rv)) {
return rv;
}
// If the decoder needs a new frame, enqueue an event to get it; that event
// will enqueue another decode request when it's done.
if (aImage->mDecoder && aImage->mDecoder->NeedsNewFrame()) {
FrameNeededWorker::Dispatch(aImage);
} else {
rv = aImage->FinishedSomeDecoding();
}
return rv;
return aImage->FinishedSomeDecoding();
}
nsresult
DecodePool::DecodeSomeOfImage(RasterImage* aImage,
DecodeStrategy aStrategy,
DecodeUntil aDecodeUntil /* = DecodeUntil::TIME */,
uint32_t bytesToDecode /* = 0 */)
{
@ -447,15 +370,6 @@ DecodePool::DecodeSomeOfImage(RasterImage* aImage,
return NS_OK;
}
if (aImage->mDecoder->NeedsNewFrame()) {
if (aStrategy == DecodeStrategy::SYNC) {
MOZ_ASSERT(NS_IsMainThread());
aImage->mDecoder->AllocateFrame();
} else {
return NS_OK;
}
}
nsRefPtr<Decoder> decoderKungFuDeathGrip = aImage->mDecoder;
uint32_t maxBytes;
@ -482,16 +396,12 @@ DecodePool::DecodeSomeOfImage(RasterImage* aImage,
// * the decode completes,
// * we're an DecodeUntil::SIZE decode and we get the size, or
// * we run out of time.
// We also try to decode at least one "chunk" if we've allocated a new frame,
// even if we have no more data to send to the decoder.
while ((aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded() &&
bytesToDecode > 0 &&
!aImage->IsDecodeFinished() &&
!(aDecodeUntil == DecodeUntil::SIZE && aImage->mHasSize) &&
!aImage->mDecoder->NeedsNewFrame()) ||
aImage->mDecoder->NeedsToFlushData()) {
while (aImage->mSourceData.Length() > aImage->mDecoder->BytesDecoded() &&
bytesToDecode > 0 &&
!aImage->IsDecodeFinished() &&
!(aDecodeUntil == DecodeUntil::SIZE && aImage->mHasSize)) {
uint32_t chunkSize = min(bytesToDecode, maxBytes);
nsresult rv = aImage->DecodeSomeData(chunkSize, aStrategy);
nsresult rv = aImage->DecodeSomeData(chunkSize);
if (NS_FAILED(rv)) {
aImage->DoError();
return rv;

View File

@ -25,22 +25,6 @@ namespace image {
class Decoder;
class RasterImage;
MOZ_BEGIN_ENUM_CLASS(DecodeStrategy, uint8_t)
// DecodeStrategy::SYNC requests a synchronous decode, which will continue
// decoding frames as long as it has more source data. It returns to the
// caller only once decoding is complete (or until it needs more source data
// before continuing). Because DecodeStrategy::SYNC can involve allocating new
// imgFrames, it can only be run on the main thread.
SYNC,
// DecodeStrategy::ASYNC requests an asynchronous decode, which will continue
// decoding until it either finishes a frame or runs out of source data.
// Because DecodeStrategy::ASYNC does not allocate new imgFrames, it can be
// safely run off the main thread. (And hence workers in the decode pool
// always use it.)
ASYNC
MOZ_END_ENUM_CLASS(DecodeStrategy)
MOZ_BEGIN_ENUM_CLASS(DecodeStatus, uint8_t)
INACTIVE,
PENDING,
@ -92,7 +76,7 @@ public:
* Decode aImage for a short amount of time, and post the remainder to the
* queue.
*/
void DecodeABitOf(RasterImage* aImage, DecodeStrategy aStrategy);
void DecodeABitOf(RasterImage* aImage);
/**
* Ask the DecodePool to stop decoding this image. Internally, we also
@ -128,7 +112,6 @@ public:
* DONE_BYTES, decode until all bytesToDecode bytes are decoded.
*/
nsresult DecodeSomeOfImage(RasterImage* aImage,
DecodeStrategy aStrategy,
DecodeUntil aDecodeUntil = DecodeUntil::TIME,
uint32_t bytesToDecode = 0);

View File

@ -98,13 +98,11 @@ Decoder::InitSharedDecoder(uint8_t* aImageData, uint32_t aImageDataLength,
}
void
Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy)
Decoder::Write(const char* aBuffer, uint32_t aCount)
{
PROFILER_LABEL("ImageDecoder", "Write",
js::ProfileEntry::Category::GRAPHICS);
MOZ_ASSERT(NS_IsMainThread() || aStrategy == DecodeStrategy::ASYNC);
// We're strict about decoder errors
MOZ_ASSERT(!HasDecoderError(),
"Not allowed to make more decoder calls after error!");
@ -131,8 +129,13 @@ Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy)
return;
}
// Pass the data along to the implementation
WriteInternal(aBuffer, aCount, aStrategy);
MOZ_ASSERT(!NeedsNewFrame() || HasDataError(),
"Should not need a new frame before writing anything");
MOZ_ASSERT(!NeedsToFlushData() || HasDataError(),
"Should not need to flush data before writing anything");
// Pass the data along to the implementation.
WriteInternal(aBuffer, aCount);
// If we need a new frame to proceed, let's create one and call it again.
while (NeedsNewFrame() && !HasDataError()) {
@ -142,7 +145,7 @@ Decoder::Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy)
if (NS_SUCCEEDED(rv)) {
// Use the data we saved when we asked for a new frame.
WriteInternal(nullptr, 0, aStrategy);
WriteInternal(nullptr, 0);
}
mNeedsToFlushData = false;
@ -418,7 +421,7 @@ Decoder::SetSizeOnImage()
*/
void Decoder::InitInternal() { }
void Decoder::WriteInternal(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy) { }
void Decoder::WriteInternal(const char* aBuffer, uint32_t aCount) { }
void Decoder::FinishInternal() { }
/*

View File

@ -56,7 +56,7 @@ public:
*
* Notifications Sent: TODO
*/
void Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy);
void Write(const char* aBuffer, uint32_t aCount);
/**
* Informs the decoder that all the data has been written.
@ -180,13 +180,8 @@ public:
uint32_t width, uint32_t height,
gfx::SurfaceFormat format,
uint8_t palette_depth = 0);
virtual bool NeedsNewFrame() const { return mNeedsNewFrame; }
// Returns true if we may have stored data that we need to flush now that we
// have a new frame to decode into. Callers can use Write() to actually
// flush the data; see the documentation for that method.
bool NeedsToFlushData() const { return mNeedsToFlushData; }
// Try to allocate a frame as described in mNewFrameData and return the
// status code from that attempt. Clears mNewFrameData.
@ -212,8 +207,7 @@ protected:
* only these methods.
*/
virtual void InitInternal();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy);
virtual void WriteInternal(const char* aBuffer, uint32_t aCount);
virtual void FinishInternal();
/*
@ -270,6 +264,11 @@ protected:
void PostDataError();
void PostDecoderError(nsresult aFailCode);
// Returns true if we may have stored data that we need to flush now that we
// have a new frame to decode into. Callers can use Write() to actually
// flush the data; see the documentation for that method.
bool NeedsToFlushData() const { return mNeedsToFlushData; }
/**
* Ensures that a given frame number exists with the given parameters, and
* returns a RawAccessFrameRef for that frame.

View File

@ -1230,7 +1230,7 @@ RasterImage::AddSourceData(const char *aBuffer, uint32_t aCount)
// write the data directly to the decoder. (If we haven't gotten the size,
// we'll queue up the data and write it out when we do.)
if (!StoringSourceData() && mHasSize) {
rv = WriteToDecoder(aBuffer, aCount, DecodeStrategy::SYNC);
rv = WriteToDecoder(aBuffer, aCount);
CONTAINER_ENSURE_SUCCESS(rv);
rv = FinishedSomeDecoding();
@ -1638,7 +1638,7 @@ RasterImage::ShutdownDecoder(ShutdownReason aReason)
// Writes the data to the decoder, updating the total number of bytes written.
nsresult
RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy aStrategy)
RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount)
{
mDecodingMonitor.AssertCurrentThreadIn();
@ -1647,7 +1647,7 @@ RasterImage::WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy
// Write
nsRefPtr<Decoder> kungFuDeathGrip = mDecoder;
mDecoder->Write(aBuffer, aCount, aStrategy);
mDecoder->Write(aBuffer, aCount);
CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError());
@ -1717,11 +1717,6 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
if (mDecoded)
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 we have a size decoder open, make sure we get the size
if (mDecoder && mDecoder->IsSizeDecode()) {
nsresult rv = DecodePool::Singleton()->DecodeUntilSizeAvailable(this);
@ -1821,7 +1816,7 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
PROFILER_LABEL_PRINTF("RasterImage", "DecodeABitOf",
js::ProfileEntry::Category::GRAPHICS, "%s", GetURIString().get());
DecodePool::Singleton()->DecodeABitOf(this, DecodeStrategy::SYNC);
DecodePool::Singleton()->DecodeABitOf(this);
return NS_OK;
}
@ -1889,11 +1884,6 @@ RasterImage::SyncDecode()
}
}
// If we're currently waiting on a new frame for this image, create it now.
if (mDecoder && mDecoder->NeedsNewFrame()) {
mDecoder->AllocateFrame();
}
// If we don't have a decoder, create one
if (!mDecoder) {
rv = InitDecoder(/* aDoSizeDecode = */ false);
@ -1903,8 +1893,7 @@ RasterImage::SyncDecode()
MOZ_ASSERT(mDecoder);
// Write everything we have
rv = DecodeSomeData(mSourceData.Length() - mDecoder->BytesDecoded(),
DecodeStrategy::SYNC);
rv = DecodeSomeData(mSourceData.Length() - mDecoder->BytesDecoded());
CONTAINER_ENSURE_SUCCESS(rv);
rv = FinishedSomeDecoding();
@ -2215,22 +2204,12 @@ RasterImage::RequestDiscard()
// Flushes up to aMaxBytes to the decoder.
nsresult
RasterImage::DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy)
RasterImage::DecodeSomeData(size_t aMaxBytes)
{
MOZ_ASSERT(mDecoder, "Should have a decoder");
mDecodingMonitor.AssertCurrentThreadIn();
// First, if we've just been called because we allocated a frame on the main
// thread, let the decoder deal with the data it set aside at that time by
// passing it a null buffer.
if (mDecoder->NeedsToFlushData()) {
nsresult rv = WriteToDecoder(nullptr, 0, aStrategy);
if (NS_FAILED(rv) || mDecoder->NeedsNewFrame()) {
return rv;
}
}
// If we have nothing else to decode, return.
if (mDecoder->BytesDecoded() == mSourceData.Length()) {
return NS_OK;
@ -2242,8 +2221,7 @@ RasterImage::DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy)
size_t bytesToDecode = min(aMaxBytes,
mSourceData.Length() - mDecoder->BytesDecoded());
return WriteToDecoder(mSourceData.Elements() + mDecoder->BytesDecoded(),
bytesToDecode,
aStrategy);
bytesToDecode);
}
@ -2267,13 +2245,6 @@ RasterImage::IsDecodeFinished()
return true;
}
// If the decoder returned because it needed a new frame and we haven't
// written to it since then, the decoder may be storing data that it hasn't
// decoded yet.
if (mDecoder->NeedsNewFrame() || mDecoder->NeedsToFlushData()) {
return false;
}
// Otherwise, if we have all the source data and wrote all the source data,
// we're done.
//

View File

@ -426,8 +426,8 @@ private: // data
nsresult WantDecodedFrames(uint32_t aFlags, bool aShouldSyncNotify);
nsresult SyncDecode();
nsresult InitDecoder(bool aDoSizeDecode);
nsresult WriteToDecoder(const char *aBuffer, uint32_t aCount, DecodeStrategy aStrategy);
nsresult DecodeSomeData(size_t aMaxBytes, DecodeStrategy aStrategy);
nsresult WriteToDecoder(const char *aBuffer, uint32_t aCount);
nsresult DecodeSomeData(size_t aMaxBytes);
bool IsDecodeFinished();
TimeStamp mDrawStartTime;