Bug 666446, Part 5/18 - Change nsImageBoxFrame to register corresponding image with nsRefreshDriver to facilitate refresh driver-based animations. [r=roc]

This commit is contained in:
Scott Johnson 2011-10-03 13:39:05 -07:00
parent e317548311
commit 9a5b073351
2 changed files with 61 additions and 5 deletions

View File

@ -72,6 +72,7 @@
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsTransform2D.h" #include "nsTransform2D.h"
#include "nsITheme.h" #include "nsITheme.h"
#include "nsIImageLoadingContent.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsIURI.h" #include "nsIURI.h"
@ -178,6 +179,7 @@ nsImageBoxFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext): nsImageBoxFrame::nsImageBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):
nsLeafBoxFrame(aShell, aContext), nsLeafBoxFrame(aShell, aContext),
mIntrinsicSize(0,0), mIntrinsicSize(0,0),
mRequestRegistered(false),
mLoadFlags(nsIRequest::LOAD_NORMAL), mLoadFlags(nsIRequest::LOAD_NORMAL),
mUseSrcAttr(PR_FALSE), mUseSrcAttr(PR_FALSE),
mSuppressStyleCheck(PR_FALSE) mSuppressStyleCheck(PR_FALSE)
@ -200,9 +202,16 @@ nsImageBoxFrame::MarkIntrinsicWidthsDirty()
void void
nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot) nsImageBoxFrame::DestroyFrom(nsIFrame* aDestructRoot)
{ {
// Release image loader first so that it's refcnt can go to zero if (mImageRequest) {
if (mImageRequest) nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::DeregisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
// Release image loader first so that it's refcnt can go to zero
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE); mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
}
if (mListener) if (mListener)
reinterpret_cast<nsImageBoxListener*>(mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object. reinterpret_cast<nsImageBoxListener*>(mListener.get())->SetFrame(nsnull); // set the frame to null so we don't send messages to a dead object.
@ -237,7 +246,12 @@ nsImageBoxFrame::Init(nsIContent* aContent,
void void
nsImageBoxFrame::UpdateImage() nsImageBoxFrame::UpdateImage()
{ {
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
if (mImageRequest) { if (mImageRequest) {
nsLayoutUtils::DeregisterImageRequest(presContext, mImageRequest,
&mRequestRegistered);
mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE); mImageRequest->CancelAndForgetObserver(NS_ERROR_FAILURE);
mImageRequest = nsnull; mImageRequest = nsnull;
} }
@ -264,6 +278,12 @@ nsImageBoxFrame::UpdateImage()
nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(), nsContentUtils::LoadImage(uri, doc, mContent->NodePrincipal(),
doc->GetDocumentURI(), mListener, mLoadFlags, doc->GetDocumentURI(), mListener, mLoadFlags,
getter_AddRefs(mImageRequest)); getter_AddRefs(mImageRequest));
// Register our imgIRequest with the refresh driver
nsLayoutUtils::RegisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
} }
} else { } else {
// Only get the list-style-image if we aren't being drawn // Only get the list-style-image if we aren't being drawn
@ -588,10 +608,31 @@ NS_IMETHODIMP nsImageBoxFrame::OnStopContainer(imgIRequest *request,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsImageBoxFrame::OnStartDecode(imgIRequest* aRequest)
{
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::RegisterImageRequest(presContext,
mImageRequest,
&mRequestRegistered);
return NS_OK;
}
NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request, NS_IMETHODIMP nsImageBoxFrame::OnStopDecode(imgIRequest *request,
nsresult aStatus, nsresult aStatus,
const PRUnichar *statusArg) const PRUnichar *statusArg)
{ {
// If the imgIRequest does not represent an animated image, then we should
// deregister it from our refresh driver.
nsPresContext* presContext = PresContext();
NS_ASSERTION(presContext, "No PresContext");
nsLayoutUtils::DeregisterImageRequestIfNotAnimated(presContext,
mImageRequest,
&mRequestRegistered);
if (NS_SUCCEEDED(aStatus)) if (NS_SUCCEEDED(aStatus))
// Fire an onload DOM event. // Fire an onload DOM event.
FireImageDOMEvent(mContent, NS_LOAD); FireImageDOMEvent(mContent, NS_LOAD);
@ -629,7 +670,7 @@ NS_IMETHODIMP nsImageBoxListener::OnStartContainer(imgIRequest *request,
imgIContainer *image) imgIContainer *image)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_OK;
return mFrame->OnStartContainer(request, image); return mFrame->OnStartContainer(request, image);
} }
@ -638,17 +679,26 @@ NS_IMETHODIMP nsImageBoxListener::OnStopContainer(imgIRequest *request,
imgIContainer *image) imgIContainer *image)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_OK;
return mFrame->OnStopContainer(request, image); return mFrame->OnStopContainer(request, image);
} }
NS_IMETHODIMP nsImageBoxListener::OnStartDecode(imgIRequest *aRequest)
{
if (!mFrame) {
return NS_OK;
}
return mFrame->OnStartDecode(aRequest);
}
NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request, NS_IMETHODIMP nsImageBoxListener::OnStopDecode(imgIRequest *request,
nsresult status, nsresult status,
const PRUnichar *statusArg) const PRUnichar *statusArg)
{ {
if (!mFrame) if (!mFrame)
return NS_ERROR_FAILURE; return NS_OK;
return mFrame->OnStopDecode(request, status, statusArg); return mFrame->OnStopDecode(request, status, statusArg);
} }

View File

@ -56,6 +56,7 @@ public:
// imgIDecoderObserver (override nsStubImageDecoderObserver) // imgIDecoderObserver (override nsStubImageDecoderObserver)
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status, NS_IMETHOD OnStopDecode(imgIRequest *request, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
// imgIContainerObserver (override nsStubImageDecoderObserver) // imgIContainerObserver (override nsStubImageDecoderObserver)
@ -119,6 +120,7 @@ public:
NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStartContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image); NS_IMETHOD OnStopContainer(imgIRequest *request, imgIContainer *image);
NS_IMETHOD OnStartDecode(imgIRequest *aRequest);
NS_IMETHOD OnStopDecode(imgIRequest *request, NS_IMETHOD OnStopDecode(imgIRequest *request,
nsresult status, nsresult status,
const PRUnichar *statusArg); const PRUnichar *statusArg);
@ -142,6 +144,10 @@ private:
nsSize mIntrinsicSize; nsSize mIntrinsicSize;
nsSize mImageSize; nsSize mImageSize;
// Boolean variable to determine if the current image request has been
// registered with the refresh driver.
bool mRequestRegistered;
nsCOMPtr<imgIRequest> mImageRequest; nsCOMPtr<imgIRequest> mImageRequest;
nsCOMPtr<imgIDecoderObserver> mListener; nsCOMPtr<imgIDecoderObserver> mListener;