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 249677 9bee343c34ec0bf144f95c277680f7e5263dd24d
parent 249676 4c3af36331e06dbb56da0b5d37feb5b97c07db61
child 249678 9eed99d204967b603da7eb343dd04e059db4e01f
push id28936
push userryanvm@gmail.com
push dateFri, 19 Jun 2015 20:34:42 +0000
treeherdermozilla-central@c319f262ce3e [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