Bug 1357318 - remember previous priority boost request in imgRequest. r=tnikkel
MozReview-Commit-ID: IieWWUw8EIB
--- a/image/imgIRequest.idl
+++ b/image/imgIRequest.idl
@@ -203,10 +203,28 @@ interface imgIRequest : nsIRequest
/**
* Tell the image it can forget about a request that the image animate.
*
* @see Image::DecrementAnimationConsumers for documentation of the
* underlying call.
*/
void decrementAnimationConsumers();
+
+ /**
+ * Request loading priority boost to requested category, each category
+ * of request increases priority only one time..
+ *
+ * CATEGORY_FRAME_INIT: increase priority when the imgRequest is associated
+ * with an nsImageFrame.
+ *
+ * CATEGORY_SIZE_QUERY: increase priority when size decoding is necessary to
+ * determine the layout size of the associated nsImageFrame.
+ *
+ * CATEGORY_DISPLAY: increase priority when the image is about to be displayed
+ * in the viewport.
+ */
+ const uint32_t CATEGORY_FRAME_INIT = 1 << 0;
+ const uint32_t CATEGORY_SIZE_QUERY = 1 << 1;
+ const uint32_t CATEGORY_DISPLAY = 1 << 2;
+ void boostPriority(in uint32_t aCategory);
};
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -536,20 +536,58 @@ imgRequest::AdjustPriority(imgRequestPro
// to increase the priority of requests that have a lot of proxies. the key
// concern though is that image loads remain lower priority than other pieces
// of content such as link clicks, CSS, and JS.
//
if (!mFirstProxy || proxy != mFirstProxy) {
return;
}
+ AdjustPriorityInternal(delta);
+}
+
+void
+imgRequest::AdjustPriorityInternal(int32_t aDelta)
+{
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
if (p) {
- p->AdjustPriority(delta);
+ p->AdjustPriority(aDelta);
+ }
+}
+
+void
+imgRequest::BoostPriority(uint32_t aCategory)
+{
+ uint32_t newRequestedCategory =
+ (mBoostCategoriesRequested & aCategory) ^ aCategory;
+ if (!newRequestedCategory) {
+ // priority boost for each category can only apply once.
+ return;
}
+
+ MOZ_LOG(gImgLog, LogLevel::Debug,
+ ("[this=%p] imgRequest::BoostPriority for category %x",
+ this, newRequestedCategory));
+
+ int32_t delta = 0;
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_FRAME_INIT) {
+ --delta;
+ }
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_SIZE_QUERY) {
+ --delta;
+ }
+
+ if (newRequestedCategory & imgIRequest::CATEGORY_DISPLAY) {
+ delta += nsISupportsPriority::PRIORITY_HIGH;
+ }
+
+ AdjustPriorityInternal(delta);
+ mBoostCategoriesRequested |= newRequestedCategory;
}
bool
imgRequest::HasTransferredData() const
{
MutexAutoLock lock(mMutex);
return mGotData;
}
--- a/image/imgRequest.h
+++ b/image/imgRequest.h
@@ -166,16 +166,18 @@ public:
/// @return the priority of the underlying network request, or
/// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
int32_t Priority() const;
/// Adjust the priority of the underlying network request by @aDelta on behalf
/// of @aProxy.
void AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta);
+ void BoostPriority(uint32_t aCategory);
+
/// Returns a weak pointer to the underlying request.
nsIRequest* GetRequest() const { return mRequest; }
nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
nsresult GetSecurityInfo(nsISupports** aSecurityInfoOut);
imgCacheValidator* GetValidator() const { return mValidator; }
@@ -218,16 +220,18 @@ private:
void Cancel(nsresult aStatus);
// Update the cache entry size based on the image container.
void UpdateCacheEntrySize();
/// Returns true if StartDecoding() was called.
bool IsDecodeRequested() const;
+ void AdjustPriorityInternal(int32_t aDelta);
+
// Weak reference to parent loader; this request cannot outlive its owner.
imgLoader* mLoader;
nsCOMPtr<nsIRequest> mRequest;
// The original URI we were loaded with. This is the same as the URI we are
// keyed on in the cache. We store a string here to avoid off main thread
// refcounting issues with nsStandardURL.
RefPtr<ImageURL> mURI;
// The URI of the resource we ended up loading after all redirects, etc.
@@ -270,16 +274,19 @@ private:
// default, imgIRequest::CORS_NONE.
int32_t mCORSMode;
// The Referrer Policy (defined in ReferrerPolicy.h) used for this image.
ReferrerPolicy mReferrerPolicy;
nsresult mImageErrorCode;
+ // The categories of prioritization strategy that have been requested.
+ uint32_t mBoostCategoriesRequested = 0;
+
mutable mozilla::Mutex mMutex;
// Member variables protected by mMutex. Note that *all* flags in our bitfield
// are protected by mMutex; if you're adding a new flag that isn'protected, it
// must not be a part of this bitfield.
RefPtr<ProgressTracker> mProgressTracker;
RefPtr<Image> mImage;
bool mIsMultiPartChannel : 1;
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -713,16 +713,24 @@ imgRequestProxy::GetCORSMode(int32_t* aC
return NS_ERROR_FAILURE;
}
*aCorsMode = GetOwner()->GetCORSMode();
return NS_OK;
}
+NS_IMETHODIMP
+imgRequestProxy::BoostPriority(uint32_t aCategory)
+{
+ NS_ENSURE_STATE(GetOwner() && !mCanceled);
+ GetOwner()->BoostPriority(aCategory);
+ return NS_OK;
+}
+
/** nsISupportsPriority methods **/
NS_IMETHODIMP
imgRequestProxy::GetPriority(int32_t* priority)
{
NS_ENSURE_STATE(GetOwner());
*priority = GetOwner()->Priority();
return NS_OK;