Bug 1175371 - Make VectorImage wait to deliver LOAD_COMPLETE until its size is available. r=dholbert
authorSeth Fowler <mark.seth.fowler@gmail.com>
Thu, 18 Jun 2015 14:48:41 -0700
changeset 280448 9bee343c34ec0bf144f95c277680f7e5263dd24d
parent 280447 4c3af36331e06dbb56da0b5d37feb5b97c07db61
child 280449 9eed99d204967b603da7eb343dd04e059db4e01f
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1175371
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1175371 - Make VectorImage wait to deliver LOAD_COMPLETE until its size is available. r=dholbert
image/VectorImage.cpp
image/VectorImage.h
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -410,23 +410,28 @@ VectorImage::OnImageDataComplete(nsIRequ
   // Call our internal OnStopRequest method, which only talks to our embedded
   // SVG document. This won't have any effect on our ProgressTracker.
   nsresult finalStatus = OnStopRequest(aRequest, aContext, aStatus);
 
   // Give precedence to Necko failure codes.
   if (NS_FAILED(aStatus)) {
     finalStatus = aStatus;
   }
+  
+  Progress loadProgress = LoadCompleteProgress(aLastPart, mError, finalStatus);
 
-  // Actually fire OnStopRequest.
-  if (mProgressTracker) {
-    mProgressTracker->SyncNotifyProgress(LoadCompleteProgress(aLastPart,
-                                                              mError,
-                                                              finalStatus));
+  if (mIsFullyLoaded || mError) {
+    // Our document is loaded, so we're ready to notify now.
+    mProgressTracker->SyncNotifyProgress(loadProgress);
+  } else {
+    // Record our progress so far; we'll actually send the notifications in
+    // OnSVGDocumentLoaded or OnSVGDocumentError.
+    mLoadProgress = Some(loadProgress);
   }
+
   return finalStatus;
 }
 
 nsresult
 VectorImage::OnImageDataAvailable(nsIRequest* aRequest,
                                   nsISupports* aContext,
                                   nsIInputStream* aInStr,
                                   uint64_t aSourceOffset,
@@ -1170,42 +1175,57 @@ VectorImage::OnSVGDocumentLoaded()
   mIsFullyLoaded = true;
   mHaveAnimations = mSVGDocumentWrapper->IsAnimated();
 
   // Start listening to our image for rendering updates.
   mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
 
   // Tell *our* observers that we're done loading.
   if (mProgressTracker) {
-    mProgressTracker->SyncNotifyProgress(FLAG_SIZE_AVAILABLE |
-                                         FLAG_HAS_TRANSPARENCY |
-                                         FLAG_FRAME_COMPLETE |
-                                         FLAG_DECODE_COMPLETE |
-                                         FLAG_ONLOAD_UNBLOCKED,
-                                         GetMaxSizedIntRect());
+    Progress progress = FLAG_SIZE_AVAILABLE |
+                        FLAG_HAS_TRANSPARENCY |
+                        FLAG_FRAME_COMPLETE |
+                        FLAG_DECODE_COMPLETE |
+                        FLAG_ONLOAD_UNBLOCKED;
+
+    // Merge in any saved progress from OnImageDataComplete.
+    if (mLoadProgress) {
+      progress |= *mLoadProgress;
+      mLoadProgress = Nothing();
+    }
+
+    mProgressTracker->SyncNotifyProgress(progress, GetMaxSizedIntRect());
   }
 
   EvaluateAnimation();
 }
 
 void
 VectorImage::OnSVGDocumentError()
 {
   CancelAllListeners();
 
   // XXXdholbert Need to do something more for the parsing failed case -- right
   // now, this just makes us draw the "object" icon, rather than the (jagged)
   // "broken image" icon.  See bug 594505.
   mError = true;
 
   if (mProgressTracker) {
-    // Unblock page load.
-    mProgressTracker->SyncNotifyProgress(FLAG_DECODE_COMPLETE |
-                                         FLAG_ONLOAD_UNBLOCKED |
-                                         FLAG_HAS_ERROR);
+    // Notify observers about the error and unblock page load.
+    Progress progress = FLAG_DECODE_COMPLETE |
+                        FLAG_ONLOAD_UNBLOCKED |
+                        FLAG_HAS_ERROR;
+
+    // Merge in any saved progress from OnImageDataComplete.
+    if (mLoadProgress) {
+      progress |= *mLoadProgress;
+      mLoadProgress = Nothing();
+    }
+
+    mProgressTracker->SyncNotifyProgress(progress);
   }
 }
 
 //------------------------------------------------------------------------------
 // nsIStreamListener method
 
 //******************************************************************************
 /* void onDataAvailable(in nsIRequest request, in nsISupports ctxt,
--- a/image/VectorImage.h
+++ b/image/VectorImage.h
@@ -95,16 +95,22 @@ private:
   nsRefPtr<SVGDocumentWrapper>       mSVGDocumentWrapper;
   nsRefPtr<SVGRootRenderingObserver> mRenderingObserver;
   nsRefPtr<SVGLoadEventListener>     mLoadEventListener;
   nsRefPtr<SVGParseCompleteListener> mParseCompleteListener;
 
   /// Count of locks on this image (roughly correlated to visible instances).
   uint32_t mLockCount;
 
+  // Stored result from the Necko load of the image, which we save in
+  // OnImageDataComplete if the underlying SVG document isn't loaded. If we save
+  // this, we actually notify this progress (and clear this value) in
+  // OnSVGDocumentLoaded or OnSVGDocumentError.
+  Maybe<Progress> mLoadProgress;
+
   bool           mIsInitialized;          // Have we been initialized?
   bool           mDiscardable;            // Are we discardable?
   bool           mIsFullyLoaded;          // Has the SVG document finished
                                           // loading?
   bool           mIsDrawing;              // Are we currently drawing?
   bool           mHaveAnimations;         // Is our SVG content SMIL-animated?
                                           // (Only set after mIsFullyLoaded.)
   bool           mHasPendingInvalidation; // Invalidate observers next refresh