Bug 1378697 - Release resources in WebRenderXXXLayer::ClearCachedResources() r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Tue, 18 Jul 2017 22:37:36 +0900
changeset 418281 7b05ec8e1222d09bbf59d0ddfaa016fed1899a48
parent 418280 649a35887b3018c91766cc4afea8370d54dd3ccd
child 418282 7bf2876b0ffd8fdb5107fcb245f02915805ca3c9
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1378697
milestone56.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 1378697 - Release resources in WebRenderXXXLayer::ClearCachedResources() r=nical
gfx/layers/client/ImageClient.cpp
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderCanvasLayer.h
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderImageLayer.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/layers/wr/WebRenderPaintedLayer.h
gfx/layers/wr/WebRenderPaintedLayerBlob.h
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -79,18 +79,16 @@ ImageClientSingle::ImageClientSingle(Com
 TextureInfo ImageClientSingle::GetTextureInfo() const
 {
   return TextureInfo(CompositableType::IMAGE);
 }
 
 void
 ImageClientSingle::FlushAllImages()
 {
-  MOZ_ASSERT(GetForwarder()->GetTextureForwarder()->UsesImageBridge());
-
   for (auto& b : mBuffers) {
     RemoveTexture(b.mTextureClient);
   }
   mBuffers.Clear();
 }
 
 /* static */ already_AddRefed<TextureClient>
 ImageClient::CreateTextureClientForImage(Image* aImage, KnowsCompositor* aForwarder)
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -17,16 +17,17 @@
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 WebRenderBridgeChild::WebRenderBridgeChild(const wr::PipelineId& aPipelineId)
   : mReadLockSequenceNumber(0)
   , mIsInTransaction(false)
+  , mIsInClearCachedResources(false)
   , mIdNamespace(0)
   , mResourceId(0)
   , mPipelineId(aPipelineId)
   , mIPCOpen(false)
   , mDestroyed(false)
   , mFontKeysDeleted(0)
 {
 }
@@ -52,17 +53,17 @@ void
 WebRenderBridgeChild::ActorDestroy(ActorDestroyReason why)
 {
   mDestroyed = true;
 }
 
 void
 WebRenderBridgeChild::AddWebRenderParentCommand(const WebRenderParentCommand& aCmd)
 {
-  MOZ_ASSERT(mIsInTransaction);
+  MOZ_ASSERT(mIsInTransaction || mIsInClearCachedResources);
   mParentCommands.AppendElement(aCmd);
 }
 
 void
 WebRenderBridgeChild::AddWebRenderParentCommands(const nsTArray<WebRenderParentCommand>& aCommands)
 {
   MOZ_ASSERT(mIsInTransaction);
   mParentCommands.AppendElements(aCommands);
@@ -455,10 +456,24 @@ WebRenderBridgeChild::RecvWrUpdated(cons
   for (auto iter = mFontKeys.Iter(); !iter.Done(); iter.Next()) {
     SendDeleteFont(iter.Data());
   }
   mFontKeys.Clear();
   GetCompositorBridgeChild()->RecvInvalidateLayers(wr::AsUint64(mPipelineId));
   return IPC_OK();
 }
 
+void
+WebRenderBridgeChild::BeginClearCachedResources()
+{
+  mIsInClearCachedResources = true;
+  SendClearCachedResources();
+}
+
+void
+WebRenderBridgeChild::EndClearCachedResources()
+{
+  ProcessWebRenderParentCommands();
+  mIsInClearCachedResources = false;
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -105,16 +105,19 @@ public:
                   gfx::ScaledFont* aFont, const StackingContextHelper& aSc,
                   const LayerRect& aBounds, const LayerRect& aClip);
 
   wr::FontKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
 
   void RemoveExpiredFontKeys();
   void ClearReadLocks();
 
+  void BeginClearCachedResources();
+  void EndClearCachedResources();
+
 private:
   friend class CompositorBridgeChild;
 
   ~WebRenderBridgeChild() {}
 
   wr::ExternalImageId GetNextExternalImageId();
 
   // CompositableForwarder
@@ -157,16 +160,17 @@ private:
   bool AddOpDestroy(const OpDestroy& aOp);
 
   nsTArray<WebRenderParentCommand> mParentCommands;
   nsTArray<OpDestroy> mDestroyedActors;
   nsDataHashtable<nsUint64HashKey, CompositableClient*> mCompositables;
   nsTArray<nsTArray<ReadLockInit>> mReadLocks;
   uint64_t mReadLockSequenceNumber;
   bool mIsInTransaction;
+  bool mIsInClearCachedResources;
   uint32_t mIdNamespace;
   uint32_t mResourceId;
   wr::PipelineId mPipelineId;
 
   bool mIPCOpen;
   bool mDestroyed;
 
   uint32_t mFontKeysDeleted;
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -22,19 +22,25 @@
 #include "mozilla/webrender/WebRenderTypes.h"
 
 namespace mozilla {
 namespace layers {
 
 WebRenderCanvasLayer::~WebRenderCanvasLayer()
 {
   MOZ_COUNT_DTOR(WebRenderCanvasLayer);
+  ClearWrResources();
+}
 
+void
+WebRenderCanvasLayer::ClearWrResources()
+{
   if (mExternalImageId.isSome()) {
     WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+    mExternalImageId = Nothing();
   }
 }
 
 void
 WebRenderCanvasLayer::Initialize(const Data& aData)
 {
   ShareableCanvasLayer::Initialize(aData);
 
@@ -92,10 +98,22 @@ WebRenderCanvasLayer::AttachCompositable
 }
 
 CompositableForwarder*
 WebRenderCanvasLayer::GetForwarder()
 {
   return WrManager()->WrBridge();
 }
 
+void
+WebRenderCanvasLayer::ClearCachedResources()
+{
+  ClearWrResources();
+  if (mBufferProvider) {
+    mBufferProvider->ClearCachedResources();
+  }
+  if (mCanvasClient) {
+    mCanvasClient->Clear();
+  }
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderCanvasLayer.h
+++ b/gfx/layers/wr/WebRenderCanvasLayer.h
@@ -28,19 +28,23 @@ public:
   }
 
   virtual void Initialize(const Data& aData) override;
 
   virtual CompositableForwarder* GetForwarder() override;
 
   virtual void AttachCompositable() override;
 
+  virtual void ClearCachedResources() override;
+
 protected:
   virtual ~WebRenderCanvasLayer();
 
+  void ClearWrResources();
+
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder,
                    const StackingContextHelper& aSc) override;
 
 protected:
   wr::MaybeExternalImageId mExternalImageId;
 };
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -27,26 +27,33 @@ WebRenderImageLayer::WebRenderImageLayer
   , mImageClientContainerType(CompositableType::UNKNOWN)
 {
   MOZ_COUNT_CTOR(WebRenderImageLayer);
 }
 
 WebRenderImageLayer::~WebRenderImageLayer()
 {
   MOZ_COUNT_DTOR(WebRenderImageLayer);
+  ClearWrResources();
+}
 
+void
+WebRenderImageLayer::ClearWrResources()
+{
   if (mKey.isSome()) {
     WrManager()->AddImageKeyForDiscard(mKey.value());
+    mKey = Nothing();
   }
-
   if (mExternalImageId.isSome()) {
     WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+    mExternalImageId = Nothing();
   }
   if (mPipelineId.isSome()) {
     WrBridge()->RemovePipelineIdForAsyncCompositable(mPipelineId.ref());
+    mPipelineId = Nothing();
   }
 }
 
 CompositableType
 WebRenderImageLayer::GetImageClientType()
 {
   if (mImageClientContainerType != CompositableType::UNKNOWN) {
     return mImageClientContainerType;
@@ -80,16 +87,17 @@ WebRenderImageLayer::GetAsSourceSurface(
     return nullptr;
   }
   return surface.forget();
 }
 
 void
 WebRenderImageLayer::ClearCachedResources()
 {
+  ClearWrResources();
   if (mImageClient) {
     mImageClient->ClearCachedResources();
   }
 }
 
 bool
 WebRenderImageLayer::SupportsAsyncUpdate()
 {
--- a/gfx/layers/wr/WebRenderImageLayer.h
+++ b/gfx/layers/wr/WebRenderImageLayer.h
@@ -33,16 +33,17 @@ public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder,
                    const StackingContextHelper& aSc) override;
   Maybe<WrImageMask> RenderMaskLayer(const StackingContextHelper& aSc,
                                      const gfx::Matrix4x4& aTransform) override;
 
 protected:
   CompositableType GetImageClientType();
+  void ClearWrResources();
 
   void AddWRVideoImage(size_t aChannelNumber);
 
   wr::MaybeExternalImageId mExternalImageId;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
   CompositableType mImageClientContainerType;
   Maybe<wr::PipelineId> mPipelineId;
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -741,31 +741,35 @@ WebRenderLayerManager::DidComposite(uint
     mDidCompositeObservers[i]->DidComposite();
   }
 }
 
 void
 WebRenderLayerManager::ClearLayer(Layer* aLayer)
 {
   aLayer->ClearCachedResources();
+  if (aLayer->GetMaskLayer()) {
+    aLayer->GetMaskLayer()->ClearCachedResources();
+  }
   for (Layer* child = aLayer->GetFirstChild(); child;
        child = child->GetNextSibling()) {
     ClearLayer(child);
   }
 }
 
 void
 WebRenderLayerManager::ClearCachedResources(Layer* aSubtree)
 {
-  WrBridge()->SendClearCachedResources();
+  WrBridge()->BeginClearCachedResources();
   if (aSubtree) {
     ClearLayer(aSubtree);
   } else if (mRoot) {
     ClearLayer(mRoot);
   }
+  WrBridge()->EndClearCachedResources();
 }
 
 void
 WebRenderLayerManager::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier,
                                                       uint64_t aDeviceResetSeqNo)
 {
   WrBridge()->IdentifyTextureHost(aNewIdentifier);
 }
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -158,10 +158,34 @@ WebRenderPaintedLayer::RenderLayer(wr::D
     // We have an empty transaction, just reuse the old image we had before.
     MOZ_ASSERT(mExternalImageId);
     MOZ_ASSERT(mImageContainer->HasCurrentImage());
   }
 
   CreateWebRenderDisplayList(aBuilder, aSc);
 }
 
+void
+WebRenderPaintedLayer::ClearCachedResources()
+{
+  ClearWrResources();
+  if (mImageClient) {
+    mImageClient->FlushAllImages();
+    mImageClient->ClearCachedResources();
+  }
+  if (mImageContainer) {
+    mImageContainer->ClearAllImages();
+    mImageContainer->ClearCachedResources();
+  }
+  ClearValidRegion();
+}
+
+void
+WebRenderPaintedLayer::ClearWrResources()
+{
+  if (mExternalImageId.isSome()) {
+    WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+    mExternalImageId = Nothing();
+  }
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderPaintedLayer.h
+++ b/gfx/layers/wr/WebRenderPaintedLayer.h
@@ -27,39 +27,40 @@ public:
   {
     MOZ_COUNT_CTOR(WebRenderPaintedLayer);
   }
 
 protected:
   virtual ~WebRenderPaintedLayer()
   {
     MOZ_COUNT_DTOR(WebRenderPaintedLayer);
-    if (mExternalImageId.isSome()) {
-      WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
-    }
+    ClearWrResources();
   }
 
   wr::MaybeExternalImageId mExternalImageId;
   LayerIntRect mPaintedRect;
 public:
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     mInvalidRegion.Add(aRegion);
     UpdateValidRegionAfterInvalidRegionChanged();
   }
 
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder,
                    const StackingContextHelper& aSc) override;
+  virtual void ClearCachedResources() override;
+
   RefPtr<ImageContainer> mImageContainer;
   RefPtr<ImageClient> mImageClient;
 
 private:
   bool SetupExternalImages();
   bool UpdateImageClient();
   void CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
                                   const StackingContextHelper& aSc);
+  void ClearWrResources();
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERPAINTEDLAYER_H
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.h
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.h
@@ -27,33 +27,42 @@ public:
   {
     MOZ_COUNT_CTOR(WebRenderPaintedLayerBlob);
   }
 
 protected:
   virtual ~WebRenderPaintedLayerBlob()
   {
     MOZ_COUNT_DTOR(WebRenderPaintedLayerBlob);
+    ClearWrResources();
+  }
+  void ClearWrResources()
+  {
     if (mExternalImageId.isSome()) {
       WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+      mExternalImageId = Nothing();
     }
     if (mImageKey.isSome()) {
       WrManager()->AddImageKeyForDiscard(mImageKey.value());
+      mImageKey = Nothing();
     }
   }
 
   wr::MaybeExternalImageId mExternalImageId;
 
 public:
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     mInvalidRegion.Add(aRegion);
     UpdateValidRegionAfterInvalidRegionChanged();
   }
-
+  virtual void ClearCachedResources() override
+  {
+    ClearWrResources();
+  }
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder,
                    const StackingContextHelper& aSc) override;
 private:
   Maybe<WrImageKey> mImageKey;
   LayerIntRect mImageBounds;
 };