Bug 1453801 - Part 1. Ensure WebRenderUserData objects are freed after a tab switch. r=sotaro
authorAndrew Osmond <aosmond@mozilla.com>
Mon, 23 Apr 2018 07:57:13 -0400
changeset 415099 f3eeeae62a5a723d500cd9d1bd92beeae363f2c1
parent 415098 3beab0f25e5152f1b874239c403bfb91c0920cc9
child 415100 c9f4fd7170ad7602981791cb1db1288afed61472
push id33889
push useraciure@mozilla.com
push dateTue, 24 Apr 2018 01:14:50 +0000
treeherdermozilla-central@b35a1f66c452 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1453801
milestone61.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 1453801 - Part 1. Ensure WebRenderUserData objects are freed after a tab switch. r=sotaro
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderUserData.cpp
gfx/layers/wr/WebRenderUserData.h
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -1065,20 +1065,17 @@ WebRenderCommandBuilder::DoGroupingForDi
   g.ConstructGroups(this, aBuilder, aResources, &group, aList, aSc);
   mScrollingHelper.EndList(aSc);
 }
 
 void
 WebRenderCommandBuilder::Destroy()
 {
   mLastCanvasDatas.Clear();
-  RemoveUnusedAndResetWebRenderUserData();
-  // UserDatas should only be in the used state during a call to WebRenderCommandBuilder::BuildWebRenderCommands
-  // The should always be false upon return from BuildWebRenderCommands().
-  MOZ_RELEASE_ASSERT(mWebRenderUserDatas.Count() == 0);
+  ClearCachedResources();
 }
 
 void
 WebRenderCommandBuilder::EmptyTransaction()
 {
   // We need to update canvases that might have changed.
   for (auto iter = mLastCanvasDatas.Iter(); !iter.Done(); iter.Next()) {
     RefPtr<WebRenderCanvasData> canvasData = iter.Get()->GetKey();
@@ -1825,20 +1822,20 @@ WebRenderCommandBuilder::RemoveUnusedAnd
 
     data->SetUsed(false);
   }
 }
 
 void
 WebRenderCommandBuilder::ClearCachedResources()
 {
-  for (auto iter = mWebRenderUserDatas.Iter(); !iter.Done(); iter.Next()) {
-    WebRenderUserData* data = iter.Get()->GetKey();
-    data->ClearCachedResources();
-  }
+  RemoveUnusedAndResetWebRenderUserData();
+  // UserDatas should only be in the used state during a call to WebRenderCommandBuilder::BuildWebRenderCommands
+  // The should always be false upon return from BuildWebRenderCommands().
+  MOZ_RELEASE_ASSERT(mWebRenderUserDatas.Count() == 0);
 }
 
 
 
 WebRenderGroupData::WebRenderGroupData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
   : WebRenderUserData(aWRManager, aItem)
 {
   MOZ_COUNT_CTOR(WebRenderGroupData);
--- a/gfx/layers/wr/WebRenderUserData.cpp
+++ b/gfx/layers/wr/WebRenderUserData.cpp
@@ -62,59 +62,41 @@ WebRenderUserData::WrBridge() const
 WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
   : WebRenderUserData(aWRManager, aItem)
   , mOwnsKey(false)
 {
 }
 
 WebRenderImageData::~WebRenderImageData()
 {
-  DoClearCachedResources();
+  ClearImageKey();
+
+  if (mExternalImageId) {
+    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+  }
+
+  if (mPipelineId) {
+    WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
+  }
 }
 
 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) {
       mWRManager->AddImageKeyForDiscard(mKey.value());
     }
     mKey.reset();
   }
   mOwnsKey = false;
 }
 
-void
-WebRenderImageData::ClearCachedResources()
-{
-  DoClearCachedResources();
-}
-
-void
-WebRenderImageData::DoClearCachedResources()
-{
-  ClearImageKey();
-
-  if (mExternalImageId) {
-    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
-    mExternalImageId.reset();
-  }
-
-  if (mPipelineId) {
-    WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
-    mPipelineId.reset();
-  }
-
-  if (mImageClient) {
-    mImageClient = nullptr;
-  }
-}
-
 Maybe<wr::ImageKey>
 WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
                                    wr::IpcResourceUpdateQueue& aResources,
                                    bool aFallback)
 {
   MOZ_ASSERT(aContainer);
 
   if (mContainer != aContainer) {
@@ -270,24 +252,16 @@ WebRenderFallbackData::WebRenderFallback
   , mInvalid(false)
 {
 }
 
 WebRenderFallbackData::~WebRenderFallbackData()
 {
 }
 
-void
-WebRenderFallbackData::ClearCachedResources()
-{
-  WebRenderImageData::ClearCachedResources();
-  mBasicLayerManager = nullptr;
-  mInvalid = true;
-}
-
 nsDisplayItemGeometry*
 WebRenderFallbackData::GetGeometry()
 {
   return mGeometry.get();
 }
 
 void
 WebRenderFallbackData::SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
@@ -315,28 +289,16 @@ WebRenderAnimationData::~WebRenderAnimat
 
 WebRenderCanvasData::WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
   : WebRenderUserData(aWRManager, aItem)
 {
 }
 
 WebRenderCanvasData::~WebRenderCanvasData()
 {
-  DoClearCachedResources();
-}
-
-void
-WebRenderCanvasData::ClearCachedResources()
-{
-  DoClearCachedResources();
-}
-
-void
-WebRenderCanvasData::DoClearCachedResources()
-{
   if (mCanvasRenderer) {
     mCanvasRenderer->ClearCachedResources();
   }
 }
 
 void
 WebRenderCanvasData::ClearCanvasRenderer()
 {
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -57,17 +57,16 @@ public:
   };
 
   virtual UserDataType GetType() = 0;
   bool IsUsed() { return mUsed; }
   void SetUsed(bool aUsed) { mUsed = aUsed; }
   nsIFrame* GetFrame() { return mFrame; }
   uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
   void RemoveFromTable();
-  virtual void ClearCachedResources() {};
   virtual nsDisplayItemGeometry* GetGeometry() { return nullptr; }
 protected:
   virtual ~WebRenderUserData();
 
   WebRenderBridgeChild* WrBridge() const;
 
   RefPtr<WebRenderLayerManager> mWRManager;
   nsIFrame* mFrame;
@@ -121,27 +120,25 @@ public:
                                          const LayoutDeviceRect& aSCBounds,
                                          const gfx::Matrix4x4& aSCTransform,
                                          const gfx::MaybeIntSize& aScaleToSize,
                                          const wr::ImageRendering& aFilter,
                                          const wr::MixBlendMode& aMixBlendMode,
                                          bool aIsBackfaceVisible);
 
   void CreateImageClientIfNeeded();
-  void ClearCachedResources() override;
 
   bool IsAsync()
   {
     return mPipelineId.isSome();
   }
 
 protected:
   void ClearImageKey();
   void CreateExternalImageIfNeeded();
-  void DoClearCachedResources();
 
   wr::MaybeExternalImageId mExternalImageId;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
   Maybe<wr::PipelineId> mPipelineId;
   RefPtr<ImageContainer> mContainer;
   bool mOwnsKey;
 };
@@ -150,17 +147,16 @@ class WebRenderFallbackData : public Web
 {
 public:
   explicit WebRenderFallbackData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
   virtual ~WebRenderFallbackData();
 
   virtual WebRenderFallbackData* AsFallbackData() override { return this; }
   virtual UserDataType GetType() override { return UserDataType::eFallback; }
   static UserDataType Type() { return UserDataType::eFallback; }
-  void ClearCachedResources() override;
   nsDisplayItemGeometry* GetGeometry() override;
   void SetGeometry(nsAutoPtr<nsDisplayItemGeometry> aGeometry);
   nsRect GetBounds() { return mBounds; }
   void SetBounds(const nsRect& aRect) { mBounds = aRect; }
   void SetInvalid(bool aInvalid) { mInvalid = aInvalid; }
   void SetScale(gfx::Size aScale) { mScale = aScale; }
   gfx::Size GetScale() { return mScale; }
   bool IsInvalid() { return mInvalid; }
@@ -195,19 +191,17 @@ public:
 
   virtual WebRenderCanvasData* AsCanvasData() override { return this; }
   virtual UserDataType GetType() override { return UserDataType::eCanvas; }
   static UserDataType Type() { return UserDataType::eCanvas; }
 
   void ClearCanvasRenderer();
   WebRenderCanvasRendererAsync* GetCanvasRenderer();
   WebRenderCanvasRendererAsync* CreateCanvasRenderer();
-  void ClearCachedResources() override;
 protected:
-  void DoClearCachedResources();
 
   UniquePtr<WebRenderCanvasRendererAsync> mCanvasRenderer;
 };
 
 extern void DestroyWebRenderUserDataTable(WebRenderUserDataTable* aTable);
 
 struct WebRenderUserDataProperty {
   NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(Key, WebRenderUserDataTable, DestroyWebRenderUserDataTable)