Bug 1368776 - Part 15. Cache flags passed to ImageResource::GetImageContainerImpl for consistency. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 17 Nov 2017 06:45:28 -0500
changeset 392351 b9a29d94ccac646c9336fa75e084bbc8581501ad
parent 392350 ea3f6961ec397c07c6a6d4ffc2c72c402a6ea1dc
child 392352 8d8cfa078d8601abcb66e1edb786e971f929ad89
push id97447
push useraosmond@gmail.com
push dateFri, 17 Nov 2017 11:46:46 +0000
treeherdermozilla-inbound@8d8cfa078d86 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1368776
milestone59.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 1368776 - Part 15. Cache flags passed to ImageResource::GetImageContainerImpl for consistency. r=tnikkel When FLAG_HIGH_QUALITY_SCALING is used, we need to make sure we continue using that flag when we update the container. We should also use it for comparing whether or not an existing image container is equivalent.
image/Image.cpp
image/Image.h
--- a/image/Image.cpp
+++ b/image/Image.cpp
@@ -106,23 +106,25 @@ ImageResource::GetImageContainerImpl(Lay
   if (size.IsEmpty()) {
     return nullptr;
   }
 
   if (mAnimationConsumers == 0) {
     SendOnUnlockedDraw(aFlags);
   }
 
+  uint32_t flags = (aFlags & ~(FLAG_SYNC_DECODE |
+                               FLAG_SYNC_DECODE_IF_FAST)) | FLAG_ASYNC_NOTIFY;
   RefPtr<layers::ImageContainer> container;
   ImageContainerEntry* entry = nullptr;
   int i = mImageContainers.Length() - 1;
   for (; i >= 0; --i) {
     entry = &mImageContainers[i];
     container = entry->mContainer.get();
-    if (size == entry->mSize) {
+    if (size == entry->mSize && flags == entry->mFlags) {
       // Lack of a container is handled below.
       break;
     } else if (!container) {
       // Stop tracking if our weak pointer to the image container was freed.
       mImageContainers.RemoveElementAt(i);
     }
   }
 
@@ -174,17 +176,17 @@ ImageResource::GetImageContainerImpl(Lay
     container = nullptr;
 
     // We need to do the entry search again for the new size. We skip pruning
     // because we did this above once already, but ImageContainer is threadsafe,
     // so there is a remote possibility it got freed.
     i = mImageContainers.Length() - 1;
     for (; i >= 0; --i) {
       entry = &mImageContainers[i];
-      if (bestSize == entry->mSize) {
+      if (bestSize == entry->mSize && flags == entry->mFlags) {
         container = entry->mContainer.get();
         if (container) {
           switch (entry->mLastDrawResult) {
             case DrawResult::SUCCESS:
             case DrawResult::BAD_IMAGE:
             case DrawResult::BAD_ARGS:
               return container.forget();
             case DrawResult::NOT_READY:
@@ -208,17 +210,17 @@ ImageResource::GetImageContainerImpl(Lay
   if (!container) {
     // We need a new ImageContainer, so create one.
     container = LayerManager::CreateImageContainer();
 
     if (i >= 0) {
       entry->mContainer = container;
     } else {
       entry = mImageContainers.AppendElement(
-        ImageContainerEntry(bestSize, container.get()));
+        ImageContainerEntry(bestSize, container.get(), flags));
     }
   }
 
   SetCurrentImage(container, surface, true);
   entry->mLastDrawResult = drawResult;
   return container.forget();
 }
 
@@ -229,17 +231,17 @@ ImageResource::UpdateImageContainer()
 
   for (int i = mImageContainers.Length() - 1; i >= 0; --i) {
     ImageContainerEntry& entry = mImageContainers[i];
     RefPtr<ImageContainer> container = entry.mContainer.get();
     if (container) {
       IntSize bestSize;
       RefPtr<SourceSurface> surface;
       Tie(entry.mLastDrawResult, bestSize, surface) =
-        GetFrameInternal(entry.mSize, FRAME_CURRENT, FLAG_ASYNC_NOTIFY);
+        GetFrameInternal(entry.mSize, FRAME_CURRENT, entry.mFlags);
 
       // It is possible that this is a factor-of-2 substitution. Since we
       // managed to convert the weak reference into a strong reference, that
       // means that an imagelib user still is holding onto the container. thus
       // we cannot consolidate and must keep updating the duplicate container.
       SetCurrentImage(container, surface, false);
     } else {
       // Stop tracking if our weak pointer to the image container was freed.
--- a/image/Image.h
+++ b/image/Image.h
@@ -370,29 +370,34 @@ protected:
 
 private:
   void SetCurrentImage(layers::ImageContainer* aContainer,
                        gfx::SourceSurface* aSurface,
                        bool aInTransaction);
 
   struct ImageContainerEntry {
     ImageContainerEntry(const gfx::IntSize& aSize,
-                        layers::ImageContainer* aContainer)
+                        layers::ImageContainer* aContainer,
+                        uint32_t aFlags)
       : mSize(aSize)
       , mContainer(aContainer)
       , mLastDrawResult(DrawResult::NOT_READY)
+      , mFlags(aFlags)
     { }
 
     gfx::IntSize                        mSize;
     // A weak pointer to our ImageContainer, which stays alive only as long as
     // the layer system needs it.
     WeakPtr<layers::ImageContainer>     mContainer;
     // If mContainer is non-null, this contains the DrawResult we obtained
     // the last time we updated it.
     DrawResult                          mLastDrawResult;
+    // Cached flags to use for decoding. FLAG_ASYNC_NOTIFY should always be set
+    // but FLAG_HIGH_QUALITY_SCALING may vary.
+    uint32_t                            mFlags;
   };
 
   AutoTArray<ImageContainerEntry, 1> mImageContainers;
   layers::ImageContainer::ProducerID mImageProducerID;
   layers::ImageContainer::FrameID mLastFrameID;
 };
 
 } // namespace image