Bug 716140 - Convert the XPCOM imgIDecoderObserver interface into a private C++ interface, imgDecoderObserver, so we can more easily make changes to it. r=jrmuizel

This commit is contained in:
Joe Drew 2012-12-18 11:37:15 -05:00
parent 9269bc2fed
commit ca3f4c5e2b
34 changed files with 257 additions and 314 deletions

View File

@ -111,7 +111,7 @@ interface nsIImageLoadingContent : imgINotificationObserver
/**
* Used to find out what type of request one is dealing with (eg
* which request got passed through to the imgIDecoderObserver
* which request got passed through to the imgINotificationObserver
* interface of an observer)
*
* @param aRequest the request whose type we want to know

View File

@ -34,7 +34,7 @@ GetBMPLog()
#define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1))
#define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col)
nsBMPDecoder::nsBMPDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsBMPDecoder::nsBMPDecoder(RasterImage &aImage, imgDecoderObserver* aObserver)
: Decoder(aImage, aObserver)
{
mColors = nullptr;

View File

@ -8,7 +8,7 @@
#define _nsBMPDecoder_h
#include "nsAutoPtr.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "gfxColor.h"
#include "Decoder.h"
#include "BMPFileHeaders.h"
@ -25,7 +25,7 @@ class nsBMPDecoder : public Decoder
{
public:
nsBMPDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsBMPDecoder(RasterImage &aImage, imgDecoderObserver* aObserver);
~nsBMPDecoder();
// Specifies whether or not the BMP file will contain alpha data

View File

@ -71,7 +71,7 @@ namespace image {
//////////////////////////////////////////////////////////////////////
// GIF Decoder Implementation
nsGIFDecoder2::nsGIFDecoder2(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsGIFDecoder2::nsGIFDecoder2(RasterImage &aImage, imgDecoderObserver* aObserver)
: Decoder(aImage, aObserver)
, mCurrentRow(-1)
, mLastFlushedRow(-1)

View File

@ -9,7 +9,7 @@
#include "nsCOMPtr.h"
#include "Decoder.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "GIF2.h"
@ -24,7 +24,7 @@ class nsGIFDecoder2 : public Decoder
{
public:
nsGIFDecoder2(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsGIFDecoder2(RasterImage &aImage, imgDecoderObserver* aObserver);
~nsGIFDecoder2();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount);

View File

@ -62,7 +62,7 @@ nsICODecoder::GetNumColors()
}
nsICODecoder::nsICODecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsICODecoder::nsICODecoder(RasterImage &aImage, imgDecoderObserver* aObserver)
: Decoder(aImage, aObserver)
{
mPos = mImageOffset = mCurrIcon = mNumIcons = mBPP = mRowBytes = 0;

View File

@ -9,7 +9,7 @@
#include "nsAutoPtr.h"
#include "Decoder.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "nsBMPDecoder.h"
#include "nsPNGDecoder.h"
#include "ICOFileHeaders.h"
@ -23,7 +23,7 @@ class nsICODecoder : public Decoder
{
public:
nsICODecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsICODecoder(RasterImage &aImage, imgDecoderObserver* aObserver);
virtual ~nsICODecoder();
// Obtains the width of the icon directory entry

View File

@ -15,7 +15,7 @@
namespace mozilla {
namespace image {
nsIconDecoder::nsIconDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsIconDecoder::nsIconDecoder(RasterImage &aImage, imgDecoderObserver* aObserver)
: Decoder(aImage, aObserver),
mWidth(-1),
mHeight(-1),

View File

@ -11,7 +11,7 @@
#include "nsCOMPtr.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
namespace mozilla {
namespace image {
@ -40,7 +40,7 @@ class nsIconDecoder : public Decoder
{
public:
nsIconDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsIconDecoder(RasterImage &aImage, imgDecoderObserver* aObserver);
virtual ~nsIconDecoder();
virtual void WriteInternal(const char* aBuffer, uint32_t aCount);

View File

@ -80,7 +80,7 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo);
#define MAX_JPEG_MARKER_LENGTH (((uint32_t)1 << 16) - 1)
nsJPEGDecoder::nsJPEGDecoder(RasterImage& aImage, imgIDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle)
nsJPEGDecoder::nsJPEGDecoder(RasterImage& aImage, imgDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle)
: Decoder(aImage, aObserver)
, mDecodeStyle(aDecodeStyle)
{

View File

@ -17,7 +17,7 @@
#include "nsAutoPtr.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "nsIInputStream.h"
#include "nsIPipe.h"
#include "qcms.h"
@ -52,7 +52,7 @@ class RasterImage;
class nsJPEGDecoder : public Decoder
{
public:
nsJPEGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle);
nsJPEGDecoder(RasterImage &aImage, imgDecoderObserver* aObserver, Decoder::DecodeStyle aDecodeStyle);
virtual ~nsJPEGDecoder();
virtual void InitInternal();

View File

@ -57,7 +57,7 @@ GetPNGDecoderAccountingLog()
const uint8_t
nsPNGDecoder::pngSignatureBytes[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
nsPNGDecoder::nsPNGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
nsPNGDecoder::nsPNGDecoder(RasterImage &aImage, imgDecoderObserver* aObserver)
: Decoder(aImage, aObserver),
mPNG(nullptr), mInfo(nullptr),
mCMSLine(nullptr), interlacebuf(nullptr),

View File

@ -9,7 +9,7 @@
#include "Decoder.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "gfxASurface.h"
#include "nsCOMPtr.h"
@ -25,7 +25,7 @@ class RasterImage;
class nsPNGDecoder : public Decoder
{
public:
nsPNGDecoder(RasterImage &aImage, imgIDecoderObserver* aObserver);
nsPNGDecoder(RasterImage &aImage, imgDecoderObserver* aObserver);
virtual ~nsPNGDecoder();
virtual void InitInternal();

View File

@ -19,7 +19,6 @@ XPIDLSRCS = \
imgICache.idl \
imgIContainer.idl \
imgIContainerDebug.idl \
imgIDecoderObserver.idl \
imgIEncoder.idl \
imgILoader.idl \
imgINotificationObserver.idl \

View File

@ -6,8 +6,6 @@
#include "nsISupports.idl"
interface imgIDecoderObserver;
%{C++
#include "gfxImageSurface.h"
#include "gfxContext.h"

View File

@ -12,7 +12,7 @@
namespace mozilla {
namespace image {
Decoder::Decoder(RasterImage &aImage, imgIDecoderObserver* aObserver)
Decoder::Decoder(RasterImage &aImage, imgDecoderObserver* aObserver)
: mImage(aImage)
, mObserver(aObserver)
, mDecodeFlags(0)

View File

@ -7,8 +7,8 @@
#define MOZILLA_IMAGELIB_DECODER_H_
#include "RasterImage.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "mozilla/RefPtr.h"
namespace mozilla {
namespace image {
@ -17,7 +17,7 @@ class Decoder
{
public:
Decoder(RasterImage& aImage, imgIDecoderObserver* aObserver);
Decoder(RasterImage& aImage, imgDecoderObserver* aObserver);
virtual ~Decoder();
/**
@ -175,7 +175,7 @@ protected:
*
*/
RasterImage &mImage;
nsCOMPtr<imgIDecoderObserver> mObserver;
RefPtr<imgDecoderObserver> mObserver;
uint32_t mDecodeFlags;
bool mDecodeDone;

View File

@ -47,7 +47,7 @@ public:
* @param aMimeType The mimetype of the image.
* @param aFlags Initialization flags of the INIT_FLAG_* variety.
*/
virtual nsresult Init(imgIDecoderObserver* aObserver,
virtual nsresult Init(imgDecoderObserver* aObserver,
const char* aMimeType,
const char* aURIString,
uint32_t aFlags) = 0;

View File

@ -6,10 +6,9 @@
#include "base/histogram.h"
#include "ImageLogging.h"
#include "nsComponentManagerUtils.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "nsError.h"
#include "Decoder.h"
#include "imgIDecoderObserver.h"
#include "RasterImage.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
@ -358,7 +357,6 @@ RasterImage::RasterImage(imgStatusTracker* aStatusTracker) :
mFrameDecodeFlags(DECODE_FLAGS_DEFAULT),
mAnim(nullptr),
mLoopCount(-1),
mObserver(nullptr),
mLockCount(0),
mDecoder(nullptr),
mDecodeRequest(this),
@ -439,7 +437,7 @@ RasterImage::Initialize()
}
nsresult
RasterImage::Init(imgIDecoderObserver *aObserver,
RasterImage::Init(imgDecoderObserver *aObserver,
const char* aMimeType,
const char* aURIString,
uint32_t aFlags)
@ -462,7 +460,9 @@ RasterImage::Init(imgIDecoderObserver *aObserver,
"Can't be discardable or decode-on-draw for multipart");
// Store initialization data
mObserver = do_GetWeakReference(aObserver);
if (aObserver) {
mObserver = aObserver->asWeakPtr();
}
mSourceDataMimeType.Assign(aMimeType);
mURIString.Assign(aURIString);
mDiscardable = !!(aFlags & INIT_FLAG_DISCARDABLE);
@ -638,9 +638,7 @@ RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
}
if (frameAdvanced) {
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
if (!observer) {
if (!mObserver) {
NS_ERROR("Refreshing image after its imgRequest is gone");
StopAnimation();
return;
@ -654,7 +652,7 @@ RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
#endif
UpdateImageContainer();
observer->FrameChanged(&dirtyRect);
mObserver->FrameChanged(&dirtyRect);
}
}
@ -1660,9 +1658,8 @@ RasterImage::ResetAnimation()
// we fix bug 500402.
// Update display if we were animating before
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
if (mAnimating && observer)
observer->FrameChanged(&(mAnim->firstFrameRefreshArea));
if (mAnimating && mObserver)
mObserver->FrameChanged(&(mAnim->firstFrameRefreshArea));
if (ShouldAnimate()) {
StartAnimation();
@ -2468,9 +2465,8 @@ RasterImage::Discard(bool force)
mDecoded = false;
// Notify that we discarded
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
if (observer)
observer->OnDiscard();
if (mObserver)
mObserver->OnDiscard();
if (force)
DiscardTracker::Remove(&mDiscardTrackerNode);
@ -2540,30 +2536,29 @@ RasterImage::InitDecoder(bool aDoSizeDecode)
eDecoderType type = GetDecoderType(mSourceDataMimeType.get());
CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER);
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
// Instantiate the appropriate decoder
switch (type) {
case eDecoderType_png:
mDecoder = new nsPNGDecoder(*this, observer);
mDecoder = new nsPNGDecoder(*this, mObserver);
break;
case eDecoderType_gif:
mDecoder = new nsGIFDecoder2(*this, observer);
mDecoder = new nsGIFDecoder2(*this, mObserver);
break;
case eDecoderType_jpeg:
// If we have all the data we don't want to waste cpu time doing
// a progressive decode
mDecoder = new nsJPEGDecoder(*this, observer,
mDecoder = new nsJPEGDecoder(*this, mObserver,
mHasBeenDecoded ? Decoder::SEQUENTIAL :
Decoder::PROGRESSIVE);
break;
case eDecoderType_bmp:
mDecoder = new nsBMPDecoder(*this, observer);
mDecoder = new nsBMPDecoder(*this, mObserver);
break;
case eDecoderType_ico:
mDecoder = new nsICODecoder(*this, observer);
mDecoder = new nsICODecoder(*this, mObserver);
break;
case eDecoderType_icon:
mDecoder = new nsIconDecoder(*this, observer);
mDecoder = new nsIconDecoder(*this, mObserver);
break;
default:
NS_ABORT_IF_FALSE(0, "Shouldn't get here!");
@ -2912,7 +2907,7 @@ RasterImage::ScalingDone(ScaleRequest* request, ScaleStatus status)
if (status == SCALE_DONE) {
MOZ_ASSERT(request->done);
nsCOMPtr<imgIDecoderObserver> observer(do_QueryReferent(mObserver));
RefPtr<imgDecoderObserver> observer(mObserver);
if (observer) {
imgFrame *scaledFrame = request->dstFrame.get();
scaledFrame->ImageUpdated(scaledFrame->GetRect());

View File

@ -24,7 +24,6 @@
#include "nsIProperties.h"
#include "nsITimer.h"
#include "nsIRequest.h"
#include "nsWeakReference.h"
#include "nsTArray.h"
#include "imgFrame.h"
#include "nsThreadUtils.h"
@ -39,7 +38,6 @@
#include "imgIContainerDebug.h"
#endif
class imgIDecoder;
class nsIInputStream;
#define NS_RASTERIMAGE_CID \
@ -159,7 +157,7 @@ public:
virtual nsresult StopAnimation();
// Methods inherited from Image
nsresult Init(imgIDecoderObserver* aObserver,
nsresult Init(imgDecoderObserver* aObserver,
const char* aMimeType,
const char* aURIString,
uint32_t aFlags);
@ -641,8 +639,7 @@ private: // data
//! # loops remaining before animation stops (-1 no stop)
int32_t mLoopCount;
//! imgIDecoderObserver
nsWeakPtr mObserver;
mozilla::WeakPtr<imgDecoderObserver> mObserver;
// Discard members
uint32_t mLockCount;

View File

@ -5,7 +5,7 @@
#include "VectorImage.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "SVGDocumentWrapper.h"
#include "gfxContext.h"
#include "gfxPlatform.h"
@ -188,7 +188,7 @@ VectorImage::~VectorImage()
// Methods inherited from Image.h
nsresult
VectorImage::Init(imgIDecoderObserver* aObserver,
VectorImage::Init(imgDecoderObserver* aObserver,
const char* aMimeType,
const char* aURIString,
uint32_t aFlags)
@ -201,7 +201,9 @@ VectorImage::Init(imgIDecoderObserver* aObserver,
!mHaveRestrictedRegion && !mError,
"Flags unexpectedly set before initialization");
mObserver = do_GetWeakReference(aObserver);
if (aObserver) {
mObserver = aObserver->asWeakPtr();
}
NS_ABORT_IF_FALSE(!strcmp(aMimeType, SVG_MIMETYPE), "Unexpected mimetype");
mIsInitialized = true;
@ -709,7 +711,7 @@ VectorImage::OnStopRequest(nsIRequest* aRequest, nsISupports* aCtxt,
mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
// Tell *our* observers that we're done loading
nsCOMPtr<imgIDecoderObserver> observer = do_QueryReferent(mObserver);
RefPtr<imgDecoderObserver> observer(mObserver);
if (observer) {
// NOTE: This signals that width/height are available.
observer->OnStartContainer();
@ -748,13 +750,10 @@ VectorImage::OnDataAvailable(nsIRequest* aRequest, nsISupports* aCtxt,
void
VectorImage::InvalidateObserver()
{
if (!mObserver)
return;
nsCOMPtr<imgIDecoderObserver> obs(do_QueryReferent(mObserver));
if (obs) {
obs->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
obs->OnStopFrame();
RefPtr<imgDecoderObserver> observer(mObserver);
if (observer) {
observer->FrameChanged(&nsIntRect::GetMaxSizedIntRect());
observer->OnStopFrame();
}
}

View File

@ -9,10 +9,10 @@
#include "Image.h"
#include "nsIStreamListener.h"
#include "nsIRequest.h"
#include "nsWeakReference.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/WeakPtr.h"
class imgIDecoderObserver;
class imgDecoderObserver;
namespace mozilla {
namespace layers {
@ -37,7 +37,7 @@ public:
virtual ~VectorImage();
// Methods inherited from Image
nsresult Init(imgIDecoderObserver* aObserver,
nsresult Init(imgDecoderObserver* aObserver,
const char* aMimeType,
const char* aURIString,
uint32_t aFlags);
@ -69,7 +69,7 @@ protected:
virtual bool ShouldAnimate();
private:
nsWeakPtr mObserver; //! imgIDecoderObserver
WeakPtr<imgDecoderObserver> mObserver;
nsRefPtr<SVGDocumentWrapper> mSVGDocumentWrapper;
nsRefPtr<SVGRootRenderingObserver> mRenderingObserver;

View File

@ -1,30 +1,26 @@
/** -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
#include "nsISupports.idl"
#ifndef MOZILLA_IMAGELIB_IMGDECODEROBSERVER_H_
#define MOZILLA_IMAGELIB_IMGDECODEROBSERVER_H_
%{C++
#include "nsRect.h"
%}
[ptr] native nsIntRect(nsIntRect);
#include "mozilla/RefPtr.h"
#include "mozilla/WeakPtr.h"
/**
* imgIDecoderObserver interface
* imgDecoderObserver interface
*
* This interface is used both for observing imgIDecoder objects and for
* observing imgIRequest objects. In the former case, aRequest is
* always null.
* This interface is used to observe Decoder objects.
*
* We make the distinction here between "load" and "decode" notifications. Load
* notifications are fired as the image is loaded from the network or
* filesystem. Decode notifications are fired as the image is decoded. If an
* image is decoded on load and not visibly discarded, decode notifications are
* nested logically inside load notifications as one might expect. However, with
* decode-on-draw, the set of decode notifications can imgRcome completely _after_
* decode-on-draw, the set of decode notifications can come completely _after_
* the load notifications, and can come multiple times if the image is
* discardable. Moreover, they can be interleaved in various ways. In general,
* any presumed ordering between load and decode notifications should not be
@ -35,16 +31,13 @@
* triggers a decode, all notifications that can be generated from the currently
* loaded data fire before the call returns. If FLAG_SYNC_DECODE is not passed,
* all, some, or none of the notifications may fire before the call returns.
*
* This interface will be cleaned up in bug 505385.
*
* @author Stuart Parmenter <pavlov@netscape.com>
* @version 0.1
* @see imagelib2
*/
[scriptable, uuid(eb9f4145-247e-44f5-961d-50da7d08fba7)]
interface imgIDecoderObserver : nsISupports
class imgDecoderObserver : public mozilla::RefCounted<imgDecoderObserver>,
public mozilla::SupportsWeakPtr<imgDecoderObserver>
{
public:
virtual ~imgDecoderObserver() = 0;
/**
* Load notification.
*
@ -52,7 +45,7 @@ interface imgIDecoderObserver : nsISupports
* (used only for observers of imgIRequest objects, which are nsIRequests,
* not imgIDecoder objects)
*/
void onStartRequest();
virtual void OnStartRequest() = 0;
/**
* Decode notification.
@ -61,7 +54,7 @@ interface imgIDecoderObserver : nsISupports
* "header-only" decodes used by decode-on-draw to parse the width/height
* out of the image. Thus, it is a decode notification only.
*/
void onStartDecode();
virtual void OnStartDecode() = 0;
/**
* Load notification.
@ -71,36 +64,36 @@ interface imgIDecoderObserver : nsISupports
* called, the size has been set on the container and STATUS_SIZE_AVAILABLE
* has been set on the associated imgRequest.
*/
void onStartContainer();
virtual void OnStartContainer() = 0;
/**
* Decode notification.
*
* called when there is more to paint.
*/
[noscript] void onDataAvailable([const] in nsIntRect aRect);
virtual void OnDataAvailable(const nsIntRect * aRect) = 0;
[noscript] void frameChanged([const] in nsIntRect aDirtyRect);
virtual void FrameChanged(const nsIntRect * aDirtyRect) = 0;
/**
* Decode notification.
*
* called when a frame is finished decoding.
*/
void onStopFrame();
virtual void OnStopFrame() = 0;
/**
* Notification for when an image is known to be animated. This should be
* fired at the earliest possible time.
*/
void onImageIsAnimated();
virtual void OnImageIsAnimated() = 0;
/**
* Decode notification.
*
* Called when all decoding has terminated.
*/
void onStopDecode(in nsresult status);
virtual void OnStopDecode(nsresult status) = 0;
/**
* Load notification.
@ -109,13 +102,20 @@ interface imgIDecoderObserver : nsISupports
* (used only for observers of imgIRequest objects, which are nsIRequests,
* not imgIDecoder objects)
*/
void onStopRequest(in boolean aIsLastPart);
virtual void OnStopRequest(bool aIsLastPart) = 0;
/**
* Called when the decoded image data is discarded. This means that the frames
* no longer exist in decoded form, and any attempt to access or draw the
* image will initiate a new series of progressive decode notifications.
*/
void onDiscard();
virtual void OnDiscard() = 0;
};
// We must define a destructor because derived classes call our destructor from
// theirs. Pure virtual destructors only requires that child classes implement
// a virtual destructor, not that we can't have one too!
inline imgDecoderObserver::~imgDecoderObserver()
{}
#endif // MOZILLA_IMAGELIB_IMGDECODEROBSERVER_H

View File

@ -677,7 +677,7 @@ NS_IMETHODIMP imgRequestProxy::GetHasTransferredData(bool* hasData)
return NS_OK;
}
/** imgIDecoderObserver methods **/
/** imgDecoderObserver methods **/
void imgRequestProxy::OnStartContainer()
{

View File

@ -135,7 +135,7 @@ protected:
// class) imgStatusTracker is the only class allowed to send us
// notifications.
/* non-virtual imgIDecoderObserver methods */
/* non-virtual imgDecoderObserver methods */
void OnStartContainer ();
void OnFrameUpdate (const nsIntRect * aRect);
void OnStopFrame ();

View File

@ -9,7 +9,7 @@
#include "imgRequest.h"
#include "imgIContainer.h"
#include "imgRequestProxy.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
#include "Image.h"
#include "ImageLogging.h"
#include "RasterImage.h"
@ -21,138 +21,6 @@
using namespace mozilla::image;
class imgStatusTrackerObserver : public imgIDecoderObserver,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGIDECODEROBSERVER
imgStatusTrackerObserver(imgStatusTracker* aTracker)
: mTracker(aTracker) {}
virtual ~imgStatusTrackerObserver() {}
void SetTracker(imgStatusTracker* aTracker) {
mTracker = aTracker;
}
private:
imgStatusTracker* mTracker;
};
NS_IMPL_ISUPPORTS2(imgStatusTrackerObserver,
imgIDecoderObserver,
nsISupportsWeakReference)
/** imgIDecoderObserver methods **/
NS_IMETHODIMP imgStatusTrackerObserver::OnStartDecode()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStartDecode");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStartDecode callback before we've created our image");
if (mTracker->GetRequest() && !mTracker->GetRequest()->GetMultipart()) {
MOZ_ASSERT(!mTracker->mBlockingOnload);
mTracker->mBlockingOnload = true;
mTracker->RecordBlockOnload();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendBlockOnload(iter.GetNext());
}
}
/* 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 increase the data size cumulatively.
*/
if (mTracker->GetRequest()) {
mTracker->GetRequest()->ResetCacheEntry();
}
return NS_OK;
}
NS_IMETHODIMP imgStatusTrackerObserver::OnStartRequest()
{
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStartRequest");
return NS_OK;
}
/* void onStartContainer (); */
NS_IMETHODIMP imgStatusTrackerObserver::OnStartContainer()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStartContainer");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStartContainer callback before we've created our image");
mTracker->RecordStartContainer(mTracker->GetImage());
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStartContainer(iter.GetNext());
}
return NS_OK;
}
/* [noscript] void onDataAvailable ([const] in nsIntRect rect); */
NS_IMETHODIMP imgStatusTrackerObserver::OnDataAvailable(const nsIntRect * rect)
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnDataAvailable");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDataAvailable callback before we've created our image");
mTracker->RecordDataAvailable();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendDataAvailable(iter.GetNext(), rect);
}
return NS_OK;
}
/* [noscript] void frameChanged (in nsIntRect dirtyRect); */
NS_IMETHODIMP imgStatusTrackerObserver::FrameChanged(const nsIntRect *dirtyRect)
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::FrameChanged");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"FrameChanged callback before we've created our image");
mTracker->RecordFrameChanged(dirtyRect);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendFrameChanged(iter.GetNext(), dirtyRect);
}
return NS_OK;
}
/* void onStopFrame (); */
NS_IMETHODIMP imgStatusTrackerObserver::OnStopFrame()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStopFrame");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStopFrame callback before we've created our image");
mTracker->RecordStopFrame();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopFrame(iter.GetNext());
}
mTracker->MaybeUnblockOnload();
return NS_OK;
}
static void
FireFailureNotification(imgRequest* aRequest)
{
@ -167,79 +35,180 @@ FireFailureNotification(imgRequest* aRequest)
}
}
/* void onStopDecode (in nsresult status); */
NS_IMETHODIMP imgStatusTrackerObserver::OnStopDecode(nsresult aStatus)
class imgStatusTrackerObserver : public imgDecoderObserver
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStopDecode");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStopDecode callback before we've created our image");
public:
imgStatusTrackerObserver(imgStatusTracker* aTracker)
: mTracker(aTracker) {}
// We finished the decode, and thus have the decoded frames. Update the cache
// entry size to take this into account.
if (mTracker->GetRequest()) {
mTracker->GetRequest()->UpdateCacheEntrySize();
virtual ~imgStatusTrackerObserver() {}
void SetTracker(imgStatusTracker* aTracker) {
mTracker = aTracker;
}
bool preexistingError = mTracker->GetImageStatus() == imgIRequest::STATUS_ERROR;
/** imgDecoderObserver methods **/
mTracker->RecordStopDecode(aStatus);
virtual void OnStartDecode()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStartDecode");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStartDecode callback before we've created our image");
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopDecode(iter.GetNext(), aStatus);
if (mTracker->GetRequest() && !mTracker->GetRequest()->GetMultipart()) {
MOZ_ASSERT(!mTracker->mBlockingOnload);
mTracker->mBlockingOnload = true;
mTracker->RecordBlockOnload();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendBlockOnload(iter.GetNext());
}
}
/* 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 increase the data size cumulatively.
*/
if (mTracker->GetRequest()) {
mTracker->GetRequest()->ResetCacheEntry();
}
}
// This is really hacky. We need to handle the case where we start decoding,
// block onload, but then hit an error before we get to our first frame.
mTracker->MaybeUnblockOnload();
if (NS_FAILED(aStatus) && !preexistingError && mTracker->GetRequest()) {
FireFailureNotification(mTracker->GetRequest());
virtual void OnStartRequest()
{
NS_NOTREACHED("imgRequest(imgDecoderObserver)::OnStartRequest");
}
return NS_OK;
}
virtual void OnStartContainer()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStartContainer");
NS_IMETHODIMP imgStatusTrackerObserver::OnStopRequest(bool aLastPart)
{
NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
return NS_OK;
}
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStartContainer callback before we've created our image");
mTracker->RecordStartContainer(mTracker->GetImage());
/* void onDiscard (); */
NS_IMETHODIMP imgStatusTrackerObserver::OnDiscard()
{
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDiscard callback before we've created our image");
mTracker->RecordDiscard();
// Update the cache entry size, since we just got rid of frame data
if (mTracker->GetRequest()) {
mTracker->GetRequest()->UpdateCacheEntrySize();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStartContainer(iter.GetNext());
}
}
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendDiscard(iter.GetNext());
virtual void OnDataAvailable(const nsIntRect* rect)
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnDataAvailable");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDataAvailable callback before we've created our image");
mTracker->RecordDataAvailable();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendDataAvailable(iter.GetNext(), rect);
}
}
return NS_OK;
}
virtual void FrameChanged(const nsIntRect* dirtyRect)
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::FrameChanged");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"FrameChanged callback before we've created our image");
NS_IMETHODIMP imgStatusTrackerObserver::OnImageIsAnimated()
{
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnImageIsAnimated callback before we've created our image");
mTracker->RecordImageIsAnimated();
mTracker->RecordFrameChanged(dirtyRect);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendImageIsAnimated(iter.GetNext());
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendFrameChanged(iter.GetNext(), dirtyRect);
}
}
return NS_OK;
}
virtual void OnStopFrame()
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStopFrame");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStopFrame callback before we've created our image");
mTracker->RecordStopFrame();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopFrame(iter.GetNext());
}
mTracker->MaybeUnblockOnload();
}
virtual void OnStopDecode(nsresult aStatus)
{
LOG_SCOPE(GetImgLog(), "imgStatusTrackerObserver::OnStopDecode");
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnStopDecode callback before we've created our image");
// We finished the decode, and thus have the decoded frames. Update the cache
// entry size to take this into account.
if (mTracker->GetRequest()) {
mTracker->GetRequest()->UpdateCacheEntrySize();
}
bool preexistingError = mTracker->GetImageStatus() == imgIRequest::STATUS_ERROR;
mTracker->RecordStopDecode(aStatus);
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendStopDecode(iter.GetNext(), aStatus);
}
// This is really hacky. We need to handle the case where we start decoding,
// block onload, but then hit an error before we get to our first frame.
mTracker->MaybeUnblockOnload();
if (NS_FAILED(aStatus) && !preexistingError && mTracker->GetRequest()) {
FireFailureNotification(mTracker->GetRequest());
}
}
virtual void OnStopRequest(bool aLastPart)
{
NS_NOTREACHED("imgRequest(imgDecoderObserver)::OnStopRequest");
}
virtual void OnDiscard()
{
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnDiscard callback before we've created our image");
mTracker->RecordDiscard();
// Update the cache entry size, since we just got rid of frame data
if (mTracker->GetRequest()) {
mTracker->GetRequest()->UpdateCacheEntrySize();
}
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendDiscard(iter.GetNext());
}
}
virtual void OnImageIsAnimated()
{
NS_ABORT_IF_FALSE(mTracker->GetImage(),
"OnImageIsAnimated callback before we've created our image");
mTracker->RecordImageIsAnimated();
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
while (iter.HasMore()) {
mTracker->SendImageIsAnimated(iter.GetNext());
}
}
private:
imgStatusTracker* mTracker;
};
// imgStatusTracker methods

View File

@ -26,8 +26,7 @@ class Image;
#include "nsTObserverArray.h"
#include "nsIRunnable.h"
#include "nscore.h"
#include "nsWeakReference.h"
#include "imgIDecoderObserver.h"
#include "imgDecoderObserver.h"
enum {
stateRequestStarted = 1u << 0,
@ -127,7 +126,7 @@ public:
// StartFrame, DataAvailable, StopFrame, StopDecode.
void RecordDecoded();
/* non-virtual imgIDecoderObserver methods */
/* non-virtual imgDecoderObserver methods */
void RecordStartContainer(imgIContainer* aContainer);
void SendStartContainer(imgRequestProxy* aProxy);
void RecordDataAvailable();
@ -171,7 +170,7 @@ public:
inline mozilla::image::Image* GetImage() const { return mImage; }
inline imgRequest* GetRequest() const { return mRequest; }
inline imgIDecoderObserver* GetDecoderObserver() { return mTrackerObserver.get(); }
inline imgDecoderObserver* GetDecoderObserver() { return mTrackerObserver.get(); }
private:
friend class imgStatusNotifyRunnable;
@ -193,7 +192,7 @@ private:
// using the image.
nsTObserverArray<imgRequestProxy*> mConsumers;
nsRefPtr<imgIDecoderObserver> mTrackerObserver;
mozilla::RefPtr<imgDecoderObserver> mTrackerObserver;
};
#endif

View File

@ -12,7 +12,6 @@
#include "imgICache.h"
#include "imgIContainer.h"
#include "imgIEncoder.h"
#include "imgIDecoderObserver.h"
#include "gfxContext.h"
#include "nsStringStream.h"
#include "nsComponentManagerUtils.h"

View File

@ -24,14 +24,3 @@ function actOnMozImage(doc, id, func) {
func(mozImage);
return true;
}
function awaitImageContainer(doc, id, func) {
getImageLoading(doc, id).addObserver({
QueryInterface: XPCOMUtils.generateQI([Ci.imgIDecoderObserver]),
onStartContainer: function(aRequest, aContainer) {
getImageLoading(doc, id).removeObserver(this);
func(aContainer);
},
});
}

View File

@ -126,9 +126,9 @@ function getChannelLoadImageStartCallback(streamlistener)
function getChannelLoadImageStopCallback(streamlistener, next)
{
return function channelLoadStop(imglistener, aRequest) {
// We absolutely must not get imgIDecoderObserver::onStopRequest after
// nsIRequestObserver::onStopRequest has fired. If we do that, we've broken
// people's expectations by delaying events from a channel we were given.
// We absolutely must not get imgIScriptedNotificationObserver::onStopRequest
// after nsIRequestObserver::onStopRequest has fired. If we do that, we've
// broken people's expectations by delaying events from a channel we were given.
do_check_eq(streamlistener.requestStatus & STOP_REQUEST, 0);
next();

View File

@ -17,8 +17,8 @@ const LOAD_COMPLETE = 0x08;
const DECODE_COMPLETE = 0x10;
const ALL_BITS = SIZE_AVAILABLE | FRAME_COMPLETE | DECODE_COMPLETE | LOAD_COMPLETE;
// An implementation of imgIDecoderObserver with the ability to call specified
// functions on onStartRequest and onStopRequest.
// An implementation of imgIScriptedNotificationObserver with the ability to
// call specified functions on onStartRequest and onStopRequest.
function ImageListener(start_callback, stop_callback)
{
this.sizeAvailable = function onSizeAvailable(aRequest)

View File

@ -13,7 +13,6 @@
#include "nsStyleContext.h"
#include "imgIRequest.h"
#include "imgIDecoderObserver.h"
#include "imgINotificationObserver.h"
class imgRequestProxy;

View File

@ -74,7 +74,7 @@ nsMenuItemIconX::~nsMenuItemIconX()
}
// Called from mMenuObjectX's destructor, to prevent us from outliving it
// (as might otherwise happen if calls to our imgIDecoderObserver methods
// (as might otherwise happen if calls to our imgINotificationObserver methods
// are still outstanding). mMenuObjectX owns our nNativeMenuItem.
void nsMenuItemIconX::Destroy()
{

View File

@ -42,7 +42,7 @@ nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
getter_AddRefs(frame));
// If the last call failed, it was probably because our call stack originates
// in an imgIDecoderObserver event, meaning that we're not allowed request
// in an imgINotificationObserver event, meaning that we're not allowed request
// a sync decode. Presumably the originating event is something sensible like
// OnStopFrame(), so we can just retry the call without a sync decode.
if (NS_FAILED(rv))