mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
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:
parent
32255b73d9
commit
03cc795af0
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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,7 +176,7 @@ Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent)
|
||||
}
|
||||
PostDecodeDone();
|
||||
} else {
|
||||
mDiff.diffState |= FLAG_DECODE_STOPPED | FLAG_ONLOAD_UNBLOCKED |
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -12,13 +12,13 @@
|
||||
|
||||
class nsCString;
|
||||
class nsIRequest;
|
||||
class imgStatusTracker;
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
class Image;
|
||||
class ImageURL;
|
||||
class ProgressTracker;
|
||||
|
||||
class ImageFactory
|
||||
{
|
||||
@ -41,14 +41,14 @@ public:
|
||||
* 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 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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
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;
|
||||
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,
|
||||
ProgressTracker::SyncNotifyInternal(ProxyArray& aProxies,
|
||||
bool aHasImage,
|
||||
uint32_t aState,
|
||||
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,
|
||||
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,11 +342,11 @@ imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
|
||||
|
||||
ProxyArray array;
|
||||
array.AppendElement(proxy);
|
||||
SyncNotifyState(array, !!mImage, mState, r);
|
||||
SyncNotifyInternal(array, !!mImage, mProgress, r);
|
||||
}
|
||||
|
||||
void
|
||||
imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
|
||||
ProgressTracker::EmulateRequestFinished(imgRequestProxy* aProxy,
|
||||
nsresult aStatus)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(),
|
||||
@ -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
|
@ -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
|
||||
{
|
||||
ImageStatusDiff()
|
||||
: diffState(0)
|
||||
{ }
|
||||
typedef uint32_t Progress;
|
||||
|
||||
static ImageStatusDiff NoChange() { return ImageStatusDiff(); }
|
||||
bool IsNoChange() const { return *this == NoChange(); }
|
||||
const uint32_t NoProgress = 0;
|
||||
|
||||
static ImageStatusDiff ForOnStopRequest(bool aLastPart,
|
||||
inline Progress OnStopRequestProgress(bool aLastPart,
|
||||
bool aError,
|
||||
nsresult aStatus)
|
||||
{
|
||||
ImageStatusDiff diff;
|
||||
diff.diffState |= FLAG_REQUEST_STOPPED;
|
||||
Progress progress = FLAG_REQUEST_STOPPED;
|
||||
if (aLastPart) {
|
||||
diff.diffState |= FLAG_MULTIPART_STOPPED;
|
||||
progress |= FLAG_MULTIPART_STOPPED;
|
||||
}
|
||||
if (NS_FAILED(aStatus) || aError) {
|
||||
diff.diffState |= FLAG_HAS_ERROR;
|
||||
progress |= FLAG_HAS_ERROR;
|
||||
}
|
||||
return diff;
|
||||
return progress;
|
||||
}
|
||||
|
||||
bool operator!=(const ImageStatusDiff& aOther) const { return !(*this == aOther); }
|
||||
bool operator==(const ImageStatusDiff& aOther) const {
|
||||
return aOther.diffState == diffState;
|
||||
}
|
||||
|
||||
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,
|
||||
// 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,
|
||||
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
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -43,7 +43,7 @@ SOURCES += [
|
||||
'imgLoader.cpp',
|
||||
'imgRequest.cpp',
|
||||
'imgRequestProxy.cpp',
|
||||
'imgStatusTracker.cpp',
|
||||
'ProgressTracker.cpp',
|
||||
'RasterImage.cpp',
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user