Bug 792199. Only decode visible images immediately when switching to a tab. r=joe

This creates a new method 'StartDecoding' which does a RequestDecode and some
decoding of the image.

--HG--
extra : rebase_source : 89c1c2f40e3dfb6e025939ebf3257f81ce429501
This commit is contained in:
Jeff Muizelaar 2012-10-04 16:02:15 -04:00
Родитель ac8fdf1333
Коммит 62bb43ba59
16 изменённых файлов: 82 добавлений и 15 удалений

Просмотреть файл

@ -8391,7 +8391,7 @@ nsDocument::AddImage(imgIRequest* aImage)
if (oldCount == 0 && mLockingImages) {
rv = aImage->LockImage();
if (NS_SUCCEEDED(rv))
rv = aImage->RequestDecode();
rv = aImage->StartDecoding();
}
// If this is the first insertion and we're animating images, request

Просмотреть файл

@ -268,7 +268,7 @@ nsImageLoadingContent::OnStopDecode(imgIRequest* aRequest,
if (shell && shell->IsVisible() &&
(!shell->DidInitialize() || shell->IsPaintingSuppressed())) {
mCurrentRequest->RequestDecode();
mCurrentRequest->StartDecoding();
}
// Fire the appropriate DOM event.

Просмотреть файл

@ -5789,7 +5789,7 @@ nsSVGFEImageElement::OnStartContainer(imgIRequest *aRequest,
// Request a decode
NS_ABORT_IF_FALSE(aContainer, "who sent the notification then?");
aContainer->RequestDecode();
aContainer->StartDecoding();
// We have a size - invalidate
Invalidate();

Просмотреть файл

@ -57,7 +57,7 @@ native gfxGraphicsFilter(gfxPattern::GraphicsFilter);
*
* Internally, imgIContainer also manages animation of images.
*/
[scriptable, uuid(ead94080-cfd6-4a3e-8353-bd45333061d2)]
[scriptable, uuid(d6c58749-ceb6-4afe-ab72-ff3086433e1f)]
interface imgIContainer : nsISupports
{
/**
@ -233,6 +233,11 @@ interface imgIContainer : nsISupports
*/
void requestDecode();
/*
* This is equivalent to requestDecode() but it also decodes some of the image.
*/
[noscript] void startDecoding();
/**
* Increments the lock count on the image. An image will not be discarded
* as long as the lock count is nonzero. Note that it is still possible for

Просмотреть файл

@ -146,6 +146,7 @@ interface imgIRequest : nsIRequest
* container does not yet exist.
*/
void requestDecode();
void startDecoding();
/**
* Locks an image. If the image does not exist yet, locks it once it becomes

Просмотреть файл

@ -2518,13 +2518,27 @@ RasterImage::WantDecodedFrames()
}
// Request a decode (no-op if we're decoded)
return RequestDecode();
return StartDecoding();
}
//******************************************************************************
/* void requestDecode() */
NS_IMETHODIMP
RasterImage::RequestDecode()
{
return RequestDecodeCore(ASYNCHRONOUS);
}
/* void startDecode() */
NS_IMETHODIMP
RasterImage::StartDecoding()
{
return RequestDecodeCore(SOMEWHAT_SYNCHRONOUS);
}
NS_IMETHODIMP
RasterImage::RequestDecodeCore(RequestDecodeType aDecodeType)
{
nsresult rv;
@ -2584,7 +2598,7 @@ RasterImage::RequestDecode()
// If we can do decoding now, do so. Small images will decode completely,
// large images will decode a bit and post themselves to the event loop
// to finish decoding.
if (!mDecoded && !mInDecoder && mHasSourceData) {
if (!mDecoded && !mInDecoder && mHasSourceData && aDecodeType == SOMEWHAT_SYNCHRONOUS) {
SAMPLE_LABEL_PRINTF("RasterImage", "DecodeABitOf", "%s", GetURIString());
DecodeWorker::Singleton()->DecodeABitOf(this);
return NS_OK;

Просмотреть файл

@ -163,7 +163,8 @@ public:
NS_IMETHOD ExtractFrame(uint32_t aWhichFrame, const nsIntRect & aRect, uint32_t aFlags, imgIContainer **_retval);
NS_IMETHOD Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, const gfxMatrix & aUserSpaceToImageSpace, const gfxRect & aFill, const nsIntRect & aSubimage, const nsIntSize & aViewportSize, uint32_t aFlags);
NS_IMETHOD_(nsIFrame *) GetRootLayoutFrame(void);
NS_IMETHOD RequestDecode(void);
NS_IMETHOD RequestDecode();
NS_IMETHOD StartDecoding();
NS_IMETHOD LockImage(void);
NS_IMETHOD UnlockImage(void);
NS_IMETHOD RequestDiscard(void);
@ -688,6 +689,11 @@ private:
void SetInUpdateImageContainer(bool aInUpdate) { mInUpdateImageContainer = aInUpdate; }
bool IsInUpdateImageContainer() { return mInUpdateImageContainer; }
enum RequestDecodeType {
ASYNCHRONOUS,
SOMEWHAT_SYNCHRONOUS
};
NS_IMETHOD RequestDecodeCore(RequestDecodeType aDecodeType);
private: // data
@ -817,7 +823,7 @@ class imgDecodeRequestor : public nsRunnable
}
NS_IMETHOD Run() {
if (mContainer)
mContainer->RequestDecode();
mContainer->StartDecoding();
return NS_OK;
}

Просмотреть файл

@ -575,6 +575,14 @@ VectorImage::RequestDecode()
return NS_OK;
}
NS_IMETHODIMP
VectorImage::StartDecoding()
{
// Nothing to do for SVG images
return NS_OK;
}
//******************************************************************************
/* void lockImage() */
NS_IMETHODIMP

Просмотреть файл

@ -45,7 +45,8 @@ public:
NS_IMETHOD ExtractFrame(uint32_t aWhichFrame, const nsIntRect & aRect, uint32_t aFlags, imgIContainer **_retval);
NS_IMETHOD Draw(gfxContext *aContext, gfxPattern::GraphicsFilter aFilter, const gfxMatrix & aUserSpaceToImageSpace, const gfxRect & aFill, const nsIntRect & aSubimage, const nsIntSize & aViewportSize, uint32_t aFlags);
NS_IMETHOD_(nsIFrame *) GetRootLayoutFrame(void);
NS_IMETHOD RequestDecode(void);
NS_IMETHOD RequestDecode();
NS_IMETHOD StartDecoding();
NS_IMETHOD LockImage(void);
NS_IMETHOD UnlockImage(void);
NS_IMETHOD RequestDiscard(void);

Просмотреть файл

@ -496,6 +496,22 @@ imgRequest::RequestDecode()
return NS_OK;
}
nsresult
imgRequest::StartDecoding()
{
// If we've initialized our image, we can request a decode.
if (mImage) {
return mImage->StartDecoding();
}
// Otherwise, flag to do it when we get the image
mDecodeRequested = true;
return NS_OK;
}
/** imgIContainerObserver methods **/
/* [noscript] void frameChanged (in imgIRequest request,
@ -1147,7 +1163,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
if (mImage->GetType() == imgIContainer::TYPE_RASTER) {
// If we were waiting on the image to do something, now's our chance.
if (mDecodeRequested) {
mImage->RequestDecode();
mImage->StartDecoding();
}
} else { // mImage->GetType() == imgIContainer::TYPE_VECTOR
nsCOMPtr<nsIStreamListener> imageAsStream = do_QueryInterface(mImage);

Просмотреть файл

@ -81,6 +81,7 @@ public:
// instantiated.
nsresult LockImage();
nsresult UnlockImage();
nsresult StartDecoding();
nsresult RequestDecode();
inline void SetInnerWindowID(uint64_t aInnerWindowId) {

Просмотреть файл

@ -177,7 +177,7 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
// If we were decoded, or if we'd previously requested a decode, request a
// decode on the new image
if (wasDecoded || mDecodeRequested)
mOwner->RequestDecode();
mOwner->StartDecoding();
return NS_OK;
}
@ -302,6 +302,20 @@ NS_IMETHODIMP imgRequestProxy::CancelAndForgetObserver(nsresult aStatus)
return NS_OK;
}
/* void startDecode (); */
NS_IMETHODIMP
imgRequestProxy::StartDecoding()
{
if (!mOwner)
return NS_ERROR_FAILURE;
// Flag this, so we know to transfer the request if our owner changes
mDecodeRequested = true;
// Forward the request
return mOwner->StartDecoding();
}
/* void requestDecode (); */
NS_IMETHODIMP
imgRequestProxy::RequestDecode()
@ -316,6 +330,7 @@ imgRequestProxy::RequestDecode()
return mOwner->RequestDecode();
}
/* void lockImage (); */
NS_IMETHODIMP
imgRequestProxy::LockImage()

Просмотреть файл

@ -1613,7 +1613,7 @@ nsresult
nsStyleImage::RequestDecode() const
{
if ((mType == eStyleImageType_Image) && mImage)
return mImage->RequestDecode();
return mImage->StartDecoding();
return NS_OK;
}

Просмотреть файл

@ -262,7 +262,7 @@ nsImageBoxFrame::UpdateImage()
mIntrinsicSize.SizeTo(0, 0);
} else {
// We don't want discarding or decode-on-draw for xul images.
mImageRequest->RequestDecode();
mImageRequest->StartDecoding();
mImageRequest->LockImage();
}
}

Просмотреть файл

@ -2182,7 +2182,7 @@ nsTreeBodyFrame::GetImage(int32_t aRowIndex, nsTreeColumn* aCol, bool aUseContex
return NS_ERROR_FAILURE;
// We don't want discarding/decode-on-draw for xul images
imageRequest->RequestDecode();
imageRequest->StartDecoding();
imageRequest->LockImage();
// In a case it was already cached.

Просмотреть файл

@ -311,7 +311,7 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
if (NS_FAILED(rv)) return rv;
// We need to request the icon be decoded (bug 573583, bug 705516).
mIconRequest->RequestDecode();
mIconRequest->StartDecoding();
return NS_OK;