Bug 1097432 (Part 3) - Rename imgStatusTracker to ProgressTracker and ImageStatusDiff to Progress. r=tn

--HG--
rename : image/src/imgStatusTracker.cpp => image/src/ProgressTracker.cpp
rename : image/src/imgStatusTracker.h => image/src/ProgressTracker.h
This commit is contained in:
Seth Fowler 2014-11-14 20:10:47 -08:00
parent 32255b73d9
commit 03cc795af0
22 changed files with 408 additions and 428 deletions

View File

@ -83,7 +83,7 @@ nsICODecoder::FinishInternal()
if (mContainedDecoder) {
mContainedDecoder->FinishSharedDecoder();
mDecodeDone = mContainedDecoder->GetDecodeDone();
mDiff = mContainedDecoder->GetDiff();
mProgress = mContainedDecoder->GetProgress();
}
}
@ -587,7 +587,7 @@ nsICODecoder::WriteToContainedDecoder(const char* aBuffer, uint32_t aCount,
DecodeStrategy aStrategy)
{
mContainedDecoder->Write(aBuffer, aCount, aStrategy);
mDiff = mContainedDecoder->GetDiff();
mProgress = mContainedDecoder->GetProgress();
if (mContainedDecoder->HasDataError()) {
mDataError = mContainedDecoder->HasDataError();
}
@ -632,7 +632,7 @@ nsICODecoder::AllocateFrame()
if (mContainedDecoder) {
nsresult rv = mContainedDecoder->AllocateFrame();
mCurrentFrame = mContainedDecoder->GetCurrentFrame();
mDiff = mContainedDecoder->GetDiff();
mProgress = mContainedDecoder->GetProgress();
return rv;
}

View File

@ -134,8 +134,8 @@ ClippedImage::ShouldClip()
// available yet, in which case we'll try again later.
if (mShouldClip.isNothing()) {
int32_t width, height;
nsRefPtr<imgStatusTracker> innerImageStatusTracker =
InnerImage()->GetStatusTracker();
nsRefPtr<ProgressTracker> progressTracker =
InnerImage()->GetProgressTracker();
if (InnerImage()->HasError()) {
// If there's a problem with the inner image we'll let it handle everything.
mShouldClip.emplace(false);
@ -147,8 +147,7 @@ ClippedImage::ShouldClip()
// If the clipping region is the same size as the underlying image we
// don't have to do anything.
mShouldClip.emplace(!mClip.IsEqualInterior(nsIntRect(0, 0, width, height)));
} else if (innerImageStatusTracker &&
innerImageStatusTracker->IsLoading()) {
} else if (progressTracker && progressTracker->IsLoading()) {
// The image just hasn't finished loading yet. We don't yet know whether
// clipping with be needed or not for now. Just return without memoizing
// anything.

View File

@ -17,6 +17,7 @@ namespace image {
Decoder::Decoder(RasterImage &aImage)
: mImage(aImage)
, mCurrentFrame(nullptr)
, mProgress(NoProgress)
, mImageData(nullptr)
, mColormap(nullptr)
, mDecodeFlags(0)
@ -49,7 +50,7 @@ Decoder::Init()
// Fire OnStartDecode at init time to support bug 512435.
if (!IsSizeDecode()) {
mDiff.diffState |= FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED;
mProgress |= FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED;
}
// Implementation-specific initialization
@ -175,8 +176,8 @@ Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent)
}
PostDecodeDone();
} else {
mDiff.diffState |= FLAG_DECODE_STOPPED | FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR;
mProgress |= FLAG_DECODE_STOPPED | FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR;
}
}
@ -278,7 +279,7 @@ Decoder::PostSize(int32_t aWidth,
mImageMetadata.SetSize(aWidth, aHeight, aOrientation);
// Record this notification.
mDiff.diffState |= FLAG_HAS_SIZE;
mProgress |= FLAG_HAS_SIZE;
}
void
@ -294,7 +295,7 @@ Decoder::PostFrameStart()
// If we just became animated, record that fact.
if (mFrameCount > 1) {
mIsAnimated = true;
mDiff.diffState |= FLAG_IS_ANIMATED;
mProgress |= FLAG_IS_ANIMATED;
}
// Decoder implementations should only call this method if they successfully
@ -326,7 +327,7 @@ Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::k
mCurrentFrame->SetBlendMethod(aBlendMethod);
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
mDiff.diffState |= FLAG_FRAME_STOPPED | FLAG_ONLOAD_UNBLOCKED;
mProgress |= FLAG_FRAME_STOPPED | FLAG_ONLOAD_UNBLOCKED;
}
void
@ -352,7 +353,7 @@ Decoder::PostDecodeDone(int32_t aLoopCount /* = 0 */)
mImageMetadata.SetLoopCount(aLoopCount);
mImageMetadata.SetIsNonPremultiplied(GetDecodeFlags() & DECODER_NO_PREMULTIPLY_ALPHA);
mDiff.diffState |= FLAG_DECODE_STOPPED;
mProgress |= FLAG_DECODE_STOPPED;
}
void

View File

@ -99,7 +99,7 @@ public:
size_t BytesDecoded() const { return mBytesDecoded; }
ImageStatusDiff GetDiff() const { return mDiff; }
Progress GetProgress() const { return mProgress; }
// The number of frames we have, including anything in-progress. Thus, this
// is only 0 if we haven't begun any frames.
@ -227,7 +227,7 @@ protected:
RasterImage &mImage;
nsRefPtr<imgFrame> mCurrentFrame;
ImageMetadata mImageMetadata;
ImageStatusDiff mDiff;
Progress mProgress;
uint8_t* mImageData; // Pointer to image data in either Cairo or 8bit format
uint32_t mImageDataLength;

View File

@ -30,8 +30,8 @@ DynamicImage::Init(const char* aMimeType, uint32_t aFlags)
return NS_OK;
}
already_AddRefed<imgStatusTracker>
DynamicImage::GetStatusTracker()
already_AddRefed<ProgressTracker>
DynamicImage::GetProgressTracker()
{
return nullptr;
}

View File

@ -34,7 +34,7 @@ public:
// Inherited methods from Image.
virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() MOZ_OVERRIDE;
virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
virtual uint32_t SizeOfData() MOZ_OVERRIDE;

View File

@ -8,7 +8,7 @@
#include "mozilla/MemoryReporting.h"
#include "imgIContainer.h"
#include "imgStatusTracker.h"
#include "ProgressTracker.h"
#include "ImageURL.h"
#include "nsStringFwd.h"
@ -63,8 +63,8 @@ public:
virtual nsresult Init(const char* aMimeType,
uint32_t aFlags) = 0;
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() = 0;
virtual void SetStatusTracker(imgStatusTracker* aStatusTracker) {}
virtual already_AddRefed<ProgressTracker> GetProgressTracker() = 0;
virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
/**
* The rectangle defining the location and size of the given frame.
@ -146,15 +146,15 @@ public:
class ImageResource : public Image
{
public:
already_AddRefed<imgStatusTracker> GetStatusTracker() MOZ_OVERRIDE {
nsRefPtr<imgStatusTracker> statusTracker = mStatusTracker;
MOZ_ASSERT(statusTracker);
return statusTracker.forget();
already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE {
nsRefPtr<ProgressTracker> progressTracker = mProgressTracker;
MOZ_ASSERT(progressTracker);
return progressTracker.forget();
}
void SetStatusTracker(imgStatusTracker* aStatusTracker) MOZ_OVERRIDE MOZ_FINAL {
MOZ_ASSERT(aStatusTracker);
MOZ_ASSERT(!mStatusTracker);
mStatusTracker = aStatusTracker;
void SetProgressTracker(ProgressTracker* aProgressTracker) MOZ_OVERRIDE MOZ_FINAL {
MOZ_ASSERT(aProgressTracker);
MOZ_ASSERT(!mProgressTracker);
mProgressTracker = aProgressTracker;
}
virtual uint32_t SizeOfData() MOZ_OVERRIDE;
@ -215,7 +215,7 @@ protected:
virtual nsresult StopAnimation() = 0;
// Member data shared by all implementations of this abstract class
nsRefPtr<imgStatusTracker> mStatusTracker;
nsRefPtr<ProgressTracker> mProgressTracker;
nsRefPtr<ImageURL> mURI;
TimeStamp mLastRefreshTime;
uint64_t mInnerWindowId;

View File

@ -96,7 +96,7 @@ ImageFactory::CanRetargetOnDataAvailable(ImageURL* aURI, bool aIsMultiPart)
/* static */ already_AddRefed<Image>
ImageFactory::CreateImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
bool aIsMultiPart,
@ -110,10 +110,10 @@ ImageFactory::CreateImage(nsIRequest* aRequest,
// Select the type of image to create based on MIME type.
if (aMimeType.EqualsLiteral(IMAGE_SVG_XML)) {
return CreateVectorImage(aRequest, aStatusTracker, aMimeType,
return CreateVectorImage(aRequest, aProgressTracker, aMimeType,
aURI, imageFlags, aInnerWindowId);
} else {
return CreateRasterImage(aRequest, aStatusTracker, aMimeType,
return CreateRasterImage(aRequest, aProgressTracker, aMimeType,
aURI, imageFlags, aInnerWindowId);
}
}
@ -185,7 +185,7 @@ GetContentSize(nsIRequest* aRequest)
/* static */ already_AddRefed<Image>
ImageFactory::CreateRasterImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
uint32_t aImageFlags,
@ -193,7 +193,7 @@ ImageFactory::CreateRasterImage(nsIRequest* aRequest,
{
nsresult rv;
nsRefPtr<RasterImage> newImage = new RasterImage(aStatusTracker, aURI);
nsRefPtr<RasterImage> newImage = new RasterImage(aProgressTracker, aURI);
rv = newImage->Init(aMimeType.get(), aImageFlags);
NS_ENSURE_SUCCESS(rv, BadImage(newImage));
@ -246,7 +246,7 @@ ImageFactory::CreateRasterImage(nsIRequest* aRequest,
/* static */ already_AddRefed<Image>
ImageFactory::CreateVectorImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
uint32_t aImageFlags,
@ -254,7 +254,7 @@ ImageFactory::CreateVectorImage(nsIRequest* aRequest,
{
nsresult rv;
nsRefPtr<VectorImage> newImage = new VectorImage(aStatusTracker, aURI);
nsRefPtr<VectorImage> newImage = new VectorImage(aProgressTracker, aURI);
rv = newImage->Init(aMimeType.get(), aImageFlags);
NS_ENSURE_SUCCESS(rv, BadImage(newImage));

View File

@ -12,13 +12,13 @@
class nsCString;
class nsIRequest;
class imgStatusTracker;
namespace mozilla {
namespace image {
class Image;
class ImageURL;
class ProgressTracker;
class ImageFactory
{
@ -40,15 +40,15 @@ public:
* Creates a new image with the given properties.
* Can be called on or off the main thread.
*
* @param aRequest The associated request.
* @param aStatusTracker A status tracker for the image to use.
* @param aMimeType The mimetype of the image.
* @param aURI The URI of the image.
* @param aIsMultiPart Whether the image is part of a multipart request.
* @param aInnerWindowId The window this image belongs to.
* @param aRequest The associated request.
* @param aProgressTracker A status tracker for the image to use.
* @param aMimeType The mimetype of the image.
* @param aURI The URI of the image.
* @param aIsMultiPart Whether the image is part of a multipart request.
* @param aInnerWindowId The window this image belongs to.
*/
static already_AddRefed<Image> CreateImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
bool aIsMultiPart,
@ -64,14 +64,14 @@ public:
private:
// Factory functions that create specific types of image containers.
static already_AddRefed<Image> CreateRasterImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
uint32_t aImageFlags,
uint32_t aInnerWindowId);
static already_AddRefed<Image> CreateVectorImage(nsIRequest* aRequest,
imgStatusTracker* aStatusTracker,
ProgressTracker* aProgressTracker,
const nsCString& aMimeType,
ImageURL* aURI,
uint32_t aImageFlags,

View File

@ -27,10 +27,10 @@ ImageWrapper::Init(const char* aMimeType, uint32_t aFlags)
return mInnerImage->Init(aMimeType, aFlags);
}
already_AddRefed<imgStatusTracker>
ImageWrapper::GetStatusTracker()
already_AddRefed<ProgressTracker>
ImageWrapper::GetProgressTracker()
{
return mInnerImage->GetStatusTracker();
return mInnerImage->GetProgressTracker();
}
nsIntRect

View File

@ -24,7 +24,7 @@ public:
// Inherited methods from Image.
virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() MOZ_OVERRIDE;
virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
virtual uint32_t SizeOfData() MOZ_OVERRIDE;

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageLogging.h"
#include "imgStatusTracker.h"
#include "ProgressTracker.h"
#include "imgIContainer.h"
#include "imgRequestProxy.h"
@ -16,11 +16,13 @@
#include "mozilla/Assertions.h"
#include "mozilla/Services.h"
using namespace mozilla::image;
using mozilla::WeakPtr;
imgStatusTrackerInit::imgStatusTrackerInit(mozilla::image::Image* aImage,
imgStatusTracker* aTracker)
namespace mozilla {
namespace image {
ProgressTrackerInit::ProgressTrackerInit(Image* aImage,
ProgressTracker* aTracker)
{
MOZ_ASSERT(aImage);
@ -28,19 +30,19 @@ imgStatusTrackerInit::imgStatusTrackerInit(mozilla::image::Image* aImage,
mTracker = aTracker;
mTracker->SetImage(aImage);
} else {
mTracker = new imgStatusTracker(aImage);
mTracker = new ProgressTracker(aImage);
}
aImage->SetStatusTracker(mTracker);
aImage->SetProgressTracker(mTracker);
MOZ_ASSERT(mTracker);
}
imgStatusTrackerInit::~imgStatusTrackerInit()
ProgressTrackerInit::~ProgressTrackerInit()
{
mTracker->ResetImage();
}
void
imgStatusTracker::SetImage(Image* aImage)
ProgressTracker::SetImage(Image* aImage)
{
NS_ABORT_IF_FALSE(aImage, "Setting null image");
NS_ABORT_IF_FALSE(!mImage, "Setting image when we already have one");
@ -48,53 +50,53 @@ imgStatusTracker::SetImage(Image* aImage)
}
void
imgStatusTracker::ResetImage()
ProgressTracker::ResetImage()
{
NS_ABORT_IF_FALSE(mImage, "Resetting image when it's already null!");
mImage = nullptr;
}
void imgStatusTracker::SetIsMultipart()
void ProgressTracker::SetIsMultipart()
{
mState |= FLAG_IS_MULTIPART;
mProgress |= FLAG_IS_MULTIPART;
// If we haven't already blocked onload, make sure we never do.
if (!(mState & FLAG_ONLOAD_BLOCKED)) {
mState |= FLAG_ONLOAD_BLOCKED | FLAG_ONLOAD_UNBLOCKED;
if (!(mProgress & FLAG_ONLOAD_BLOCKED)) {
mProgress |= FLAG_ONLOAD_BLOCKED | FLAG_ONLOAD_UNBLOCKED;
}
}
bool
imgStatusTracker::IsLoading() const
ProgressTracker::IsLoading() const
{
// Checking for whether OnStopRequest has fired allows us to say we're
// loading before OnStartRequest gets called, letting the request properly
// get removed from the cache in certain cases.
return !(mState & FLAG_REQUEST_STOPPED);
return !(mProgress & FLAG_REQUEST_STOPPED);
}
uint32_t
imgStatusTracker::GetImageStatus() const
ProgressTracker::GetImageStatus() const
{
uint32_t status = imgIRequest::STATUS_NONE;
// Translate our current state to a set of imgIRequest::STATE_* flags.
if (mState & FLAG_HAS_SIZE) {
if (mProgress & FLAG_HAS_SIZE) {
status |= imgIRequest::STATUS_SIZE_AVAILABLE;
}
if (mState & FLAG_DECODE_STARTED) {
if (mProgress & FLAG_DECODE_STARTED) {
status |= imgIRequest::STATUS_DECODE_STARTED;
}
if (mState & FLAG_DECODE_STOPPED) {
if (mProgress & FLAG_DECODE_STOPPED) {
status |= imgIRequest::STATUS_DECODE_COMPLETE;
}
if (mState & FLAG_FRAME_STOPPED) {
if (mProgress & FLAG_FRAME_STOPPED) {
status |= imgIRequest::STATUS_FRAME_COMPLETE;
}
if (mState & FLAG_REQUEST_STOPPED) {
if (mProgress & FLAG_REQUEST_STOPPED) {
status |= imgIRequest::STATUS_LOAD_COMPLETE;
}
if (mState & FLAG_HAS_ERROR) {
if (mProgress & FLAG_HAS_ERROR) {
status |= imgIRequest::STATUS_ERROR;
}
@ -102,16 +104,16 @@ imgStatusTracker::GetImageStatus() const
}
// A helper class to allow us to call SyncNotify asynchronously.
class imgRequestNotifyRunnable : public nsRunnable
class AsyncNotifyRunnable : public nsRunnable
{
public:
imgRequestNotifyRunnable(imgStatusTracker* aTracker,
imgRequestProxy* aRequestProxy)
AsyncNotifyRunnable(ProgressTracker* aTracker,
imgRequestProxy* aRequestProxy)
: mTracker(aTracker)
{
MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
MOZ_ASSERT(aRequestProxy, "aRequestProxy should not be null");
MOZ_ASSERT(aTracker, "aTracker should not be null");
MOZ_ASSERT(aRequestProxy, "aRequestProxy should not be null");
mProxies.AppendElement(aRequestProxy);
}
@ -124,7 +126,7 @@ class imgRequestNotifyRunnable : public nsRunnable
mTracker->SyncNotify(mProxies[i]);
}
mTracker->mRequestRunnable = nullptr;
mTracker->mRunnable = nullptr;
return NS_OK;
}
@ -139,14 +141,14 @@ class imgRequestNotifyRunnable : public nsRunnable
}
private:
friend class imgStatusTracker;
friend class ProgressTracker;
nsRefPtr<imgStatusTracker> mTracker;
nsTArray< nsRefPtr<imgRequestProxy> > mProxies;
nsRefPtr<ProgressTracker> mTracker;
nsTArray<nsRefPtr<imgRequestProxy>> mProxies;
};
void
imgStatusTracker::Notify(imgRequestProxy* proxy)
ProgressTracker::Notify(imgRequestProxy* proxy)
{
MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
#ifdef PR_LOGGING
@ -154,9 +156,9 @@ imgStatusTracker::Notify(imgRequestProxy* proxy)
nsRefPtr<ImageURL> uri(mImage->GetURI());
nsAutoCString spec;
uri->GetSpec(spec);
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgStatusTracker::Notify async", "uri", spec.get());
LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", spec.get());
} else {
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgStatusTracker::Notify async", "uri", "<unknown>");
LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::Notify async", "uri", "<unknown>");
}
#endif
@ -165,28 +167,31 @@ imgStatusTracker::Notify(imgRequestProxy* proxy)
// If we have an existing runnable that we can use, we just append this proxy
// to its list of proxies to be notified. This ensures we don't unnecessarily
// delay onload.
imgRequestNotifyRunnable* runnable = static_cast<imgRequestNotifyRunnable*>(mRequestRunnable.get());
AsyncNotifyRunnable* runnable =
static_cast<AsyncNotifyRunnable*>(mRunnable.get());
if (runnable) {
runnable->AddProxy(proxy);
} else {
mRequestRunnable = new imgRequestNotifyRunnable(this, proxy);
NS_DispatchToCurrentThread(mRequestRunnable);
mRunnable = new AsyncNotifyRunnable(this, proxy);
NS_DispatchToCurrentThread(mRunnable);
}
}
// A helper class to allow us to call SyncNotify asynchronously for a given,
// fixed, state.
class imgStatusNotifyRunnable : public nsRunnable
class AsyncNotifyCurrentStateRunnable : public nsRunnable
{
public:
imgStatusNotifyRunnable(imgStatusTracker* statusTracker,
imgRequestProxy* requestproxy)
: mStatusTracker(statusTracker), mProxy(requestproxy)
AsyncNotifyCurrentStateRunnable(ProgressTracker* aProgressTracker,
imgRequestProxy* aProxy)
: mProgressTracker(aProgressTracker)
, mProxy(aProxy)
{
MOZ_ASSERT(NS_IsMainThread(), "Should be created on the main thread");
MOZ_ASSERT(requestproxy, "requestproxy cannot be null");
MOZ_ASSERT(statusTracker, "status should not be null");
mImage = statusTracker->GetImage();
MOZ_ASSERT(mProgressTracker, "mProgressTracker should not be null");
MOZ_ASSERT(mProxy, "mProxy should not be null");
mImage = mProgressTracker->GetImage();
}
NS_IMETHOD Run()
@ -194,20 +199,21 @@ class imgStatusNotifyRunnable : public nsRunnable
MOZ_ASSERT(NS_IsMainThread(), "Should be running on the main thread");
mProxy->SetNotificationsDeferred(false);
mStatusTracker->SyncNotify(mProxy);
mProgressTracker->SyncNotify(mProxy);
return NS_OK;
}
private:
nsRefPtr<imgStatusTracker> mStatusTracker;
nsRefPtr<ProgressTracker> mProgressTracker;
nsRefPtr<imgRequestProxy> mProxy;
// We have to hold on to a reference to the tracker's image, just in case
// it goes away while we're in the event queue.
nsRefPtr<Image> mImage;
nsRefPtr<imgRequestProxy> mProxy;
};
void
imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
ProgressTracker::NotifyCurrentState(imgRequestProxy* proxy)
{
MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
#ifdef PR_LOGGING
@ -215,13 +221,12 @@ imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
proxy->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgStatusTracker::NotifyCurrentState", "uri", spec.get());
LOG_FUNC_WITH_PARAM(GetImgLog(), "ProgressTracker::NotifyCurrentState", "uri", spec.get());
#endif
proxy->SetNotificationsDeferred(true);
// We don't keep track of
nsCOMPtr<nsIRunnable> ev = new imgStatusNotifyRunnable(this, proxy);
nsCOMPtr<nsIRunnable> ev = new AsyncNotifyCurrentStateRunnable(this, proxy);
NS_DispatchToCurrentThread(ev);
}
@ -237,26 +242,26 @@ imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
} while (false);
/* static */ void
imgStatusTracker::SyncNotifyState(ProxyArray& aProxies,
bool aHasImage,
uint32_t aState,
const nsIntRect& aDirtyRect)
ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies,
bool aHasImage,
Progress aProgress,
const nsIntRect& aDirtyRect)
{
MOZ_ASSERT(NS_IsMainThread());
// OnStartRequest
if (aState & FLAG_REQUEST_STARTED)
if (aProgress & FLAG_REQUEST_STARTED)
NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartRequest());
// OnStartContainer
if (aState & FLAG_HAS_SIZE)
if (aProgress & FLAG_HAS_SIZE)
NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartContainer());
// OnStartDecode
if (aState & FLAG_DECODE_STARTED)
if (aProgress & FLAG_DECODE_STARTED)
NOTIFY_IMAGE_OBSERVERS(aProxies, OnStartDecode());
// BlockOnload
if (aState & FLAG_ONLOAD_BLOCKED)
if (aProgress & FLAG_ONLOAD_BLOCKED)
NOTIFY_IMAGE_OBSERVERS(aProxies, BlockOnload());
if (aHasImage) {
@ -267,66 +272,57 @@ imgStatusTracker::SyncNotifyState(ProxyArray& aProxies,
if (!aDirtyRect.IsEmpty())
NOTIFY_IMAGE_OBSERVERS(aProxies, OnFrameUpdate(&aDirtyRect));
if (aState & FLAG_FRAME_STOPPED)
if (aProgress & FLAG_FRAME_STOPPED)
NOTIFY_IMAGE_OBSERVERS(aProxies, OnStopFrame());
// OnImageIsAnimated
if (aState & FLAG_IS_ANIMATED)
if (aProgress & FLAG_IS_ANIMATED)
NOTIFY_IMAGE_OBSERVERS(aProxies, OnImageIsAnimated());
}
// Send UnblockOnload before OnStopDecode and OnStopRequest. This allows
// observers that can fire events when they receive those notifications to do
// so then, instead of being forced to wait for UnblockOnload.
if (aState & FLAG_ONLOAD_UNBLOCKED) {
if (aProgress & FLAG_ONLOAD_UNBLOCKED) {
NOTIFY_IMAGE_OBSERVERS(aProxies, UnblockOnload());
}
if (aState & FLAG_DECODE_STOPPED) {
if (aProgress & FLAG_DECODE_STOPPED) {
MOZ_ASSERT(aHasImage, "Stopped decoding without ever having an image?");
NOTIFY_IMAGE_OBSERVERS(aProxies, OnStopDecode());
}
if (aState & FLAG_REQUEST_STOPPED) {
if (aProgress & FLAG_REQUEST_STOPPED) {
NOTIFY_IMAGE_OBSERVERS(aProxies,
OnStopRequest(aState & FLAG_MULTIPART_STOPPED));
OnStopRequest(aProgress & FLAG_MULTIPART_STOPPED));
}
}
ImageStatusDiff
imgStatusTracker::Difference(const ImageStatusDiff& aOther) const
{
ImageStatusDiff diff;
diff.diffState = ~mState & aOther.diffState;
return diff;
}
void
imgStatusTracker::SyncNotifyDifference(const ImageStatusDiff& aDiff,
const nsIntRect& aInvalidRect /* = nsIntRect() */)
ProgressTracker::SyncNotifyProgress(Progress aProgress,
const nsIntRect& aInvalidRect /* = nsIntRect() */)
{
MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
LOG_SCOPE(GetImgLog(), "imgStatusTracker::SyncNotifyDifference");
// Don't unblock onload if we're not blocked.
ImageStatusDiff diff = Difference(aDiff);
if (!((mState | diff.diffState) & FLAG_ONLOAD_BLOCKED)) {
diff.diffState &= ~FLAG_ONLOAD_UNBLOCKED;
Progress progress = Difference(aProgress);
if (!((mProgress | progress) & FLAG_ONLOAD_BLOCKED)) {
progress &= ~FLAG_ONLOAD_UNBLOCKED;
}
// Apply the changes.
mState |= diff.diffState;
mProgress |= progress;
// Send notifications.
SyncNotifyState(mConsumers, !!mImage, diff.diffState, aInvalidRect);
SyncNotifyInternal(mConsumers, !!mImage, progress, aInvalidRect);
if (diff.diffState & FLAG_HAS_ERROR) {
if (progress & FLAG_HAS_ERROR) {
FireFailureNotification();
}
}
void
imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
ProgressTracker::SyncNotify(imgRequestProxy* proxy)
{
MOZ_ASSERT(NS_IsMainThread(), "imgRequestProxy is not threadsafe");
#ifdef PR_LOGGING
@ -334,7 +330,7 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
proxy->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_SCOPE_WITH_PARAM(GetImgLog(), "imgStatusTracker::SyncNotify", "uri", spec.get());
LOG_SCOPE_WITH_PARAM(GetImgLog(), "ProgressTracker::SyncNotify", "uri", spec.get());
#endif
nsIntRect r;
@ -346,12 +342,12 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
ProxyArray array;
array.AppendElement(proxy);
SyncNotifyState(array, !!mImage, mState, r);
SyncNotifyInternal(array, !!mImage, mProgress, r);
}
void
imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
nsresult aStatus)
ProgressTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread(),
"SyncNotifyState and mConsumers are not threadsafe");
@ -359,21 +355,21 @@ imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
// In certain cases the request might not have started yet.
// We still need to fulfill the contract.
if (!(mState & FLAG_REQUEST_STARTED)) {
if (!(mProgress & FLAG_REQUEST_STARTED)) {
aProxy->OnStartRequest();
}
if (mState & FLAG_ONLOAD_BLOCKED && !(mState & FLAG_ONLOAD_UNBLOCKED)) {
if (mProgress & FLAG_ONLOAD_BLOCKED && !(mProgress & FLAG_ONLOAD_UNBLOCKED)) {
aProxy->UnblockOnload();
}
if (!(mState & FLAG_REQUEST_STOPPED)) {
if (!(mProgress & FLAG_REQUEST_STOPPED)) {
aProxy->OnStopRequest(true);
}
}
void
imgStatusTracker::AddConsumer(imgRequestProxy* aConsumer)
ProgressTracker::AddConsumer(imgRequestProxy* aConsumer)
{
MOZ_ASSERT(NS_IsMainThread());
mConsumers.AppendElementUnlessExists(aConsumer);
@ -381,7 +377,7 @@ imgStatusTracker::AddConsumer(imgRequestProxy* aConsumer)
// XXX - The last argument should go away.
bool
imgStatusTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
ProgressTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
// Remove the proxy from the list.
@ -395,7 +391,9 @@ imgStatusTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
// Make sure we don't give callbacks to a consumer that isn't interested in
// them any more.
imgRequestNotifyRunnable* runnable = static_cast<imgRequestNotifyRunnable*>(mRequestRunnable.get());
AsyncNotifyRunnable* runnable =
static_cast<AsyncNotifyRunnable*>(mRunnable.get());
if (aConsumer->NotificationsDeferred() && runnable) {
runnable->RemoveProxy(aConsumer);
aConsumer->SetNotificationsDeferred(false);
@ -405,7 +403,7 @@ imgStatusTracker::RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus)
}
bool
imgStatusTracker::FirstConsumerIs(imgRequestProxy* aConsumer)
ProgressTracker::FirstConsumerIs(imgRequestProxy* aConsumer)
{
MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
ProxyArray::ForwardIterator iter(mConsumers);
@ -419,38 +417,38 @@ imgStatusTracker::FirstConsumerIs(imgRequestProxy* aConsumer)
}
void
imgStatusTracker::OnUnlockedDraw()
ProgressTracker::OnUnlockedDraw()
{
MOZ_ASSERT(NS_IsMainThread());
NOTIFY_IMAGE_OBSERVERS(mConsumers, OnUnlockedDraw());
}
void
imgStatusTracker::ResetForNewRequest()
ProgressTracker::ResetForNewRequest()
{
MOZ_ASSERT(NS_IsMainThread());
// We're starting a new load (and if this is called more than once, this is a
// multipart request) so keep only the bits that carry over between loads.
mState &= FLAG_IS_MULTIPART | FLAG_HAS_ERROR;
mProgress &= FLAG_IS_MULTIPART | FLAG_HAS_ERROR;
}
void
imgStatusTracker::OnDiscard()
ProgressTracker::OnDiscard()
{
MOZ_ASSERT(NS_IsMainThread());
NOTIFY_IMAGE_OBSERVERS(mConsumers, OnDiscard());
}
void
imgStatusTracker::OnImageAvailable()
ProgressTracker::OnImageAvailable()
{
if (!NS_IsMainThread()) {
// Note: SetHasImage calls Image::Lock and Image::IncrementAnimationCounter
// so subsequent calls or dispatches which Unlock or Decrement~ should
// be issued after this to avoid race conditions.
NS_DispatchToMainThread(
NS_NewRunnableMethod(this, &imgStatusTracker::OnImageAvailable));
NS_NewRunnableMethod(this, &ProgressTracker::OnImageAvailable));
return;
}
@ -458,7 +456,7 @@ imgStatusTracker::OnImageAvailable()
}
void
imgStatusTracker::FireFailureNotification()
ProgressTracker::FireFailureNotification()
{
MOZ_ASSERT(NS_IsMainThread());
@ -479,3 +477,6 @@ imgStatusTracker::FireFailureNotification()
}
}
}
} // namespace image
} // namespace mozilla

View File

@ -4,14 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef imgStatusTracker_h__
#define imgStatusTracker_h__
class imgIContainer;
class imgStatusNotifyRunnable;
class imgRequestNotifyRunnable;
class imgStatusTrackerObserver;
class nsIRunnable;
#ifndef ProgressTracker_h__
#define ProgressTracker_h__
#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
@ -21,12 +15,17 @@ class nsIRunnable;
#include "nsRect.h"
#include "imgRequestProxy.h"
class imgIContainer;
class nsIRunnable;
namespace mozilla {
namespace image {
class AsyncNotifyRunnable;
class AsyncNotifyCurrentStateRunnable;
class Image;
// Image state bitflags.
// Image progress bitflags.
enum {
FLAG_REQUEST_STARTED = 1u << 0,
FLAG_HAS_SIZE = 1u << 1, // STATUS_SIZE_AVAILABLE
@ -42,85 +41,61 @@ enum {
FLAG_HAS_ERROR = 1u << 11 // STATUS_ERROR
};
struct ImageStatusDiff
typedef uint32_t Progress;
const uint32_t NoProgress = 0;
inline Progress OnStopRequestProgress(bool aLastPart,
bool aError,
nsresult aStatus)
{
ImageStatusDiff()
: diffState(0)
{ }
static ImageStatusDiff NoChange() { return ImageStatusDiff(); }
bool IsNoChange() const { return *this == NoChange(); }
static ImageStatusDiff ForOnStopRequest(bool aLastPart,
bool aError,
nsresult aStatus)
{
ImageStatusDiff diff;
diff.diffState |= FLAG_REQUEST_STOPPED;
if (aLastPart) {
diff.diffState |= FLAG_MULTIPART_STOPPED;
}
if (NS_FAILED(aStatus) || aError) {
diff.diffState |= FLAG_HAS_ERROR;
}
return diff;
Progress progress = FLAG_REQUEST_STOPPED;
if (aLastPart) {
progress |= FLAG_MULTIPART_STOPPED;
}
bool operator!=(const ImageStatusDiff& aOther) const { return !(*this == aOther); }
bool operator==(const ImageStatusDiff& aOther) const {
return aOther.diffState == diffState;
if (NS_FAILED(aStatus) || aError) {
progress |= FLAG_HAS_ERROR;
}
return progress;
}
void Combine(const ImageStatusDiff& aOther) {
diffState |= aOther.diffState;
}
uint32_t diffState;
};
} // namespace image
} // namespace mozilla
/*
* The image status tracker is a class that encapsulates all the loading and
* decoding status about an Image, and makes it possible to send notifications
* to imgRequestProxys, both synchronously (i.e., the status now) and
* asynchronously (the status later).
/**
* ProgressTracker is a class that records an Image's progress through the
* loading and decoding process, and makes it possible to send notifications to
* imgRequestProxys, both synchronously and asynchronously.
*
* When a new proxy needs to be notified of the current state of an image, call
* the Notify() method on this class with the relevant proxy as its argument,
* and the notifications will be replayed to the proxy asynchronously.
* When a new proxy needs to be notified of the current progress of an image,
* call the Notify() method on this class with the relevant proxy as its
* argument, and the notifications will be replayed to the proxy asynchronously.
*/
class imgStatusTracker : public mozilla::SupportsWeakPtr<imgStatusTracker>
class ProgressTracker : public mozilla::SupportsWeakPtr<ProgressTracker>
{
virtual ~imgStatusTracker() { }
virtual ~ProgressTracker() { }
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(imgStatusTracker)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(imgStatusTracker)
MOZ_DECLARE_REFCOUNTED_TYPENAME(ProgressTracker)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ProgressTracker)
// aImage is the image that this status tracker will pass to the
// imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
// alive as long as this instance is, because we hold a weak reference to it.
explicit imgStatusTracker(mozilla::image::Image* aImage)
// aImage is the image that will be passed to the observers in SyncNotify()
// and EmulateRequestFinished(), and must be alive as long as this instance
// is, because we hold a weak reference to it.
explicit ProgressTracker(Image* aImage)
: mImage(aImage)
, mState(0)
, mProgress(NoProgress)
{ }
bool HasImage() const { return mImage; }
already_AddRefed<mozilla::image::Image> GetImage() const
already_AddRefed<Image> GetImage() const
{
nsRefPtr<mozilla::image::Image> image = mImage;
nsRefPtr<Image> image = mImage;
return image.forget();
}
// Inform this status tracker that it is associated with a multipart image.
// Informs this ProgressTracker that it's associated with a multipart image.
void SetIsMultipart();
// Returns whether we are in the process of loading; that is, whether we have
// not received OnStopRequest.
// not received OnStopRequest from Necko.
bool IsLoading() const;
// Get the current image status (as in imgIRequest).
@ -152,7 +127,7 @@ public:
// are not threadsafe.
void SyncNotify(imgRequestProxy* proxy);
// Get this imgStatusTracker ready for a new request. This resets all the
// Get this ProgressTracker ready for a new request. This resets all the
// state that doesn't persist between requests.
void ResetForNewRequest();
@ -162,17 +137,23 @@ public:
void OnUnlockedDraw();
void OnImageAvailable();
// Compute the difference between this status tracker and aOther.
mozilla::image::ImageStatusDiff Difference(const mozilla::image::ImageStatusDiff& aOther) const;
// Compute the difference between this our progress and aProgress. This allows
// callers to predict whether SyncNotifyProgress will send any notifications.
Progress Difference(Progress aProgress) const
{
return ~mProgress & aProgress;
}
// Notify for the changes captured in an ImageStatusDiff. Because this may
// result in recursive notifications, no decoding locks may be held.
// Called on the main thread only.
void SyncNotifyDifference(const mozilla::image::ImageStatusDiff& aDiff,
const nsIntRect& aInvalidRect = nsIntRect());
// Update our state to incorporate the changes in aProgress and synchronously
// notify our observers.
//
// Because this may result in recursive notifications, no decoding locks may
// be held. Called on the main thread only.
void SyncNotifyProgress(Progress aProgress,
const nsIntRect& aInvalidRect = nsIntRect());
// We manage a set of consumers that are using an image and thus concerned
// with its status. Weak pointers.
// with its loading progress. Weak pointers.
void AddConsumer(imgRequestProxy* aConsumer);
bool RemoveConsumer(imgRequestProxy* aConsumer, nsresult aStatus);
size_t ConsumerCount() const {
@ -185,7 +166,7 @@ public:
// be improved, but it's too scary to mess with at the moment.
bool FirstConsumerIs(imgRequestProxy* aConsumer);
void AdoptConsumers(imgStatusTracker* aTracker) {
void AdoptConsumers(ProgressTracker* aTracker) {
MOZ_ASSERT(NS_IsMainThread(), "Use mConsumers on main thread only");
MOZ_ASSERT(aTracker);
mConsumers = aTracker->mConsumers;
@ -193,18 +174,18 @@ public:
private:
typedef nsTObserverArray<mozilla::WeakPtr<imgRequestProxy>> ProxyArray;
friend class imgStatusNotifyRunnable;
friend class imgRequestNotifyRunnable;
friend class imgStatusTrackerInit;
friend class AsyncNotifyRunnable;
friend class AsyncNotifyCurrentStateRunnable;
friend class ProgressTrackerInit;
imgStatusTracker(const imgStatusTracker& aOther) MOZ_DELETE;
ProgressTracker(const ProgressTracker& aOther) MOZ_DELETE;
// This method should only be called once, and only on an imgStatusTracker
// that was initialized without an image. imgStatusTrackerInit automates this.
void SetImage(mozilla::image::Image* aImage);
// This method should only be called once, and only on an ProgressTracker
// that was initialized without an image. ProgressTrackerInit automates this.
void SetImage(Image* aImage);
// Resets our weak reference to our image, for when mImage is about to go out
// of scope. imgStatusTrackerInit automates this.
// of scope. ProgressTrackerInit automates this.
void ResetImage();
// Send some notifications that would be necessary to make |aProxy| believe
@ -217,31 +198,33 @@ private:
// Main thread only, since imgRequestProxy calls are expected on the main
// thread, and mConsumers is not threadsafe.
static void SyncNotifyState(ProxyArray& aProxies,
bool aHasImage, uint32_t aState,
const nsIntRect& aInvalidRect);
static void SyncNotifyInternal(ProxyArray& aProxies,
bool aHasImage, Progress aProgress,
const nsIntRect& aInvalidRect);
nsCOMPtr<nsIRunnable> mRequestRunnable;
nsCOMPtr<nsIRunnable> mRunnable;
// This weak ref should be set null when the image goes out of scope.
mozilla::image::Image* mImage;
Image* mImage;
// List of proxies attached to the image. Each proxy represents a consumer
// using the image. Array and/or individual elements should only be accessed
// on the main thread.
ProxyArray mConsumers;
uint32_t mState;
Progress mProgress;
};
class imgStatusTrackerInit
class ProgressTrackerInit
{
public:
imgStatusTrackerInit(mozilla::image::Image* aImage,
imgStatusTracker* aTracker);
~imgStatusTrackerInit();
ProgressTrackerInit(Image* aImage, ProgressTracker* aTracker);
~ProgressTrackerInit();
private:
imgStatusTracker* mTracker;
ProgressTracker* mTracker;
};
} // namespace image
} // namespace mozilla
#endif

View File

@ -307,7 +307,7 @@ NS_IMPL_ISUPPORTS(RasterImage, imgIContainer, nsIProperties,
#endif
//******************************************************************************
RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
RasterImage::RasterImage(ProgressTracker* aProgressTracker,
ImageURL* aURI /* = nullptr */) :
ImageResource(aURI), // invoke superclass's constructor
mSize(0,0),
@ -320,7 +320,7 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
#endif
mDecodingMonitor("RasterImage Decoding Monitor"),
mDecoder(nullptr),
mStatusDiff(ImageStatusDiff::NoChange()),
mNotifyProgress(NoProgress),
mNotifying(false),
mHasSize(false),
mDecodeOnDraw(false),
@ -333,7 +333,7 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker,
mWantFullDecode(false),
mPendingError(false)
{
mStatusTrackerInit = new imgStatusTrackerInit(this, aStatusTracker);
mProgressTrackerInit = new ProgressTrackerInit(this, aProgressTracker);
// Set up the discard tracker node.
mDiscardTrackerNode.img = this;
@ -480,9 +480,8 @@ RasterImage::RequestRefresh(const TimeStamp& aTime)
UpdateImageContainer();
if (mStatusTracker) {
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(),
res.dirtyRect);
if (mProgressTracker) {
mProgressTracker->SyncNotifyProgress(NoProgress, res.dirtyRect);
}
}
@ -710,7 +709,7 @@ RasterImage::FrameRect(uint32_t aWhichFrame)
// If the frame doesn't exist, we return the empty rectangle. It's not clear
// whether this is appropriate in general, but at the moment the only
// consumer of this method is imgStatusTracker (when it wants to figure out
// consumer of this method is ProgressTracker (when it wants to figure out
// dirty rectangles to send out batched observer updates). This should
// probably be revisited when we fix bug 503973.
return nsIntRect();
@ -922,8 +921,8 @@ RasterImage::GetImageContainer(LayerManager* aManager, ImageContainer **_retval)
return NS_OK;
}
if (IsUnlocked() && mStatusTracker) {
mStatusTracker->OnUnlockedDraw();
if (IsUnlocked() && mProgressTracker) {
mProgressTracker->OnUnlockedDraw();
}
if (!mImageContainer) {
@ -1448,9 +1447,9 @@ RasterImage::ResetAnimation()
// we fix bug 500402.
// Update display
if (mStatusTracker) {
if (mProgressTracker) {
nsIntRect rect = mAnim->GetFirstFrameRefreshArea();
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(), rect);
mProgressTracker->SyncNotifyProgress(NoProgress, rect);
}
// Start the animation again. It may not have been running before, if
@ -1675,13 +1674,12 @@ RasterImage::OnImageDataComplete(nsIRequest*, nsISupports*, nsresult aStatus, bo
if (NS_FAILED(aStatus))
finalStatus = aStatus;
ImageStatusDiff diff =
ImageStatusDiff::ForOnStopRequest(aLastPart, mError, finalStatus);
// We just recorded OnStopRequest; we need to inform our listeners.
{
ReentrantMonitorAutoEnter lock(mDecodingMonitor);
FinishedSomeDecoding(eShutdownIntent_Done, nullptr, diff);
FinishedSomeDecoding(eShutdownIntent_Done,
nullptr,
OnStopRequestProgress(aLastPart, mError, finalStatus));
}
return finalStatus;
@ -1845,8 +1843,8 @@ RasterImage::Discard(bool force)
mDecoded = false;
// Notify that we discarded
if (mStatusTracker)
mStatusTracker->OnDiscard();
if (mProgressTracker)
mProgressTracker->OnDiscard();
mDecodeRequest = nullptr;
@ -2435,11 +2433,11 @@ RasterImage::CanScale(GraphicsFilter aFilter,
void
RasterImage::NotifyNewScaledFrame()
{
if (mStatusTracker) {
if (mProgressTracker) {
// Send an invalidation so observers will repaint and can take advantage of
// the new scaled frame if possible.
nsIntRect rect(0, 0, mSize.width, mSize.height);
mStatusTracker->SyncNotifyDifference(ImageStatusDiff::NoChange(), rect);
mProgressTracker->SyncNotifyProgress(NoProgress, rect);
}
}
@ -2593,8 +2591,8 @@ RasterImage::Draw(gfxContext* aContext,
}
if (IsUnlocked() && mStatusTracker) {
mStatusTracker->OnUnlockedDraw();
if (IsUnlocked() && mProgressTracker) {
mProgressTracker->OnUnlockedDraw();
}
// We use !mDecoded && mHasSourceData to mean discarded.
@ -2914,7 +2912,7 @@ RasterImage::RequestDecodeIfNeeded(nsresult aStatus,
nsresult
RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_Done */,
DecodeRequest* aRequest /* = nullptr */,
const ImageStatusDiff& aDiff /* = ImageStatusDiff::NoChange() */)
Progress aProgress /* = NoProgress */)
{
MOZ_ASSERT(NS_IsMainThread());
@ -2935,11 +2933,11 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
bool wasSize = false;
nsIntRect invalidRect;
nsresult rv = NS_OK;
ImageStatusDiff diff = aDiff;
Progress progress = aProgress;
if (image->mDecoder) {
invalidRect = image->mDecoder->TakeInvalidRect();
diff.Combine(image->mDecoder->GetDiff());
progress |= image->mDecoder->GetProgress();
if (request && request->mChunkCount && !image->mDecoder->IsSizeDecode()) {
Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, request->mChunkCount);
@ -2981,8 +2979,8 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
image->DoError();
}
// If there were any final state changes, grab them.
diff.Combine(decoder->GetDiff());
// If there were any final progress changes, grab them.
progress |= decoder->GetProgress();
}
}
@ -2998,32 +2996,33 @@ RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_D
}
if (mNotifying) {
// Accumulate the status changes. We don't permit recursive notifications
// Accumulate the progress changes. We don't permit recursive notifications
// because they cause subtle concurrency bugs, so we'll delay sending out
// the notifications until we pop back to the lowest invocation of
// FinishedSomeDecoding on the stack.
NS_WARNING("Recursively notifying in RasterImage::FinishedSomeDecoding!");
mStatusDiff.Combine(diff);
mInvalidRect.Union(invalidRect);
mNotifyProgress |= progress;
mNotifyInvalidRect.Union(invalidRect);
} else {
MOZ_ASSERT(mStatusDiff.IsNoChange(), "Shouldn't have an accumulated change at this point");
MOZ_ASSERT(mInvalidRect.IsEmpty(), "Shouldn't have an accumulated invalidation rect here");
MOZ_ASSERT(mNotifyProgress == NoProgress && mNotifyInvalidRect.IsEmpty(),
"Shouldn't have an accumulated change at this point");
diff = image->mStatusTracker->Difference(diff);
progress = image->mProgressTracker->Difference(progress);
while (!diff.IsNoChange() || !invalidRect.IsEmpty()) {
while (progress != NoProgress || !invalidRect.IsEmpty()) {
// Tell the observers what happened.
mNotifying = true;
image->mStatusTracker->SyncNotifyDifference(diff, invalidRect);
image->mProgressTracker->SyncNotifyProgress(progress, invalidRect);
mNotifying = false;
// Gather any status changes that may have occurred as a result of sending
// Gather any progress changes that may have occurred as a result of sending
// out the previous notifications. If there were any, we'll send out
// notifications for them next.
diff = image->mStatusTracker->Difference(mStatusDiff);
mStatusDiff = ImageStatusDiff::NoChange();
invalidRect = mInvalidRect;
mInvalidRect = nsIntRect();
progress = image->mProgressTracker->Difference(mNotifyProgress);
mNotifyProgress = NoProgress;
invalidRect = mNotifyInvalidRect;
mNotifyInvalidRect = nsIntRect();
}
}

View File

@ -513,7 +513,7 @@ private:
nsresult FinishedSomeDecoding(eShutdownIntent intent = eShutdownIntent_Done,
DecodeRequest* request = nullptr,
const ImageStatusDiff& aDiff = ImageStatusDiff::NoChange());
Progress aProgress = NoProgress);
void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
gfxContext* aContext,
@ -641,8 +641,8 @@ private: // data
// END LOCKED MEMBER VARIABLES
// Notification state. Used to avoid recursive notifications.
ImageStatusDiff mStatusDiff;
nsIntRect mInvalidRect;
Progress mNotifyProgress;
nsIntRect mNotifyInvalidRect;
bool mNotifying:1;
// Boolean flags (clustered together to conserve space):
@ -683,8 +683,8 @@ private: // data
bool IsDecodeFinished();
TimeStamp mDrawStartTime;
// Initializes imgStatusTracker and resets it on RasterImage destruction.
nsAutoPtr<imgStatusTrackerInit> mStatusTrackerInit;
// Initializes ProgressTracker and resets it on RasterImage destruction.
nsAutoPtr<ProgressTrackerInit> mProgressTrackerInit;
nsresult ShutdownDecoder(eShutdownIntent aIntent);
@ -734,7 +734,7 @@ private: // data
bool StoringSourceData() const;
protected:
explicit RasterImage(imgStatusTracker* aStatusTracker = nullptr,
explicit RasterImage(ProgressTracker* aProgressTracker = nullptr,
ImageURL* aURI = nullptr);
bool ShouldAnimate();

View File

@ -322,7 +322,7 @@ NS_IMPL_ISUPPORTS(VectorImage,
//------------------------------------------------------------------------------
// Constructor / Destructor
VectorImage::VectorImage(imgStatusTracker* aStatusTracker,
VectorImage::VectorImage(ProgressTracker* aProgressTracker,
ImageURL* aURI /* = nullptr */) :
ImageResource(aURI), // invoke superclass's constructor
mIsInitialized(false),
@ -331,7 +331,7 @@ VectorImage::VectorImage(imgStatusTracker* aStatusTracker,
mHaveAnimations(false),
mHasPendingInvalidation(false)
{
mStatusTrackerInit = new imgStatusTrackerInit(this, aStatusTracker);
mProgressTrackerInit = new ProgressTrackerInit(this, aProgressTracker);
}
VectorImage::~VectorImage()
@ -433,7 +433,7 @@ VectorImage::OnImageDataComplete(nsIRequest* aRequest,
bool aLastPart)
{
// Call our internal OnStopRequest method, which only talks to our embedded
// SVG document. This won't have any effect on our imgStatusTracker.
// SVG document. This won't have any effect on our ProgressTracker.
nsresult finalStatus = OnStopRequest(aRequest, aContext, aStatus);
// Give precedence to Necko failure codes.
@ -441,10 +441,10 @@ VectorImage::OnImageDataComplete(nsIRequest* aRequest,
finalStatus = aStatus;
// Actually fire OnStopRequest.
if (mStatusTracker) {
ImageStatusDiff diff =
ImageStatusDiff::ForOnStopRequest(aLastPart, mError, finalStatus);
mStatusTracker->SyncNotifyDifference(diff);
if (mProgressTracker) {
mProgressTracker->SyncNotifyProgress(OnStopRequestProgress(aLastPart,
mError,
finalStatus));
}
return finalStatus;
}
@ -564,11 +564,10 @@ VectorImage::SendInvalidationNotifications()
// we would miss the subsequent invalidations if we didn't send out the
// notifications directly in |InvalidateObservers...|.
if (mStatusTracker) {
if (mProgressTracker) {
SurfaceCache::Discard(this);
ImageStatusDiff diff;
diff.diffState = FLAG_FRAME_STOPPED;
mStatusTracker->SyncNotifyDifference(diff, nsIntRect::GetMaxSizedIntRect());
mProgressTracker->SyncNotifyProgress(FLAG_FRAME_STOPPED,
nsIntRect::GetMaxSizedIntRect());
}
}
@ -822,8 +821,8 @@ VectorImage::Draw(gfxContext* aContext,
return NS_ERROR_FAILURE;
}
if (mAnimationConsumers == 0 && mStatusTracker) {
mStatusTracker->OnUnlockedDraw();
if (mAnimationConsumers == 0 && mProgressTracker) {
mProgressTracker->OnUnlockedDraw();
}
AutoRestore<bool> autoRestoreIsDrawing(mIsDrawing);
@ -1030,10 +1029,9 @@ VectorImage::OnStartRequest(nsIRequest* aRequest, nsISupports* aCtxt)
// Sending StartDecode will block page load until the document's ready. (We
// unblock it by sending StopDecode in OnSVGDocumentLoaded or
// OnSVGDocumentError.)
if (mStatusTracker) {
ImageStatusDiff diff;
diff.diffState |= FLAG_DECODE_STARTED | FLAG_ONLOAD_BLOCKED;
mStatusTracker->SyncNotifyDifference(diff);
if (mProgressTracker) {
mProgressTracker->SyncNotifyProgress(FLAG_DECODE_STARTED |
FLAG_ONLOAD_BLOCKED);
}
// Create a listener to wait until the SVG document is fully loaded, which
@ -1111,11 +1109,12 @@ VectorImage::OnSVGDocumentLoaded()
mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
// Tell *our* observers that we're done loading.
if (mStatusTracker) {
ImageStatusDiff diff;
diff.diffState = FLAG_HAS_SIZE | FLAG_FRAME_STOPPED | FLAG_DECODE_STOPPED |
FLAG_ONLOAD_UNBLOCKED;
mStatusTracker->SyncNotifyDifference(diff, nsIntRect::GetMaxSizedIntRect());
if (mProgressTracker) {
mProgressTracker->SyncNotifyProgress(FLAG_HAS_SIZE |
FLAG_FRAME_STOPPED |
FLAG_DECODE_STOPPED |
FLAG_ONLOAD_UNBLOCKED,
nsIntRect::GetMaxSizedIntRect());
}
EvaluateAnimation();
@ -1131,12 +1130,11 @@ VectorImage::OnSVGDocumentError()
// "broken image" icon. See bug 594505.
mError = true;
if (mStatusTracker) {
if (mProgressTracker) {
// Unblock page load.
ImageStatusDiff diff;
diff.diffState |= FLAG_DECODE_STOPPED | FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR;
mStatusTracker->SyncNotifyDifference(diff);
mProgressTracker->SyncNotifyProgress(FLAG_DECODE_STOPPED |
FLAG_ONLOAD_UNBLOCKED |
FLAG_HAS_ERROR);
}
}

View File

@ -78,7 +78,7 @@ public:
void OnSVGDocumentError();
protected:
explicit VectorImage(imgStatusTracker* aStatusTracker = nullptr,
explicit VectorImage(ProgressTracker* aProgressTracker = nullptr,
ImageURL* aURI = nullptr);
virtual ~VectorImage();
@ -106,8 +106,8 @@ private:
bool mHasPendingInvalidation; // Invalidate observers next refresh
// driver tick.
// Initializes imgStatusTracker and resets it on RasterImage destruction.
nsAutoPtr<imgStatusTrackerInit> mStatusTrackerInit;
// Initializes ProgressTracker and resets it on RasterImage destruction.
nsAutoPtr<ProgressTrackerInit> mProgressTrackerInit;
friend class ImageFactory;
};

View File

@ -9,7 +9,7 @@
#include "imgLoader.h"
#include "imgRequestProxy.h"
#include "imgStatusTracker.h"
#include "ProgressTracker.h"
#include "ImageFactory.h"
#include "Image.h"
#include "RasterImage.h"
@ -62,7 +62,7 @@ NS_IMPL_ISUPPORTS(imgRequest,
imgRequest::imgRequest(imgLoader* aLoader)
: mLoader(aLoader)
, mStatusTracker(new imgStatusTracker(nullptr))
, mProgressTracker(new ProgressTracker(nullptr))
, mValidator(nullptr)
, mInnerWindowId(0)
, mCORSMode(imgIRequest::CORS_NONE)
@ -136,19 +136,19 @@ void imgRequest::ClearLoader() {
mLoader = nullptr;
}
already_AddRefed<imgStatusTracker>
imgRequest::GetStatusTracker()
already_AddRefed<ProgressTracker>
imgRequest::GetProgressTracker()
{
if (mImage && mGotData) {
NS_ABORT_IF_FALSE(!mStatusTracker,
"Should have given mStatusTracker to mImage");
return mImage->GetStatusTracker();
NS_ABORT_IF_FALSE(!mProgressTracker,
"Should have given mProgressTracker to mImage");
return mImage->GetProgressTracker();
} else {
NS_ABORT_IF_FALSE(mStatusTracker,
"Should have mStatusTracker until we create mImage");
nsRefPtr<imgStatusTracker> statusTracker = mStatusTracker;
MOZ_ASSERT(statusTracker);
return statusTracker.forget();
NS_ABORT_IF_FALSE(mProgressTracker,
"Should have mProgressTracker until we create mImage");
nsRefPtr<ProgressTracker> progressTracker = mProgressTracker;
MOZ_ASSERT(progressTracker);
return progressTracker.forget();
}
}
@ -176,15 +176,15 @@ void imgRequest::AddProxy(imgRequestProxy *proxy)
// If we're empty before adding, we have to tell the loader we now have
// proxies.
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
if (statusTracker->ConsumerCount() == 0) {
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (progressTracker->ConsumerCount() == 0) {
NS_ABORT_IF_FALSE(mURI, "Trying to SetHasProxies without key uri.");
if (mLoader) {
mLoader->SetHasProxies(this);
}
}
statusTracker->AddConsumer(proxy);
progressTracker->AddConsumer(proxy);
}
nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
@ -200,11 +200,11 @@ nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
// below, because Cancel() may result in OnStopRequest being called back
// before Cancel() returns, leaving the image in a different state then the
// one it was in at this point.
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
if (!statusTracker->RemoveConsumer(proxy, aStatus))
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (!progressTracker->RemoveConsumer(proxy, aStatus))
return NS_OK;
if (statusTracker->ConsumerCount() == 0) {
if (progressTracker->ConsumerCount() == 0) {
// If we have no observers, there's nothing holding us alive. If we haven't
// been cancelled and thus removed from the cache, tell the image loader so
// we can be evicted from the cache.
@ -228,7 +228,7 @@ nsresult imgRequest::RemoveProxy(imgRequestProxy *proxy, nsresult aStatus)
This way, if a proxy is destroyed without calling cancel on it, it won't leak
and won't leave a bad pointer in the observer list.
*/
if (statusTracker->IsLoading() && NS_FAILED(aStatus)) {
if (progressTracker->IsLoading() && NS_FAILED(aStatus)) {
LOG_MSG(GetImgLog(), "imgRequest::RemoveProxy", "load in progress. canceling");
this->Cancel(NS_BINDING_ABORTED);
@ -299,16 +299,12 @@ void imgRequest::ContinueCancel(nsresult aStatus)
{
MOZ_ASSERT(NS_IsMainThread());
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
ImageStatusDiff diff;
diff.diffState |= FLAG_HAS_ERROR | FLAG_ONLOAD_UNBLOCKED;
statusTracker->SyncNotifyDifference(diff);
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
progressTracker->SyncNotifyProgress(FLAG_HAS_ERROR | FLAG_ONLOAD_UNBLOCKED);
RemoveFromCache();
if (mRequest && statusTracker->IsLoading()) {
if (mRequest && progressTracker->IsLoading()) {
mRequest->Cancel(aStatus);
}
}
@ -417,8 +413,8 @@ void imgRequest::RemoveFromCache()
bool imgRequest::HasConsumers()
{
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
return statusTracker && statusTracker->ConsumerCount() > 0;
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
return progressTracker && progressTracker->ConsumerCount() > 0;
}
int32_t imgRequest::Priority() const
@ -439,8 +435,8 @@ void imgRequest::AdjustPriority(imgRequestProxy *proxy, int32_t delta)
// concern though is that image loads remain lower priority than other pieces
// of content such as link clicks, CSS, and JS.
//
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
if (!statusTracker->FirstConsumerIs(proxy))
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (!progressTracker->FirstConsumerIs(proxy))
return;
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
@ -634,10 +630,10 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
// Figure out if we're multipart
nsCOMPtr<nsIMultiPartChannel> mpchan(do_QueryInterface(aRequest));
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (mpchan) {
mIsMultiPartChannel = true;
statusTracker->SetIsMultipart();
progressTracker->SetIsMultipart();
} else {
NS_ABORT_IF_FALSE(!mIsMultiPartChannel, "Something went wrong");
}
@ -674,13 +670,10 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
mRequest = chan;
}
// Note: refreshing statusTracker in case OnNewSourceData changed it.
statusTracker = GetStatusTracker();
statusTracker->ResetForNewRequest();
ImageStatusDiff diff;
diff.diffState |= FLAG_REQUEST_STARTED;
statusTracker->SyncNotifyDifference(diff);
// Note: refreshing progressTracker in case OnNewSourceData changed it.
progressTracker = GetProgressTracker();
progressTracker->ResetForNewRequest();
progressTracker->SyncNotifyProgress(FLAG_REQUEST_STARTED);
nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
if (channel)
@ -704,7 +697,7 @@ NS_IMETHODIMP imgRequest::OnStartRequest(nsIRequest *aRequest, nsISupports *ctxt
mApplicationCache = GetApplicationCache(aRequest);
// Shouldn't we be dead already if this gets hit? Probably multipart/x-mixed-replace...
if (statusTracker->ConsumerCount() == 0) {
if (progressTracker->ConsumerCount() == 0) {
this->Cancel(NS_IMAGELIB_ERROR_FAILURE);
}
@ -797,13 +790,13 @@ NS_IMETHODIMP imgRequest::OnStopRequest(nsIRequest *aRequest, nsISupports *ctxt,
}
if (!mImage) {
// We have to fire imgStatusTracker::OnStopRequest ourselves because there's
// We have to fire the OnStopRequest notifications ourselves because there's
// no image capable of doing so.
ImageStatusDiff diff =
ImageStatusDiff::ForOnStopRequest(lastPart, /* aError = */ false, status);
Progress progress =
OnStopRequestProgress(lastPart, /* aError = */ false, status);
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
statusTracker->SyncNotifyDifference(diff);
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
progressTracker->SyncNotifyProgress(progress);
}
mTimedChannel = nullptr;
@ -899,10 +892,10 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
if (resniffMimeType) {
NS_ABORT_IF_FALSE(mIsMultiPartChannel, "Resniffing a non-multipart image");
nsRefPtr<imgStatusTracker> freshTracker = new imgStatusTracker(nullptr);
nsRefPtr<imgStatusTracker> oldStatusTracker = GetStatusTracker();
freshTracker->AdoptConsumers(oldStatusTracker);
mStatusTracker = freshTracker.forget();
nsRefPtr<ProgressTracker> freshTracker = new ProgressTracker(nullptr);
nsRefPtr<ProgressTracker> oldProgressTracker = GetProgressTracker();
freshTracker->AdoptConsumers(oldProgressTracker);
mProgressTracker = freshTracker.forget();
}
SetProperties(chan);
@ -915,16 +908,16 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
// Now we can create a new image to hold the data. If we don't have a decoder
// for this mimetype we'll find out about it here.
mImage = ImageFactory::CreateImage(aRequest, mStatusTracker, mContentType,
mImage = ImageFactory::CreateImage(aRequest, mProgressTracker, mContentType,
mURI, mIsMultiPartChannel,
static_cast<uint32_t>(mInnerWindowId));
// Release our copy of the status tracker since the image owns it now.
mStatusTracker = nullptr;
mProgressTracker = nullptr;
// Notify listeners that we have an image.
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
statusTracker->OnImageAvailable();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
progressTracker->OnImageAvailable();
if (mImage->HasError() && !mIsMultiPartChannel) { // Probably bad mimetype
// We allow multipart images to fail to initialize without cancelling the
@ -934,7 +927,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
return NS_BINDING_ABORTED;
}
NS_ABORT_IF_FALSE(statusTracker->HasImage(), "Status tracker should have an image!");
NS_ABORT_IF_FALSE(progressTracker->HasImage(), "Status tracker should have an image!");
NS_ABORT_IF_FALSE(mImage, "imgRequest should have an image!");
if (mDecodeRequested)

View File

@ -21,7 +21,6 @@
#include "nsIAsyncVerifyRedirectCallback.h"
class imgCacheValidator;
class imgStatusTracker;
class imgLoader;
class imgRequestProxy;
class imgCacheEntry;
@ -37,6 +36,7 @@ namespace mozilla {
namespace image {
class Image;
class ImageURL;
class ProgressTracker;
} // namespace image
} // namespace mozilla
@ -49,7 +49,10 @@ class imgRequest MOZ_FINAL : public nsIStreamListener,
virtual ~imgRequest();
public:
typedef mozilla::image::Image Image;
typedef mozilla::image::ImageURL ImageURL;
typedef mozilla::image::ProgressTracker ProgressTracker;
explicit imgRequest(imgLoader* aLoader);
NS_DECL_THREADSAFE_ISUPPORTS
@ -121,10 +124,10 @@ public:
return principal.forget();
}
// Return the imgStatusTracker associated with this imgRequest. It may live
// in |mStatusTracker| or in |mImage.mStatusTracker|, depending on whether
// Return the ProgressTracker associated with this imgRequest. It may live
// in |mProgressTracker| or in |mImage.mProgressTracker|, depending on whether
// mImage has been instantiated yet.
already_AddRefed<imgStatusTracker> GetStatusTracker();
already_AddRefed<ProgressTracker> GetProgressTracker();
// Get the current principal of the image. No AddRefing.
inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
@ -146,9 +149,9 @@ private:
friend class imgRequestProxy;
friend class imgLoader;
friend class imgCacheValidator;
friend class imgStatusTracker;
friend class imgCacheExpirationTracker;
friend class imgRequestNotifyRunnable;
friend class mozilla::image::ProgressTracker;
inline void SetLoadId(void *aLoadId) {
mLoadId = aLoadId;
@ -222,9 +225,9 @@ private:
nsCOMPtr<nsIPrincipal> mLoadingPrincipal;
// The principal of this image.
nsCOMPtr<nsIPrincipal> mPrincipal;
// Status-tracker -- transferred to mImage, when it gets instantiated
nsRefPtr<imgStatusTracker> mStatusTracker;
nsRefPtr<mozilla::image::Image> mImage;
// Progress tracker -- transferred to mImage, when it gets instantiated.
nsRefPtr<ProgressTracker> mProgressTracker;
nsRefPtr<Image> mImage;
nsCOMPtr<nsIProperties> mProperties;
nsCOMPtr<nsISupports> mSecurityInfo;
nsCOMPtr<nsIChannel> mChannel;

View File

@ -28,7 +28,7 @@ class ProxyBehaviour
virtual already_AddRefed<mozilla::image::Image> GetImage() const = 0;
virtual bool HasImage() const = 0;
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() const = 0;
virtual already_AddRefed<ProgressTracker> GetProgressTracker() const = 0;
virtual imgRequest* GetOwner() const = 0;
virtual void SetOwner(imgRequest* aOwner) = 0;
};
@ -40,7 +40,7 @@ class RequestBehaviour : public ProxyBehaviour
virtual already_AddRefed<mozilla::image::Image> GetImage() const MOZ_OVERRIDE;
virtual bool HasImage() const MOZ_OVERRIDE;
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() const MOZ_OVERRIDE;
virtual already_AddRefed<ProgressTracker> GetProgressTracker() const MOZ_OVERRIDE;
virtual imgRequest* GetOwner() const MOZ_OVERRIDE {
return mOwner;
@ -50,8 +50,8 @@ class RequestBehaviour : public ProxyBehaviour
mOwner = aOwner;
if (mOwner) {
nsRefPtr<imgStatusTracker> ownerStatusTracker = GetStatusTracker();
mOwnerHasImage = ownerStatusTracker && ownerStatusTracker->HasImage();
nsRefPtr<ProgressTracker> ownerProgressTracker = GetProgressTracker();
mOwnerHasImage = ownerProgressTracker && ownerProgressTracker->HasImage();
} else {
mOwnerHasImage = false;
}
@ -74,20 +74,20 @@ RequestBehaviour::GetImage() const
{
if (!mOwnerHasImage)
return nullptr;
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
return statusTracker->GetImage();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
return progressTracker->GetImage();
}
already_AddRefed<imgStatusTracker>
RequestBehaviour::GetStatusTracker() const
already_AddRefed<ProgressTracker>
RequestBehaviour::GetProgressTracker() const
{
// NOTE: It's possible that our mOwner has an Image that it didn't notify
// us about, if we were Canceled before its Image was constructed.
// (Canceling removes us as an observer, so mOwner has no way to notify us).
// That's why this method uses mOwner->GetStatusTracker() instead of just
// mOwner->mStatusTracker -- we might have a null mImage and yet have an
// mOwner with a non-null mImage (and a null mStatusTracker pointer).
return mOwner->GetStatusTracker();
// That's why this method uses mOwner->GetProgressTracker() instead of just
// mOwner->mProgressTracker -- we might have a null mImage and yet have an
// mOwner with a non-null mImage (and a null mProgressTracker pointer).
return mOwner->GetProgressTracker();
}
NS_IMPL_ADDREF(imgRequestProxy)
@ -201,9 +201,9 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
// Were we decoded before?
bool wasDecoded = false;
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
if (statusTracker->HasImage() &&
statusTracker->GetImageStatus() & imgIRequest::STATUS_FRAME_COMPLETE) {
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (progressTracker->HasImage() &&
progressTracker->GetImageStatus() & imgIRequest::STATUS_FRAME_COMPLETE) {
wasDecoded = true;
}
@ -511,8 +511,8 @@ NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer **aImage)
/* readonly attribute unsigned long imageStatus; */
NS_IMETHODIMP imgRequestProxy::GetImageStatus(uint32_t *aStatus)
{
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
*aStatus = statusTracker->GetImageStatus();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
*aStatus = progressTracker->GetImageStatus();
return NS_OK;
}
@ -729,7 +729,7 @@ void imgRequestProxy::OnStartDecode()
// In the case of streaming jpegs, it is possible to get multiple
// OnStartDecodes which indicates the beginning of a new decode. The cache
// entry's size therefore needs to be reset to 0 here. If we do not do
// this, the code in imgStatusTrackerObserver::OnStopFrame will continue to
// this, the code in ProgressTrackerObserver::OnStopFrame will continue to
// increase the data size cumulatively.
GetOwner()->ResetCacheEntry();
}
@ -973,16 +973,16 @@ void imgRequestProxy::NotifyListener()
// processing when we receive notifications (like OnStopRequest()), and we
// need to check mCanceled everywhere too.
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
if (GetOwner()) {
// Send the notifications to our listener asynchronously.
statusTracker->Notify(this);
progressTracker->Notify(this);
} else {
// We don't have an imgRequest, so we can only notify the clone of our
// current state, but we still have to do that asynchronously.
NS_ABORT_IF_FALSE(HasImage(),
"if we have no imgRequest, we should have an Image");
statusTracker->NotifyCurrentState(this);
progressTracker->NotifyCurrentState(this);
}
}
@ -993,16 +993,16 @@ void imgRequestProxy::SyncNotifyListener()
// processing when we receive notifications (like OnStopRequest()), and we
// need to check mCanceled everywhere too.
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
statusTracker->SyncNotify(this);
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
progressTracker->SyncNotify(this);
}
void
imgRequestProxy::SetHasImage()
{
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
MOZ_ASSERT(statusTracker);
nsRefPtr<Image> image = statusTracker->GetImage();
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
MOZ_ASSERT(progressTracker);
nsRefPtr<Image> image = progressTracker->GetImage();
MOZ_ASSERT(image);
// Force any private status related to the owner to reflect
@ -1018,10 +1018,10 @@ imgRequestProxy::SetHasImage()
image->IncrementAnimationConsumers();
}
already_AddRefed<imgStatusTracker>
imgRequestProxy::GetStatusTracker() const
already_AddRefed<ProgressTracker>
imgRequestProxy::GetProgressTracker() const
{
return mBehaviour->GetStatusTracker();
return mBehaviour->GetProgressTracker();
}
already_AddRefed<mozilla::image::Image>
@ -1035,8 +1035,8 @@ RequestBehaviour::HasImage() const
{
if (!mOwnerHasImage)
return false;
nsRefPtr<imgStatusTracker> statusTracker = GetStatusTracker();
return statusTracker ? statusTracker->HasImage() : false;
nsRefPtr<ProgressTracker> progressTracker = GetProgressTracker();
return progressTracker ? progressTracker->HasImage() : false;
}
bool
@ -1068,8 +1068,8 @@ public:
return mImage;
}
virtual already_AddRefed<imgStatusTracker> GetStatusTracker() const MOZ_OVERRIDE {
return mImage->GetStatusTracker();
virtual already_AddRefed<ProgressTracker> GetProgressTracker() const MOZ_OVERRIDE {
return mImage->GetProgressTracker();
}
virtual imgRequest* GetOwner() const MOZ_OVERRIDE {

View File

@ -39,6 +39,7 @@ namespace mozilla {
namespace image {
class Image;
class ImageURL;
class ProgressTracker;
} // namespace image
} // namespace mozilla
@ -52,8 +53,11 @@ protected:
virtual ~imgRequestProxy();
public:
MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
typedef mozilla::image::Image Image;
typedef mozilla::image::ImageURL ImageURL;
typedef mozilla::image::ProgressTracker ProgressTracker;
MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
NS_DECL_ISUPPORTS
NS_DECL_IMGIREQUEST
NS_DECL_NSIREQUEST
@ -91,7 +95,7 @@ public:
// asynchronously-called function.
void SyncNotifyListener();
// Whether we want notifications from imgStatusTracker to be deferred until
// Whether we want notifications from ProgressTracker to be deferred until
// an event it has scheduled has been fired.
bool NotificationsDeferred() const
{
@ -117,7 +121,7 @@ public:
nsresult GetURI(ImageURL **aURI);
protected:
friend class imgStatusTracker;
friend class mozilla::image::ProgressTracker;
friend class imgStatusNotifyRunnable;
friend class imgRequestNotifyRunnable;
@ -142,7 +146,7 @@ protected:
};
// The following notification functions are protected to ensure that (friend
// class) imgStatusTracker is the only class allowed to send us
// class) ProgressTracker is the only class allowed to send us
// notifications.
void OnStartDecode ();
@ -172,11 +176,11 @@ protected:
RemoveFromLoadGroup(true);
}
// Return the imgStatusTracker associated with mOwner and/or mImage. It may
// Return the ProgressTracker associated with mOwner and/or mImage. It may
// live either on mOwner or mImage, depending on whether
// (a) we have an mOwner at all
// (b) whether mOwner has instantiated its image yet
already_AddRefed<imgStatusTracker> GetStatusTracker() const;
already_AddRefed<ProgressTracker> GetProgressTracker() const;
nsITimedChannel* TimedChannel()
{
@ -185,7 +189,7 @@ protected:
return GetOwner()->mTimedChannel;
}
already_AddRefed<mozilla::image::Image> GetImage() const;
already_AddRefed<Image> GetImage() const;
bool HasImage() const;
imgRequest* GetOwner() const;
@ -235,8 +239,7 @@ class imgRequestProxyStatic : public imgRequestProxy
{
public:
imgRequestProxyStatic(mozilla::image::Image* aImage,
nsIPrincipal* aPrincipal);
imgRequestProxyStatic(Image* aImage, nsIPrincipal* aPrincipal);
NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) MOZ_OVERRIDE;

View File

@ -43,7 +43,7 @@ SOURCES += [
'imgLoader.cpp',
'imgRequest.cpp',
'imgRequestProxy.cpp',
'imgStatusTracker.cpp',
'ProgressTracker.cpp',
'RasterImage.cpp',
]