Bug 1312770 - Part 1, allow any imgRequestProxy to adjust load priority. r?tnikkel draft
authorShih-Chiang Chien <schien@mozilla.com>
Thu, 16 Feb 2017 14:01:22 +0800
changeset 501865 57fdb18cbbee272c69196f6d3ed7ade6758f0ad6
parent 499512 ff04d410e74b69acfab17ef7e73e7397602d5a68
child 501866 13e9755bd62bccb6764e645defcab3d0734dc134
push id50136
push userbmo:schien@mozilla.com
push dateTue, 21 Mar 2017 02:23:02 +0000
reviewerstnikkel
bugs1312770
milestone55.0a1
Bug 1312770 - Part 1, allow any imgRequestProxy to adjust load priority. r?tnikkel MozReview-Commit-ID: AE5M2MxT6Ku
image/imgIRequest.idl
image/imgRequest.cpp
image/imgRequest.h
image/imgRequestProxy.cpp
layout/generic/nsImageFrame.cpp
--- a/image/imgIRequest.idl
+++ b/image/imgIRequest.idl
@@ -203,10 +203,18 @@ 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();
+
+  /**
+   * Allows any imgRequestProxy to adjust priority by a given delta.
+   *
+   * @param delta  the delta value to increase or decrease the priority
+   * @see xpcom/threads/nsISupportsPriority.idl for the priority value
+   */
+  void forceAdjustPriority(in int32_t delta);
 };
 
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -523,26 +523,29 @@ int32_t imgRequest::Priority() const
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mRequest);
   if (p) {
     p->GetPriority(&priority);
   }
   return priority;
 }
 
 void
-imgRequest::AdjustPriority(imgRequestProxy* proxy, int32_t delta)
+imgRequest::AdjustPriority(imgRequestProxy* proxy,
+                           int32_t delta,
+                           bool aForceUpdate)
 {
   // only the first proxy is allowed to modify the priority of this image load.
   //
   // XXX(darin): this is probably not the most optimal algorithm as we may want
   // 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) {
+  // aForceUpdate is introduced to allow micro managing the image load priority.
+  if (!aForceUpdate && (!mFirstProxy || proxy != mFirstProxy)) {
     return;
   }
 
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel);
   if (p) {
     p->AdjustPriority(delta);
   }
 }
--- a/image/imgRequest.h
+++ b/image/imgRequest.h
@@ -164,17 +164,17 @@ public:
   const char* GetMimeType() const { return mContentType.get(); }
 
   /// @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 AdjustPriority(imgRequestProxy* aProxy, int32_t aDelta, bool aForceUpdate = false);
 
   /// Returns a weak pointer to the underlying request.
   nsIRequest* GetRequest() const { return mRequest; }
 
   nsITimedChannel* GetTimedChannel() const { return mTimedChannel; }
 
   nsresult GetSecurityInfo(nsISupports** aSecurityInfoOut);
 
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -711,16 +711,24 @@ imgRequestProxy::GetCORSMode(int32_t* aC
     return NS_ERROR_FAILURE;
   }
 
   *aCorsMode = GetOwner()->GetCORSMode();
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+imgRequestProxy::ForceAdjustPriority(int32_t aDelta)
+{
+  NS_ENSURE_STATE(GetOwner() && !mCanceled);
+  GetOwner()->AdjustPriority(this, aDelta, /* aForceUpdate = */ true);
+  return NS_OK;
+}
+
 /** nsISupportsPriority methods **/
 
 NS_IMETHODIMP
 imgRequestProxy::GetPriority(int32_t* priority)
 {
   NS_ENSURE_STATE(GetOwner());
   *priority = GetOwner()->Priority();
   return NS_OK;
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -278,19 +278,19 @@ nsImageFrame::Init(nsIContent*       aCo
   // We have a PresContext now, so we need to notify the image content node
   // that it can register images.
   imageLoader->FrameCreated(this);
 
   // Give image loads associated with an image frame a small priority boost!
   nsCOMPtr<imgIRequest> currentRequest;
   imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
                           getter_AddRefs(currentRequest));
-  nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(currentRequest);
-  if (p)
-    p->AdjustPriority(-1);
+  if (currentRequest) {
+    currentRequest->ForceAdjustPriority(-1);
+  }
 }
 
 bool
 nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
 {
   NS_PRECONDITION(aImage, "null image");
   if (!aImage)
     return false;