mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1116733 (Part 2) - Remove DecodeStrategy and frame allocation handling outside of Decoder. r=tn
This commit is contained in:
parent
954c87102c
commit
97e722b9e0
@ -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!");
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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() { }
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
//
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user