Bug 1520158 - Avoid scene rebuilding for image frame updates if possible. r=jrmuizel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 18 Jan 2019 22:21:30 -0500
changeset 511699 096cd49afd334998208b46af3bbfc32d1ebd0760
parent 511698 1d1f4d473d92581e24f46a822968f024e28203b0
child 511700 f90bab5af97efa714181eea7fad45cf8cf14e3ea
child 511710 af99824dcbcd5c142c4abbd9ca6c44f17a2bc947
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1520158
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 1520158 - Avoid scene rebuilding for image frame updates if possible. r=jrmuizel We already avoid scene rebuilding for animated image frame updates, but we can easily apply this to still images. If the decoding is happening slowly and in chunks for some reason (really large image, slow network), then we may save some work.
gfx/layers/wr/WebRenderUserData.cpp
gfx/layers/wr/WebRenderUserData.h
layout/style/ImageLoader.cpp
--- a/gfx/layers/wr/WebRenderUserData.cpp
+++ b/gfx/layers/wr/WebRenderUserData.cpp
@@ -52,17 +52,17 @@ void WebRenderBackgroundData::AddWebRend
   if (fallback) {
     fallback->SetInvalid(true);
     aFrame->SchedulePaint();
     return true;
   }
 
   RefPtr<WebRenderImageData> image =
       GetWebRenderUserData<WebRenderImageData>(aFrame, type);
-  if (image && image->IsAsyncAnimatedImage()) {
+  if (image && image->UsingSharedSurface()) {
     return true;
   }
 
   aFrame->SchedulePaint();
   return false;
 }
 
 WebRenderUserData::WebRenderUserData(RenderRootStateManager* aManager,
@@ -88,18 +88,28 @@ WebRenderImageData::WebRenderImageData(R
 WebRenderImageData::~WebRenderImageData() {
   ClearImageKey();
 
   if (mPipelineId) {
     mManager->RemovePipelineIdForCompositable(mPipelineId.ref());
   }
 }
 
-bool WebRenderImageData::IsAsyncAnimatedImage() const {
-  return mContainer && mContainer->GetSharedSurfacesAnimation();
+bool WebRenderImageData::UsingSharedSurface() const {
+  if (!mContainer || !mKey || mOwnsKey) {
+    return false;
+  }
+
+  // If this is just an update with the same image key, then we know that the
+  // share request initiated an asynchronous update so that we don't need to
+  // rebuild the scene.
+  wr::ImageKey key;
+  nsresult rv = SharedSurfacesChild::Share(mContainer, mManager,
+      mManager->AsyncResourceUpdates(), key);
+  return NS_SUCCEEDED(rv) && mKey.ref() == key;
 }
 
 void WebRenderImageData::ClearImageKey() {
   if (mKey) {
     // If we don't own the key, then the owner is responsible for discarding the
     // key when appropriate.
     if (mOwnsKey) {
       mManager->AddImageKeyForDiscard(mKey.value());
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -142,17 +142,17 @@ class WebRenderImageData : public WebRen
       const LayoutDeviceRect& aSCBounds, const gfx::Matrix4x4& aSCTransform,
       const gfx::MaybeIntSize& aScaleToSize, const wr::ImageRendering& aFilter,
       const wr::MixBlendMode& aMixBlendMode, bool aIsBackfaceVisible);
 
   void CreateImageClientIfNeeded();
 
   bool IsAsync() { return mPipelineId.isSome(); }
 
-  bool IsAsyncAnimatedImage() const;
+  bool UsingSharedSurface() const;
 
  protected:
   virtual void ClearImageKey();
 
   RefPtr<TextureClient> mTextureOfImage;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
   Maybe<wr::PipelineId> mPipelineId;
--- a/layout/style/ImageLoader.cpp
+++ b/layout/style/ImageLoader.cpp
@@ -511,17 +511,17 @@ static void InvalidateImages(nsIFrame* a
             static_cast<layers::WebRenderFallbackData*>(data.get())
                 ->SetInvalid(true);
           }
           // XXX: handle Blob data
           invalidateFrame = true;
           break;
         case layers::WebRenderUserData::UserDataType::eImage:
           if (static_cast<layers::WebRenderImageData*>(data.get())
-                  ->IsAsyncAnimatedImage()) {
+                  ->UsingSharedSurface()) {
             break;
           }
           MOZ_FALLTHROUGH;
         default:
           invalidateFrame = true;
           break;
       }
     }