mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1079653 (Part 4) - Move decode status tracking onto RasterImage and remove DecodeRequest. r=tn
This commit is contained in:
parent
550967dd4b
commit
ae5c2d16a1
@ -320,6 +320,7 @@ RasterImage::RasterImage(ProgressTracker* aProgressTracker,
|
||||
#endif
|
||||
mDecodingMonitor("RasterImage Decoding Monitor"),
|
||||
mDecoder(nullptr),
|
||||
mDecodeStatus(DecodeStatus::INACTIVE),
|
||||
mNotifyProgress(NoProgress),
|
||||
mNotifying(false),
|
||||
mHasSize(false),
|
||||
@ -1665,7 +1666,6 @@ RasterImage::OnImageDataComplete(nsIRequest*, nsISupports*, nsresult aStatus, bo
|
||||
{
|
||||
ReentrantMonitorAutoEnter lock(mDecodingMonitor);
|
||||
FinishedSomeDecoding(eShutdownIntent_Done,
|
||||
nullptr,
|
||||
LoadCompleteProgress(aLastPart, mError, finalStatus));
|
||||
}
|
||||
|
||||
@ -1732,7 +1732,7 @@ RasterImage::OnNewSourceData()
|
||||
mHasSourceData = false;
|
||||
mHasSize = false;
|
||||
mWantFullDecode = true;
|
||||
mDecodeRequest = nullptr;
|
||||
mDecodeStatus = DecodeStatus::INACTIVE;
|
||||
|
||||
if (mAnim) {
|
||||
mAnim->SetDoneDecoding(false);
|
||||
@ -1833,7 +1833,7 @@ RasterImage::Discard(bool force)
|
||||
if (mProgressTracker)
|
||||
mProgressTracker->OnDiscard();
|
||||
|
||||
mDecodeRequest = nullptr;
|
||||
mDecodeStatus = DecodeStatus::INACTIVE;
|
||||
|
||||
if (force)
|
||||
DiscardTracker::Remove(&mDiscardTrackerNode);
|
||||
@ -1953,9 +1953,6 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
|
||||
}
|
||||
|
||||
// Initialize the decoder
|
||||
if (!mDecodeRequest) {
|
||||
mDecodeRequest = new DecodeRequest(this);
|
||||
}
|
||||
mDecoder->SetSizeDecode(aDoSizeDecode);
|
||||
mDecoder->SetDecodeFlags(mFrameDecodeFlags);
|
||||
if (!aDoSizeDecode) {
|
||||
@ -2168,8 +2165,7 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
|
||||
}
|
||||
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (mDecodeRequest &&
|
||||
mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE &&
|
||||
if (mDecodeStatus == DecodeStatus::WORK_DONE &&
|
||||
aDecodeType == SYNCHRONOUS_NOTIFY) {
|
||||
ReentrantMonitorAutoEnter lock(mDecodingMonitor);
|
||||
nsresult rv = FinishedSomeDecoding();
|
||||
@ -2205,9 +2201,7 @@ RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
|
||||
// we need to repeat the following three checks after getting the lock.
|
||||
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (mDecodeRequest &&
|
||||
mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE &&
|
||||
aDecodeType != ASYNCHRONOUS) {
|
||||
if (mDecodeStatus == DecodeStatus::WORK_DONE && aDecodeType != ASYNCHRONOUS) {
|
||||
nsresult rv = FinishedSomeDecoding();
|
||||
CONTAINER_ENSURE_SUCCESS(rv);
|
||||
}
|
||||
@ -2292,12 +2286,10 @@ RasterImage::SyncDecode()
|
||||
|
||||
ReentrantMonitorAutoEnter lock(mDecodingMonitor);
|
||||
|
||||
if (mDecodeRequest) {
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
|
||||
nsresult rv = FinishedSomeDecoding();
|
||||
CONTAINER_ENSURE_SUCCESS(rv);
|
||||
}
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (mDecodeStatus == DecodeStatus::WORK_DONE) {
|
||||
nsresult rv = FinishedSomeDecoding();
|
||||
CONTAINER_ENSURE_SUCCESS(rv);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
@ -2894,20 +2886,12 @@ RasterImage::RequestDecodeIfNeeded(nsresult aStatus,
|
||||
|
||||
nsresult
|
||||
RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_Done */,
|
||||
DecodeRequest* aRequest /* = nullptr */,
|
||||
Progress aProgress /* = NoProgress */)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDecodingMonitor.AssertCurrentThreadIn();
|
||||
|
||||
nsRefPtr<DecodeRequest> request;
|
||||
if (aRequest) {
|
||||
request = aRequest;
|
||||
} else {
|
||||
request = mDecodeRequest;
|
||||
}
|
||||
|
||||
// Ensure that, if the decoder is the last reference to the image, we don't
|
||||
// destroy it by destroying the decoder.
|
||||
nsRefPtr<RasterImage> image(this);
|
||||
@ -2942,7 +2926,7 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
|
||||
wasSize = decoder->IsSizeDecode();
|
||||
|
||||
// Do some telemetry if this isn't a size decode.
|
||||
if (request && !wasSize) {
|
||||
if (!wasSize) {
|
||||
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
|
||||
int32_t(decoder->DecodeTime().ToMicroseconds()));
|
||||
|
||||
@ -3140,15 +3124,15 @@ RasterImage::DecodePool::RequestDecode(RasterImage* aImg)
|
||||
// If we're currently waiting on a new frame for this image, we can't do any
|
||||
// decoding.
|
||||
if (!aImg->mDecoder->NeedsNewFrame()) {
|
||||
if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_PENDING ||
|
||||
aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_ACTIVE) {
|
||||
if (aImg->mDecodeStatus == DecodeStatus::PENDING ||
|
||||
aImg->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;
|
||||
}
|
||||
|
||||
aImg->mDecodeRequest->mRequestStatus = DecodeRequest::REQUEST_PENDING;
|
||||
nsRefPtr<DecodeJob> job = new DecodeJob(aImg->mDecodeRequest, aImg);
|
||||
aImg->mDecodeStatus = DecodeStatus::PENDING;
|
||||
nsRefPtr<DecodeJob> job = new DecodeJob(aImg);
|
||||
|
||||
MutexAutoLock threadPoolLock(mThreadPoolMutex);
|
||||
if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) {
|
||||
@ -3165,11 +3149,9 @@ RasterImage::DecodePool::DecodeABitOf(RasterImage* aImg, DecodeStrategy aStrateg
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
aImg->mDecodingMonitor.AssertCurrentThreadIn();
|
||||
|
||||
if (aImg->mDecodeRequest) {
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
|
||||
aImg->FinishedSomeDecoding();
|
||||
}
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (aImg->mDecodeStatus == DecodeStatus::WORK_DONE) {
|
||||
aImg->FinishedSomeDecoding();
|
||||
}
|
||||
|
||||
DecodeSomeOfImage(aImg, aStrategy);
|
||||
@ -3199,9 +3181,7 @@ RasterImage::DecodePool::StopDecoding(RasterImage* aImg)
|
||||
|
||||
// If we haven't got a decode request, we're not currently decoding. (Having
|
||||
// a decode request doesn't imply we *are* decoding, though.)
|
||||
if (aImg->mDecodeRequest) {
|
||||
aImg->mDecodeRequest->mRequestStatus = DecodeRequest::REQUEST_STOPPED;
|
||||
}
|
||||
aImg->mDecodeStatus = DecodeStatus::STOPPED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -3210,14 +3190,14 @@ RasterImage::DecodePool::DecodeJob::Run()
|
||||
ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
|
||||
|
||||
// If we were interrupted, we shouldn't do any work.
|
||||
if (mRequest->mRequestStatus == DecodeRequest::REQUEST_STOPPED) {
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
|
||||
if (mImage->mDecodeStatus == DecodeStatus::STOPPED) {
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If someone came along and synchronously decoded us, there's nothing for us to do.
|
||||
if (!mImage->mDecoder || mImage->IsDecodeFinished()) {
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3228,7 +3208,7 @@ RasterImage::DecodePool::DecodeJob::Run()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mRequest->mRequestStatus = DecodeRequest::REQUEST_ACTIVE;
|
||||
mImage->mDecodeStatus = DecodeStatus::ACTIVE;
|
||||
|
||||
size_t oldByteCount = mImage->mDecoder->BytesDecoded();
|
||||
|
||||
@ -3247,7 +3227,7 @@ RasterImage::DecodePool::DecodeJob::Run()
|
||||
|
||||
size_t bytesDecoded = mImage->mDecoder->BytesDecoded() - oldByteCount;
|
||||
|
||||
mRequest->mRequestStatus = DecodeRequest::REQUEST_WORK_DONE;
|
||||
mImage->mDecodeStatus = DecodeStatus::WORK_DONE;
|
||||
|
||||
// If the decoder needs a new frame, enqueue an event to get it; that event
|
||||
// will enqueue another decode request when it's done.
|
||||
@ -3265,7 +3245,7 @@ RasterImage::DecodePool::DecodeJob::Run()
|
||||
DecodePool::Singleton()->RequestDecode(mImage);
|
||||
} else {
|
||||
// Nothing more for us to do - let everyone know what happened.
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
|
||||
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -3293,14 +3273,12 @@ RasterImage::DecodePool::DecodeUntilSizeAvailable(RasterImage* aImg)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter lock(aImg->mDecodingMonitor);
|
||||
|
||||
if (aImg->mDecodeRequest) {
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
|
||||
nsresult rv = aImg->FinishedSomeDecoding();
|
||||
if (NS_FAILED(rv)) {
|
||||
aImg->DoError();
|
||||
return rv;
|
||||
}
|
||||
// If the image is waiting for decode work to be notified, go ahead and do that.
|
||||
if (aImg->mDecodeStatus == DecodeStatus::WORK_DONE) {
|
||||
nsresult rv = aImg->FinishedSomeDecoding();
|
||||
if (NS_FAILED(rv)) {
|
||||
aImg->DoError();
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3411,17 +3389,16 @@ RasterImage::DecodePool::DecodeSomeOfImage(RasterImage* aImg,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RasterImage::DecodeDoneWorker::DecodeDoneWorker(RasterImage* image, DecodeRequest* request)
|
||||
: mImage(image)
|
||||
, mRequest(request)
|
||||
{}
|
||||
RasterImage::DecodeDoneWorker::DecodeDoneWorker(RasterImage* aImage)
|
||||
: mImage(aImage)
|
||||
{ }
|
||||
|
||||
void
|
||||
RasterImage::DecodeDoneWorker::NotifyFinishedSomeDecoding(RasterImage* image, DecodeRequest* request)
|
||||
RasterImage::DecodeDoneWorker::NotifyFinishedSomeDecoding(RasterImage* aImage)
|
||||
{
|
||||
image->mDecodingMonitor.AssertCurrentThreadIn();
|
||||
aImage->mDecodingMonitor.AssertCurrentThreadIn();
|
||||
|
||||
nsCOMPtr<nsIRunnable> worker = new DecodeDoneWorker(image, request);
|
||||
nsCOMPtr<nsIRunnable> worker = new DecodeDoneWorker(aImage);
|
||||
NS_DispatchToMainThread(worker);
|
||||
}
|
||||
|
||||
@ -3431,7 +3408,7 @@ RasterImage::DecodeDoneWorker::Run()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
|
||||
|
||||
mImage->FinishedSomeDecoding(eShutdownIntent_Done, mRequest);
|
||||
mImage->FinishedSomeDecoding(eShutdownIntent_Done);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/TypedEnum.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
@ -136,6 +137,14 @@ class Decoder;
|
||||
class FrameAnimator;
|
||||
class ScaleRunner;
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(DecodeStatus, uint8_t)
|
||||
INACTIVE,
|
||||
PENDING,
|
||||
ACTIVE,
|
||||
WORK_DONE,
|
||||
STOPPED
|
||||
MOZ_END_ENUM_CLASS(DecodeStatus)
|
||||
|
||||
class RasterImage MOZ_FINAL : public ImageResource
|
||||
, public nsIProperties
|
||||
, public SupportsWeakPtr<RasterImage>
|
||||
@ -306,39 +315,7 @@ public:
|
||||
eShutdownIntent_AllCount = 3
|
||||
};
|
||||
|
||||
// Decode strategy
|
||||
|
||||
private:
|
||||
nsresult OnImageDataCompleteCore(nsIRequest* aRequest, nsISupports*, nsresult aStatus);
|
||||
|
||||
/**
|
||||
* Each RasterImage has a pointer to one or zero heap-allocated
|
||||
* DecodeRequests.
|
||||
*/
|
||||
struct DecodeRequest
|
||||
{
|
||||
explicit DecodeRequest(RasterImage* aImage)
|
||||
: mImage(aImage)
|
||||
, mRequestStatus(REQUEST_INACTIVE)
|
||||
{ }
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodeRequest)
|
||||
|
||||
RasterImage* mImage;
|
||||
|
||||
enum DecodeRequestStatus
|
||||
{
|
||||
REQUEST_INACTIVE,
|
||||
REQUEST_PENDING,
|
||||
REQUEST_ACTIVE,
|
||||
REQUEST_WORK_DONE,
|
||||
REQUEST_STOPPED
|
||||
} mRequestStatus;
|
||||
|
||||
private:
|
||||
~DecodeRequest() {}
|
||||
};
|
||||
|
||||
/*
|
||||
* DecodePool is a singleton class we use when decoding large images.
|
||||
*
|
||||
@ -426,18 +403,14 @@ private:
|
||||
class DecodeJob : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DecodeJob(DecodeRequest* aRequest, RasterImage* aImg)
|
||||
: mRequest(aRequest)
|
||||
, mImage(aImg)
|
||||
{}
|
||||
DecodeJob(RasterImage* aImage) : mImage(aImage) { }
|
||||
|
||||
NS_IMETHOD Run();
|
||||
NS_IMETHOD Run() MOZ_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual ~DecodeJob();
|
||||
|
||||
private:
|
||||
nsRefPtr<DecodeRequest> mRequest;
|
||||
nsRefPtr<RasterImage> mImage;
|
||||
};
|
||||
|
||||
@ -460,17 +433,14 @@ private:
|
||||
* Ensures the decode state accumulated by the decoding process gets
|
||||
* applied to the image.
|
||||
*/
|
||||
static void NotifyFinishedSomeDecoding(RasterImage* image, DecodeRequest* request);
|
||||
static void NotifyFinishedSomeDecoding(RasterImage* aImage);
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private: /* methods */
|
||||
DecodeDoneWorker(RasterImage* image, DecodeRequest* request);
|
||||
|
||||
private: /* members */
|
||||
private:
|
||||
DecodeDoneWorker(RasterImage* aImage);
|
||||
|
||||
nsRefPtr<RasterImage> mImage;
|
||||
nsRefPtr<DecodeRequest> mRequest;
|
||||
};
|
||||
|
||||
class FrameNeededWorker : public nsRunnable
|
||||
@ -481,7 +451,7 @@ private:
|
||||
* decoder that it needs a new frame to be allocated on the main thread.
|
||||
*
|
||||
* Dispatches an event to do so, which will further dispatch a
|
||||
* DecodeRequest event to continue decoding.
|
||||
* RequestDecode event to continue decoding.
|
||||
*/
|
||||
static void GetNewFrame(RasterImage* image);
|
||||
|
||||
@ -496,7 +466,6 @@ private:
|
||||
};
|
||||
|
||||
nsresult FinishedSomeDecoding(eShutdownIntent intent = eShutdownIntent_Done,
|
||||
DecodeRequest* request = nullptr,
|
||||
Progress aProgress = NoProgress);
|
||||
|
||||
void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
|
||||
@ -621,7 +590,7 @@ private: // data
|
||||
|
||||
// Decoder and friends
|
||||
nsRefPtr<Decoder> mDecoder;
|
||||
nsRefPtr<DecodeRequest> mDecodeRequest;
|
||||
DecodeStatus mDecodeStatus;
|
||||
// END LOCKED MEMBER VARIABLES
|
||||
|
||||
// Notification state. Used to avoid recursive notifications.
|
||||
|
Loading…
Reference in New Issue
Block a user