mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 505385 - Part 8: Remove image reference from proxies, and delegate operations on images to the owning request or the status tracker. r=joe
This commit is contained in:
parent
b215db7b80
commit
6348c50b96
@ -995,7 +995,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
|
||||
if (mResniffMimeType) {
|
||||
NS_ABORT_IF_FALSE(mIsMultiPartChannel, "Resniffing a non-multipart image");
|
||||
imgStatusTracker* freshTracker = new imgStatusTracker(nullptr, this);
|
||||
freshTracker->AdoptConsumers(mStatusTracker);
|
||||
freshTracker->AdoptConsumers(&GetStatusTracker());
|
||||
mStatusTracker = freshTracker;
|
||||
}
|
||||
|
||||
@ -1012,7 +1012,7 @@ imgRequest::OnDataAvailable(nsIRequest *aRequest, nsISupports *ctxt,
|
||||
// Notify any imgRequestProxys that are observing us that we have an Image.
|
||||
nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(GetStatusTracker().GetConsumers());
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->SetImage(mImage);
|
||||
iter.GetNext()->SetHasImage();
|
||||
}
|
||||
|
||||
/* set our mimetype as a property */
|
||||
|
@ -40,7 +40,6 @@ NS_INTERFACE_MAP_END
|
||||
imgRequestProxy::imgRequestProxy() :
|
||||
mOwner(nullptr),
|
||||
mURI(nullptr),
|
||||
mImage(nullptr),
|
||||
mListener(nullptr),
|
||||
mLoadFlags(nsIRequest::LOAD_NORMAL),
|
||||
mLockCount(0),
|
||||
@ -50,7 +49,8 @@ imgRequestProxy::imgRequestProxy() :
|
||||
mListenerIsStrongRef(false),
|
||||
mDecodeRequested(false),
|
||||
mDeferNotifications(false),
|
||||
mSentStartContainer(false)
|
||||
mSentStartContainer(false),
|
||||
mOwnerHasImage(false)
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
|
||||
@ -100,6 +100,8 @@ nsresult imgRequestProxy::Init(imgStatusTracker* aStatusTracker,
|
||||
|
||||
mStatusTracker = aStatusTracker;
|
||||
mOwner = aStatusTracker->GetRequest();
|
||||
mOwnerHasImage = !!aStatusTracker->GetImage();
|
||||
MOZ_ASSERT_IF(mOwner, mStatusTracker == &mOwner->GetStatusTracker());
|
||||
mListener = aObserver;
|
||||
// Make sure to addref mListener before the AddProxy call below, since
|
||||
// that call might well want to release it if the imgRequest has
|
||||
@ -109,7 +111,6 @@ nsresult imgRequestProxy::Init(imgStatusTracker* aStatusTracker,
|
||||
NS_ADDREF(mListener);
|
||||
}
|
||||
mLoadGroup = aLoadGroup;
|
||||
mImage = aStatusTracker->GetImage();
|
||||
mURI = aURI;
|
||||
|
||||
// Note: AddProxy won't send all the On* notifications immediately
|
||||
@ -133,9 +134,9 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
||||
uint32_t oldAnimationConsumers = mAnimationConsumers;
|
||||
ClearAnimationConsumers();
|
||||
|
||||
// Even if we are cancelled, we MUST change our image, because the image
|
||||
// holds our status, and the status must always be correct.
|
||||
mImage = aNewOwner->mImage;
|
||||
nsRefPtr<imgRequest> oldOwner = mOwner;
|
||||
mOwner = aNewOwner;
|
||||
mStatusTracker = &aNewOwner->GetStatusTracker();
|
||||
|
||||
// If we were locked, apply the locks here
|
||||
for (uint32_t i = 0; i < oldLockCount; i++)
|
||||
@ -152,13 +153,12 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
||||
|
||||
// Were we decoded before?
|
||||
bool wasDecoded = false;
|
||||
if (mImage &&
|
||||
(mImage->GetStatusTracker().GetImageStatus() &
|
||||
imgIRequest::STATUS_FRAME_COMPLETE)) {
|
||||
if (GetImage() &&
|
||||
(GetStatusTracker().GetImageStatus() & imgIRequest::STATUS_FRAME_COMPLETE)) {
|
||||
wasDecoded = true;
|
||||
}
|
||||
|
||||
mOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER);
|
||||
oldOwner->RemoveProxy(this, NS_IMAGELIB_CHANGING_OWNER);
|
||||
|
||||
// If we had animation requests, restore them here. Note that we
|
||||
// do this *after* RemoveProxy, which clears out animation consumers
|
||||
@ -166,8 +166,6 @@ nsresult imgRequestProxy::ChangeOwner(imgRequest *aNewOwner)
|
||||
for (uint32_t i = 0; i < oldAnimationConsumers; i++)
|
||||
IncrementAnimationConsumers();
|
||||
|
||||
mOwner = aNewOwner;
|
||||
|
||||
mOwner->AddProxy(this);
|
||||
|
||||
// If we were decoded, or if we'd previously requested a decode, request a
|
||||
@ -330,8 +328,8 @@ NS_IMETHODIMP
|
||||
imgRequestProxy::LockImage()
|
||||
{
|
||||
mLockCount++;
|
||||
if (mImage)
|
||||
return mImage->LockImage();
|
||||
if (GetImage())
|
||||
return GetImage()->LockImage();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -342,8 +340,8 @@ imgRequestProxy::UnlockImage()
|
||||
NS_ABORT_IF_FALSE(mLockCount > 0, "calling unlock but no locks!");
|
||||
|
||||
mLockCount--;
|
||||
if (mImage)
|
||||
return mImage->UnlockImage();
|
||||
if (GetImage())
|
||||
return GetImage()->UnlockImage();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -351,9 +349,8 @@ imgRequestProxy::UnlockImage()
|
||||
NS_IMETHODIMP
|
||||
imgRequestProxy::RequestDiscard()
|
||||
{
|
||||
if (mImage) {
|
||||
return mImage->RequestDiscard();
|
||||
}
|
||||
if (GetImage())
|
||||
return GetImage()->RequestDiscard();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -361,8 +358,8 @@ NS_IMETHODIMP
|
||||
imgRequestProxy::IncrementAnimationConsumers()
|
||||
{
|
||||
mAnimationConsumers++;
|
||||
if (mImage)
|
||||
mImage->IncrementAnimationConsumers();
|
||||
if (GetImage())
|
||||
GetImage()->IncrementAnimationConsumers();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -377,8 +374,8 @@ imgRequestProxy::DecrementAnimationConsumers()
|
||||
// early, but not the observer.)
|
||||
if (mAnimationConsumers > 0) {
|
||||
mAnimationConsumers--;
|
||||
if (mImage)
|
||||
mImage->DecrementAnimationConsumers();
|
||||
if (GetImage())
|
||||
GetImage()->DecrementAnimationConsumers();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -435,7 +432,7 @@ NS_IMETHODIMP imgRequestProxy::GetImage(imgIContainer * *aImage)
|
||||
// that'll happen if we get Canceled before the owner instantiates its image
|
||||
// (because Canceling unregisters us as a listener on mOwner). If we're
|
||||
// in that situation, just grab the image off of mOwner.
|
||||
imgIContainer* imageToReturn = mImage ? mImage : mOwner->mImage;
|
||||
imgIContainer* imageToReturn = GetImage() ? GetImage() : mOwner->mImage.get();
|
||||
|
||||
if (!imageToReturn)
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -824,9 +821,10 @@ NS_IMETHODIMP
|
||||
imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
||||
{
|
||||
*aReturn = nullptr;
|
||||
mozilla::image::Image* image = GetImage();
|
||||
|
||||
bool animated;
|
||||
if (!mImage || (NS_SUCCEEDED(mImage->GetAnimated(&animated)) && !animated)) {
|
||||
if (!image || (NS_SUCCEEDED(image->GetAnimated(&animated)) && !animated)) {
|
||||
// Early exit - we're not animated, so we don't have to do anything.
|
||||
NS_ADDREF(*aReturn = this);
|
||||
return NS_OK;
|
||||
@ -835,13 +833,13 @@ imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
||||
// We are animated. We need to extract the current frame from this image.
|
||||
int32_t w = 0;
|
||||
int32_t h = 0;
|
||||
mImage->GetWidth(&w);
|
||||
mImage->GetHeight(&h);
|
||||
image->GetWidth(&w);
|
||||
image->GetHeight(&h);
|
||||
nsIntRect rect(0, 0, w, h);
|
||||
nsCOMPtr<imgIContainer> currentFrame;
|
||||
nsresult rv = mImage->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
|
||||
imgIContainer::FLAG_SYNC_DECODE,
|
||||
getter_AddRefs(currentFrame));
|
||||
nsresult rv = image->ExtractFrame(imgIContainer::FRAME_CURRENT, rect,
|
||||
imgIContainer::FLAG_SYNC_DECODE,
|
||||
getter_AddRefs(currentFrame));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -850,7 +848,7 @@ imgRequestProxy::GetStaticRequest(imgIRequest** aReturn)
|
||||
// Create a static imgRequestProxy with our new extracted frame.
|
||||
nsCOMPtr<nsIPrincipal> currentPrincipal;
|
||||
GetImagePrincipal(getter_AddRefs(currentPrincipal));
|
||||
nsRefPtr<imgRequestProxy> req = new imgRequestProxyStatic(currentPrincipal);
|
||||
nsRefPtr<imgRequestProxy> req = new imgRequestProxyStatic(frame, currentPrincipal);
|
||||
req->Init(&frame->GetStatusTracker(), nullptr, mURI, nullptr);
|
||||
|
||||
NS_ADDREF(*aReturn = req);
|
||||
@ -871,9 +869,9 @@ void imgRequestProxy::NotifyListener()
|
||||
} 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(mImage,
|
||||
NS_ABORT_IF_FALSE(GetImage(),
|
||||
"if we have no imgRequest, we should have an Image");
|
||||
mImage->GetStatusTracker().NotifyCurrentState(this);
|
||||
GetStatusTracker().NotifyCurrentState(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -888,25 +886,23 @@ void imgRequestProxy::SyncNotifyListener()
|
||||
}
|
||||
|
||||
void
|
||||
imgRequestProxy::SetImage(Image* aImage)
|
||||
imgRequestProxy::SetHasImage()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(aImage, "Setting null image");
|
||||
NS_ABORT_IF_FALSE(!mImage || mOwner->GetMultipart(),
|
||||
"Setting image when we already have one");
|
||||
Image* image = GetStatusTracker().GetImage();
|
||||
|
||||
mImage = aImage;
|
||||
mOwnerHasImage = true;
|
||||
|
||||
// Apply any locks we have
|
||||
for (uint32_t i = 0; i < mLockCount; ++i)
|
||||
mImage->LockImage();
|
||||
image->LockImage();
|
||||
|
||||
// Apply any animation consumers we have
|
||||
for (uint32_t i = 0; i < mAnimationConsumers; i++)
|
||||
mImage->IncrementAnimationConsumers();
|
||||
image->IncrementAnimationConsumers();
|
||||
}
|
||||
|
||||
imgStatusTracker&
|
||||
imgRequestProxy::GetStatusTracker()
|
||||
imgRequestProxy::GetStatusTracker() 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.
|
||||
@ -914,7 +910,15 @@ imgRequestProxy::GetStatusTracker()
|
||||
// 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 mImage ? mImage->GetStatusTracker() : mOwner->GetStatusTracker();
|
||||
return *mStatusTracker;
|
||||
}
|
||||
|
||||
mozilla::image::Image*
|
||||
imgRequestProxy::GetImage() const
|
||||
{
|
||||
if (!mOwnerHasImage)
|
||||
return nullptr;
|
||||
return GetStatusTracker().GetImage();
|
||||
}
|
||||
|
||||
////////////////// imgRequestProxyStatic methods
|
||||
@ -928,3 +932,9 @@ NS_IMETHODIMP imgRequestProxyStatic::GetImagePrincipal(nsIPrincipal **aPrincipal
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::image::Image*
|
||||
imgRequestProxyStatic::GetImage() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
@ -93,9 +93,8 @@ public:
|
||||
mDeferNotifications = aDeferNotifications;
|
||||
}
|
||||
|
||||
// Setter for our |mImage| pointer, for imgRequest to use, once it
|
||||
// instantiates an Image.
|
||||
void SetImage(mozilla::image::Image* aImage);
|
||||
// XXXbholley - This eventually gets folded into the new notification API.
|
||||
void SetHasImage();
|
||||
|
||||
// Removes all animation consumers that were created with
|
||||
// IncrementAnimationConsumers. This is necessary since we need
|
||||
@ -169,7 +168,7 @@ protected:
|
||||
// live either on mOwner or mImage, depending on whether
|
||||
// (a) we have an mOwner at all
|
||||
// (b) whether mOwner has instantiated its image yet
|
||||
imgStatusTracker& GetStatusTracker();
|
||||
imgStatusTracker& GetStatusTracker() const;
|
||||
|
||||
nsITimedChannel* TimedChannel()
|
||||
{
|
||||
@ -178,6 +177,8 @@ protected:
|
||||
return mOwner->mTimedChannel;
|
||||
}
|
||||
|
||||
virtual mozilla::image::Image* GetImage() const;
|
||||
|
||||
public:
|
||||
NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
|
||||
|
||||
@ -198,10 +199,6 @@ private:
|
||||
// The URI of our request.
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
// The image we represent. Is null until data has been received, and is then
|
||||
// set by imgRequest.
|
||||
nsRefPtr<mozilla::image::Image> mImage;
|
||||
|
||||
// mListener is only promised to be a weak ref (see imgILoader.idl),
|
||||
// but we actually keep a strong ref to it until we've seen our
|
||||
// first OnStopRequest.
|
||||
@ -223,6 +220,9 @@ private:
|
||||
// We only want to send OnStartContainer once for each proxy, but we might
|
||||
// get multiple OnStartContainer calls.
|
||||
bool mSentStartContainer;
|
||||
|
||||
protected:
|
||||
bool mOwnerHasImage;
|
||||
};
|
||||
|
||||
// Used for static image proxies for which no requests are available, so
|
||||
@ -231,15 +231,28 @@ class imgRequestProxyStatic : public imgRequestProxy
|
||||
{
|
||||
|
||||
public:
|
||||
imgRequestProxyStatic(nsIPrincipal* aPrincipal) : mPrincipal(aPrincipal) {};
|
||||
imgRequestProxyStatic(mozilla::image::Image* aImage,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: mImage(aImage)
|
||||
, mPrincipal(aPrincipal)
|
||||
{
|
||||
mOwnerHasImage = true;
|
||||
};
|
||||
|
||||
NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal);
|
||||
|
||||
protected:
|
||||
// Our image. We have to hold a strong reference here, because that's normally
|
||||
// the job of the underlying request.
|
||||
nsRefPtr<mozilla::image::Image> mImage;
|
||||
|
||||
// Our principal. We have to cache it, rather than accessing the underlying
|
||||
// request on-demand, because static proxies don't have an underlying request.
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
|
||||
private:
|
||||
mozilla::image::Image* GetImage() const MOZ_OVERRIDE;
|
||||
using imgRequestProxy::GetImage;
|
||||
};
|
||||
|
||||
#endif // imgRequestProxy_h__
|
||||
|
Loading…
Reference in New Issue
Block a user