Bug 1079653 (Part 5) - Move decode status tracking onto RasterImage and remove DecodeRequest. r=tn

--HG--
extra : rebase_source : 1276b94c41d240fba2ad4df4d5812483c10f6f27
This commit is contained in:
Seth Fowler 2014-10-15 13:52:22 -07:00
parent 4cd6dd5c37
commit 8b1914763b
2 changed files with 38 additions and 75 deletions

View File

@ -321,6 +321,7 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
#endif
mDecodingMonitor("RasterImage Decoding Monitor"),
mDecoder(nullptr),
mDecodeStatus(DecodeStatus::INACTIVE),
mInDecoder(false),
mStatusDiff(ImageStatusDiff::NoChange()),
mNotifying(false),
@ -1766,7 +1767,7 @@ RasterImage::OnNewSourceData()
mHasSourceData = false;
mHasSize = false;
mWantFullDecode = true;
mDecodeRequest = nullptr;
mDecodeStatus = DecodeStatus::INACTIVE;
mDecodeStatusTracker = nullptr;
if (mAnim) {
@ -1868,7 +1869,7 @@ RasterImage::Discard(bool force)
if (mStatusTracker)
mStatusTracker->OnDiscard();
mDecodeRequest = nullptr;
mDecodeStatus = DecodeStatus::INACTIVE;
mDecodeStatusTracker = nullptr;
if (force)
@ -1989,9 +1990,6 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
}
// Initialize the decoder
if (!mDecodeRequest) {
mDecodeRequest = new DecodeRequest();
}
if (!mDecodeStatusTracker) {
MOZ_ASSERT(mStatusTracker, "Should have an imgStatusTracker");
mDecodeStatusTracker = mStatusTracker->CloneForRecording();
@ -2233,8 +2231,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();
@ -2270,9 +2267,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);
}
@ -2363,12 +2358,10 @@ RasterImage::SyncDecode()
// disallow this type of call in the API, and check for it in API methods.
NS_ABORT_IF_FALSE(!mInDecoder, "Yikes, forcing sync in reentrant call!");
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;
@ -3204,15 +3197,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) {
@ -3229,11 +3222,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);
@ -3263,9 +3254,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
@ -3274,7 +3263,7 @@ RasterImage::DecodePool::DecodeJob::Run()
ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
// If we were interrupted, we shouldn't do any work.
if (mRequest->mRequestStatus == DecodeRequest::REQUEST_STOPPED) {
if (mImage->mDecodeStatus == DecodeStatus::STOPPED) {
DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage,
mImage->mDecodeStatusTracker);
return NS_OK;
@ -3294,7 +3283,7 @@ RasterImage::DecodePool::DecodeJob::Run()
return NS_OK;
}
mRequest->mRequestStatus = DecodeRequest::REQUEST_ACTIVE;
mImage->mDecodeStatus = DecodeStatus::ACTIVE;
size_t oldByteCount = mImage->mDecoder->BytesDecoded();
@ -3313,7 +3302,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.
@ -3360,14 +3349,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;
}
}

View File

@ -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>
@ -319,35 +328,6 @@ private:
return statusTracker.forget();
}
nsresult OnImageDataCompleteCore(nsIRequest* aRequest, nsISupports*, nsresult aStatus);
/**
* Each RasterImage has a pointer to one or zero heap-allocated
* DecodeRequests.
*/
struct DecodeRequest
{
explicit DecodeRequest()
: 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.
*
@ -435,18 +415,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;
};
@ -633,8 +609,8 @@ private: // data
// Decoder and friends
nsRefPtr<Decoder> mDecoder;
nsRefPtr<DecodeRequest> mDecodeRequest;
nsRefPtr<imgStatusTracker> mDecodeStatusTracker;
DecodeStatus mDecodeStatus;
bool mInDecoder;
// END LOCKED MEMBER VARIABLES