Bug 1084136 (Part 7) - Treat being multipart as an image state. r=tn
authorSeth Fowler <seth@mozilla.com>
Thu, 06 Nov 2014 17:33:59 -0800
changeset 214445 70b9dd23c3f972b7ed5534bde0ca651da6c0e4e6
parent 214444 443d2ef1ba033afd84eeb220d126e2d9489b1457
child 214446 e6a962ab3605e9a9f6f513bbb01274dd23e0bf35
push id51493
push usermfowler@mozilla.com
push dateFri, 07 Nov 2014 02:17:12 +0000
treeherdermozilla-inbound@f245578c4fa4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1084136
milestone36.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 1084136 (Part 7) - Treat being multipart as an image state. r=tn
image/src/imgStatusTracker.cpp
image/src/imgStatusTracker.h
--- a/image/src/imgStatusTracker.cpp
+++ b/image/src/imgStatusTracker.cpp
@@ -141,29 +141,27 @@ private:
 };
 
 // imgStatusTracker methods
 
 imgStatusTracker::imgStatusTracker(Image* aImage)
   : mImage(aImage),
     mState(0),
     mImageStatus(imgIRequest::STATUS_NONE),
-    mIsMultipart(false),
     mHadLastPart(false),
     mHasBeenDecoded(false)
 {
   mTrackerObserver = new imgStatusTrackerObserver(this);
 }
 
 // Private, used only by CloneForRecording.
 imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
   : mImage(aOther.mImage),
     mState(aOther.mState),
     mImageStatus(aOther.mImageStatus),
-    mIsMultipart(aOther.mIsMultipart),
     mHadLastPart(aOther.mHadLastPart),
     mHasBeenDecoded(aOther.mHasBeenDecoded)
     // Note: we explicitly don't copy several fields:
     //  - mRequestRunnable, because it won't be nulled out when the
     //    mRequestRunnable's Run function eventually gets called.
     //  - mProperties, because we don't need it and it'd just point at the same
     //    object
     //  - mConsumers, because we don't need to talk to consumers
@@ -205,16 +203,21 @@ imgStatusTracker::SetImage(Image* aImage
 
 void
 imgStatusTracker::ResetImage()
 {
   NS_ABORT_IF_FALSE(mImage, "Resetting image when it's already null!");
   mImage = nullptr;
 }
 
+void imgStatusTracker::SetIsMultipart()
+{
+  mState |= FLAG_IS_MULTIPART;
+}
+
 bool
 imgStatusTracker::IsLoading() const
 {
   // Checking for whether OnStopRequest has fired allows us to say we're
   // loading before OnStartRequest gets called, letting the request properly
   // get removed from the cache in certain cases.
   return !(mState & FLAG_REQUEST_STOPPED);
 }
@@ -418,18 +421,16 @@ imgStatusTracker::SyncNotifyState(ProxyA
 ImageStatusDiff
 imgStatusTracker::Difference(imgStatusTracker* aOther) const
 {
   MOZ_ASSERT(aOther, "aOther cannot be null");
   ImageStatusDiff diff;
   diff.diffState = ~mState & aOther->mState & ~FLAG_REQUEST_STARTED;
   diff.diffImageStatus = ~mImageStatus & aOther->mImageStatus;
 
-  MOZ_ASSERT(!mIsMultipart || aOther->mIsMultipart, "mIsMultipart should be monotonic");
-  diff.foundIsMultipart = !mIsMultipart && aOther->mIsMultipart;
   diff.foundLastPart = !mHadLastPart && aOther->mHadLastPart;
 
   diff.gotDecoded = !mHasBeenDecoded && aOther->mHasBeenDecoded;
 
   // Only record partial invalidations if we haven't been decoded before.
   // When images are re-decoded after discarding, we don't want to display
   // partially decoded versions to the user.
   const uint32_t combinedStatus = mImageStatus | aOther->mImageStatus;
@@ -465,17 +466,16 @@ imgStatusTracker::ApplyDifference(const 
   LOG_SCOPE(GetImgLog(), "imgStatusTracker::ApplyDifference");
 
   // We must not modify or notify for the start-load state, which happens from Necko callbacks.
   uint32_t loadState = mState & FLAG_REQUEST_STARTED;
 
   // Synchronize our state.
   mState |= aDiff.diffState | loadState;
 
-  mIsMultipart = mIsMultipart || aDiff.foundIsMultipart;
   mHadLastPart = mHadLastPart || aDiff.foundLastPart;
   mHasBeenDecoded = mHasBeenDecoded || aDiff.gotDecoded;
 
   // Update the image status. There are some subtle points which are handled below.
   mImageStatus |= aDiff.diffImageStatus;
 }
 
 void
--- a/image/src/imgStatusTracker.h
+++ b/image/src/imgStatusTracker.h
@@ -32,56 +32,53 @@ enum {
   FLAG_REQUEST_STARTED    = 1u << 0,
   FLAG_HAS_SIZE           = 1u << 1,
   FLAG_DECODE_STARTED     = 1u << 2,
   FLAG_DECODE_STOPPED     = 1u << 3,
   FLAG_FRAME_STOPPED      = 1u << 4,
   FLAG_REQUEST_STOPPED    = 1u << 5,
   FLAG_ONLOAD_BLOCKED     = 1u << 6,
   FLAG_ONLOAD_UNBLOCKED   = 1u << 7,
-  FLAG_IS_ANIMATED        = 1u << 8
+  FLAG_IS_ANIMATED        = 1u << 8,
+  FLAG_IS_MULTIPART       = 1u << 9
 };
 
 struct ImageStatusDiff
 {
   ImageStatusDiff()
     : invalidRect()
     , diffState(0)
     , diffImageStatus(0)
-    , foundIsMultipart(false)
     , foundLastPart(false)
     , gotDecoded(false)
   { }
 
   static ImageStatusDiff NoChange() { return ImageStatusDiff(); }
   bool IsNoChange() const { return *this == NoChange(); }
 
   bool operator!=(const ImageStatusDiff& aOther) const { return !(*this == aOther); }
   bool operator==(const ImageStatusDiff& aOther) const {
     return aOther.invalidRect == invalidRect
         && aOther.diffState == diffState
         && aOther.diffImageStatus == diffImageStatus
-        && aOther.foundIsMultipart == foundIsMultipart
         && aOther.foundLastPart == foundLastPart
         && aOther.gotDecoded == gotDecoded;
   }
 
   void Combine(const ImageStatusDiff& aOther) {
     invalidRect = invalidRect.Union(aOther.invalidRect);
     diffState |= aOther.diffState;
     diffImageStatus |= aOther.diffImageStatus;
-    foundIsMultipart = foundIsMultipart || aOther.foundIsMultipart;
     foundLastPart = foundLastPart || aOther.foundLastPart;
     gotDecoded = gotDecoded || aOther.gotDecoded;
   }
 
   nsIntRect invalidRect;
   uint32_t  diffState;
   uint32_t  diffImageStatus;
-  bool      foundIsMultipart   : 1;
   bool      foundLastPart      : 1;
   bool      gotDecoded         : 1;
 };
 
 } // namespace image
 } // namespace mozilla
 
 /*
@@ -115,17 +112,17 @@ public:
   // without an image.
   void SetImage(mozilla::image::Image* aImage);
 
   // Image resetter, for when mImage is about to go out of scope. mImage is a
   // weak reference, and thus must be set to null when it's object is deleted.
   void ResetImage();
 
   // Inform this status tracker that it is associated with a multipart image.
-  void SetIsMultipart() { mIsMultipart = true; }
+  void SetIsMultipart();
 
   // Schedule an asynchronous "replaying" of all the notifications that would
   // have to happen to put us in the current state.
   // We will also take note of any notifications that happen between the time
   // Notify() is called and when we call SyncNotify on |proxy|, and replay them
   // as well.
   // Should be called on the main thread only, since imgRequestProxy and GetURI
   // are not threadsafe.
@@ -247,17 +244,17 @@ public:
   void RecordUnblockOnload();
   void SendUnblockOnload(imgRequestProxy* aProxy);
 
   // Main thread only because mConsumers is not threadsafe.
   void MaybeUnblockOnload();
 
   void RecordError();
 
-  bool IsMultipart() const { return mIsMultipart; }
+  bool IsMultipart() const { return mState & mozilla::image::FLAG_IS_MULTIPART; }
 
   // Weak pointer getters - no AddRefs.
   inline already_AddRefed<mozilla::image::Image> GetImage() const {
     nsRefPtr<mozilla::image::Image> image = mImage;
     return image.forget();
   }
   inline bool HasImage() { return mImage; }
 
@@ -312,17 +309,16 @@ private:
   // using the image. Array and/or individual elements should only be accessed
   // on the main thread.
   ProxyArray mConsumers;
 
   mozilla::RefPtr<imgDecoderObserver> mTrackerObserver;
 
   uint32_t mState;
   uint32_t mImageStatus;
-  bool mIsMultipart    : 1;
   bool mHadLastPart    : 1;
   bool mHasBeenDecoded : 1;
 };
 
 class imgStatusTrackerInit
 {
 public:
   imgStatusTrackerInit(mozilla::image::Image* aImage,