Bug 1404232 - Add WebRenderCommandBuilder::ClearCachedResources() r=jrmuizel
authorsotaro <sotaro.ikeda.g@gmail.com>
Thu, 19 Oct 2017 13:03:08 +0900
changeset 387094 a88fa8d0eaa0b8c908f8ab0d2923da526b787e9f
parent 387093 fef60dc3adecc4378456e6e73bb60eca28de9921
child 387095 4212d0d0ca7762e8821d5912e5f987ffa4c2d595
push id32709
push userarchaeopteryx@coole-files.de
push dateThu, 19 Oct 2017 09:27:00 +0000
treeherdermozilla-central@87e3813e7939 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1404232
milestone58.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 1404232 - Add WebRenderCommandBuilder::ClearCachedResources() r=jrmuizel
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderCommandBuilder.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderUserData.cpp
gfx/layers/wr/WebRenderUserData.h
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -487,17 +487,17 @@ WebRenderCommandBuilder::GenerateFallbac
       if (!lastBounds.IsEqualInterior(clippedBounds)) {
         invalidRegion.OrWith(lastBounds);
         invalidRegion.OrWith(clippedBounds);
       }
     }
     needPaint = !invalidRegion.IsEmpty();
   }
 
-  if (needPaint) {
+  if (needPaint || !fallbackData->GetKey()) {
     gfx::SurfaceFormat format = aItem->GetType() == DisplayItemType::TYPE_MASK ?
                                                       gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
     if (gfxPrefs::WebRenderBlobImages()) {
       bool snapped;
       bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
 
       RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
       RefPtr<gfx::DrawTarget> dummyDt =
@@ -633,10 +633,19 @@ WebRenderCommandBuilder::RemoveUnusedAnd
       iter.Remove();
       continue;
     }
 
     data->SetUsed(false);
   }
 }
 
+void
+WebRenderCommandBuilder::ClearCachedResources()
+{
+  for (auto iter = mWebRenderUserDatas.Iter(); !iter.Done(); iter.Next()) {
+    WebRenderUserData* data = iter.Get()->GetKey();
+    data->ClearCachedResources();
+  }
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderCommandBuilder.h
+++ b/gfx/layers/wr/WebRenderCommandBuilder.h
@@ -89,16 +89,17 @@ public:
   already_AddRefed<WebRenderFallbackData> GenerateFallbackData(nsDisplayItem* aItem,
                                                                wr::DisplayListBuilder& aBuilder,
                                                                wr::IpcResourceUpdateQueue& aResources,
                                                                const StackingContextHelper& aSc,
                                                                nsDisplayListBuilder* aDisplayListBuilder,
                                                                LayerRect& aImageRect);
 
   void RemoveUnusedAndResetWebRenderUserData();
+  void ClearCachedResources();
 
   // Those are data that we kept between transactions. We used to cache some
   // data in the layer. But in layers free mode, we don't have layer which
   // means we need some other place to cached the data between transaction.
   // We store the data in frame's property.
   template<class T> already_AddRefed<T>
   CreateOrRecycleWebRenderUserData(nsDisplayItem* aItem,
                                    bool* aOutIsRecycled = nullptr)
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -535,17 +535,18 @@ WebRenderLayerManager::ClearCachedResour
   WrBridge()->BeginClearCachedResources();
   DiscardImages();
   WrBridge()->EndClearCachedResources();
 }
 
 void
 WebRenderLayerManager::WrUpdated()
 {
-  // Handle removing all obsoleted WebRenderUserData
+  mWebRenderCommandBuilder.ClearCachedResources();
+  DiscardLocalImages();
 }
 
 void
 WebRenderLayerManager::UpdateTextureFactoryIdentifier(const TextureFactoryIdentifier& aNewIdentifier,
                                                       uint64_t aDeviceResetSeqNo)
 {
   WrBridge()->IdentifyTextureHost(aNewIdentifier);
 }
--- a/gfx/layers/wr/WebRenderUserData.cpp
+++ b/gfx/layers/wr/WebRenderUserData.cpp
@@ -49,26 +49,35 @@ WebRenderUserData::WrBridge() const
 
 WebRenderImageData::WebRenderImageData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
   : WebRenderUserData(aWRManager, aItem)
 {
 }
 
 WebRenderImageData::~WebRenderImageData()
 {
+  ClearCachedResources();
+}
+
+void
+WebRenderImageData::ClearCachedResources()
+{
   if (mKey) {
     mWRManager->AddImageKeyForDiscard(mKey.value());
+    mKey.reset();
   }
 
   if (mExternalImageId) {
     WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
+    mExternalImageId.reset();
   }
 
   if (mPipelineId) {
     WrBridge()->RemovePipelineIdForCompositable(mPipelineId.ref());
+    mPipelineId.reset();
   }
 }
 
 Maybe<wr::ImageKey>
 WebRenderImageData::UpdateImageKey(ImageContainer* aContainer,
                                    wr::IpcResourceUpdateQueue& aResources,
                                    bool aForceUpdate)
 {
@@ -230,16 +239,25 @@ WebRenderAnimationData::~WebRenderAnimat
 
 WebRenderCanvasData::WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem)
   : WebRenderUserData(aWRManager, aItem)
 {
 }
 
 WebRenderCanvasData::~WebRenderCanvasData()
 {
+  ClearCachedResources();
+}
+
+void
+WebRenderCanvasData::ClearCachedResources()
+{
+  if (mCanvasRenderer) {
+    mCanvasRenderer->ClearCachedResources();
+  }
 }
 
 WebRenderCanvasRendererAsync*
 WebRenderCanvasData::GetCanvasRenderer()
 {
   if (!mCanvasRenderer) {
     mCanvasRenderer = MakeUnique<WebRenderCanvasRendererAsync>(mWRManager);
   }
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -51,17 +51,17 @@ public:
 
   virtual UserDataType GetType() = 0;
   bool IsDataValid(WebRenderLayerManager* aManager);
   bool IsUsed() { return mUsed; }
   void SetUsed(bool aUsed) { mUsed = aUsed; }
   nsIFrame* GetFrame() { return mFrame; }
   uint32_t GetDisplayItemKey() { return mDisplayItemKey; }
   void RemoveFromTable();
-
+  virtual void ClearCachedResources() {};
 protected:
   virtual ~WebRenderUserData();
 
   WebRenderBridgeChild* WrBridge() const;
 
   RefPtr<WebRenderLayerManager> mWRManager;
   nsIFrame* mFrame;
   uint32_t mDisplayItemKey;
@@ -93,17 +93,17 @@ public:
                                          const LayerRect& aSCBounds,
                                          const gfx::Matrix4x4& aSCTransform,
                                          const gfx::MaybeIntSize& aScaleToSize,
                                          const wr::ImageRendering& aFilter,
                                          const wr::MixBlendMode& aMixBlendMode,
                                          bool aIsBackfaceVisible);
 
   void CreateImageClientIfNeeded();
-
+  void ClearCachedResources() override;
 protected:
   void CreateExternalImageIfNeeded();
 
   wr::MaybeExternalImageId mExternalImageId;
   Maybe<wr::ImageKey> mKey;
   RefPtr<ImageClient> mImageClient;
   Maybe<wr::PipelineId> mPipelineId;
   RefPtr<ImageContainer> mContainer;
@@ -155,17 +155,17 @@ public:
   explicit WebRenderCanvasData(WebRenderLayerManager* aWRManager, nsDisplayItem* aItem);
   virtual ~WebRenderCanvasData();
 
   virtual WebRenderCanvasData* AsCanvasData() override { return this; }
   virtual UserDataType GetType() override { return UserDataType::eCanvas; }
   static UserDataType Type() { return UserDataType::eCanvas; }
 
   WebRenderCanvasRendererAsync* GetCanvasRenderer();
-
+  void ClearCachedResources() override;
 protected:
   UniquePtr<WebRenderCanvasRendererAsync> mCanvasRenderer;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif /* GFX_WEBRENDERUSERDATA_H */