Bug 1510139 - Part 1. Ensure we honor invalidations if using vector image containers. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Mon, 17 Dec 2018 08:31:04 -0500
changeset 513993 325d06d3ba7341035f01ae14bc882643d0235083
parent 513992 6362baa5cb54a12724396665790d982c84516c90
child 513994 b709624ce8fa0ca4146d8d0675036440e6807615
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1510139
milestone66.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 1510139 - Part 1. Ensure we honor invalidations if using vector image containers. r=tnikkel If a vector image has an image container, it is unlikely the caller will call VectorImage::Draw (and thus Show indirectly) to display the image. As such, WebRender was missing subsequent invalidations and not regenerating the rasterized surface as expected. Thus we now resume honoring the invalidations if we updated the image container. Differential Revision: https://phabricator.services.mozilla.com/D15667
image/Image.cpp
image/Image.h
image/VectorImage.cpp
--- a/image/Image.cpp
+++ b/image/Image.cpp
@@ -257,17 +257,17 @@ ImgDrawResult ImageResource::GetImageCon
   }
 
   SetCurrentImage(container, surface, Nothing());
   entry->mLastDrawResult = drawResult;
   container.forget(aOutContainer);
   return drawResult;
 }
 
-void ImageResource::UpdateImageContainer(const Maybe<IntRect>& aDirtyRect) {
+bool ImageResource::UpdateImageContainer(const Maybe<IntRect>& aDirtyRect) {
   MOZ_ASSERT(NS_IsMainThread());
 
   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;
@@ -284,16 +284,18 @@ void ImageResource::UpdateImageContainer
         IntRect dirtyRect(IntPoint(0, 0), bestSize);
         SetCurrentImage(container, surface, Some(dirtyRect));
       }
     } else {
       // Stop tracking if our weak pointer to the image container was freed.
       mImageContainers.RemoveElementAt(i);
     }
   }
+
+  return !mImageContainers.IsEmpty();
 }
 
 void ImageResource::ReleaseImageContainer() {
   MOZ_ASSERT(NS_IsMainThread());
   mImageContainers.Clear();
 }
 
 // Constructor
--- a/image/Image.h
+++ b/image/Image.h
@@ -363,17 +363,22 @@ class ImageResource : public Image {
   }
 
   ImgDrawResult GetImageContainerImpl(layers::LayerManager* aManager,
                                       const gfx::IntSize& aSize,
                                       const Maybe<SVGImageContext>& aSVGContext,
                                       uint32_t aFlags,
                                       layers::ImageContainer** aContainer);
 
-  void UpdateImageContainer(const Maybe<gfx::IntRect>& aDirtyRect);
+  /**
+   * Re-requests the appropriate frames for each image container using
+   * GetFrameInternal.
+   * @returns True if any image containers were updated, else false.
+   */
+  bool UpdateImageContainer(const Maybe<gfx::IntRect>& aDirtyRect);
 
   void ReleaseImageContainer();
 
  private:
   void SetCurrentImage(layers::ImageContainer* aContainer,
                        gfx::SourceSurface* aSurface,
                        const Maybe<gfx::IntRect>& aDirtyRect);
 
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -558,23 +558,30 @@ void VectorImage::SendInvalidationNotifi
   // Non-animated images call this method directly from
   // InvalidateObserversOnNextRefreshDriverTick, because RequestRefresh is never
   // called for them. Ordinarily this isn't needed, since we send out
   // invalidation notifications in OnSVGDocumentLoaded, but in rare cases the
   // SVG document may not be 100% ready to render at that time. In those cases
   // we would miss the subsequent invalidations if we didn't send out the
   // notifications directly in |InvalidateObservers...|.
 
+  SurfaceCache::RemoveImage(ImageKey(this));
+
+  if (UpdateImageContainer(Nothing())) {
+    // If we have image containers, that means we probably won't get a Draw call
+    // from the owner since they are using the container. We must assume all
+    // invalidations need to be handled.
+    MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
+    mRenderingObserver->ResumeHonoringInvalidations();
+  }
+
   if (mProgressTracker) {
-    SurfaceCache::RemoveImage(ImageKey(this));
     mProgressTracker->SyncNotifyProgress(FLAG_FRAME_COMPLETE,
                                          GetMaxSizedIntRect());
   }
-
-  UpdateImageContainer(Nothing());
 }
 
 NS_IMETHODIMP_(IntRect)
 VectorImage::GetImageSpaceInvalidationRect(const IntRect& aRect) {
   return aRect;
 }
 
 //******************************************************************************