Bug 1482109 - Hook the memory pressure observer up with WebRender. r=sotaro
authorNicolas Silva <nsilva@mozilla.com>
Mon, 20 Aug 2018 15:23:54 +0200
changeset 432446 202fb9c610d07d734245e8b621eda8f80e3d2250
parent 432445 68bff34cbddd1703e706bce5124c4c358352702a
child 432447 2a42fd4df1bb5ef0b16baf1782016c47abd1af60
push id34476
push userncsoregi@mozilla.com
push dateMon, 20 Aug 2018 22:00:28 +0000
treeherdermozilla-central@d0d2e0f4b33c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro
bugs1482109
milestone63.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 1482109 - Hook the memory pressure observer up with WebRender. r=sotaro
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/CompositorManagerParent.cpp
gfx/layers/ipc/CompositorManagerParent.h
gfx/layers/ipc/PCompositorManager.ipdl
gfx/thebes/gfxPlatform.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1907,16 +1907,27 @@ CompositorBridgeParent::DeallocPWebRende
     if (it != sIndirectLayerTrees.end()) {
       it->second.mWrBridge = nullptr;
     }
   }
   parent->Release(); // IPDL reference
   return true;
 }
 
+void
+CompositorBridgeParent::NotifyMemoryPressure()
+{
+  if (mWrBridge) {
+    RefPtr<wr::WebRenderAPI> api = mWrBridge->GetWebRenderAPI();
+    if (api) {
+      api->NotifyMemoryPressure();
+    }
+  }
+}
+
 RefPtr<WebRenderBridgeParent>
 CompositorBridgeParent::GetWebRenderBridgeParent() const
 {
   return mWrBridge;
 }
 
 Maybe<TimeStamp>
 CompositorBridgeParent::GetTestingTimeStamp() const
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -170,16 +170,18 @@ public:
   virtual bool IsRemote() const {
     return false;
   }
 
   virtual void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr) {
     MOZ_CRASH();
   }
 
+  virtual void NotifyMemoryPressure() {}
+
 protected:
   ~CompositorBridgeParentBase() override;
 
   bool mCanSend;
 
 private:
   RefPtr<CompositorManagerParent> mCompositorManager;
 };
@@ -231,16 +233,18 @@ public:
   mozilla::ipc::IPCResult RecvCheckContentOnlyTDR(const uint32_t& sequenceNum, bool* isContentOnlyTDR) override { return IPC_OK(); }
 
   // Unused for chrome <-> compositor communication (which this class does).
   // @see CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint
   mozilla::ipc::IPCResult RecvRequestNotifyAfterRemotePaint() override { return IPC_OK(); };
 
   mozilla::ipc::IPCResult RecvAllPluginsCaptured() override;
 
+  virtual void NotifyMemoryPressure() override;
+
   void ActorDestroy(ActorDestroyReason why) override;
 
   void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
                            const TransactionInfo& aInfo,
                            bool aHitTestUpdate) override;
   void ScheduleComposite(LayerTransactionParent* aLayerTree) override;
   bool SetTestSampleTime(const LayersId& aId,
                          const TimeStamp& aTime) override;
--- a/gfx/layers/ipc/CompositorManagerParent.cpp
+++ b/gfx/layers/ipc/CompositorManagerParent.cpp
@@ -283,10 +283,21 @@ CompositorManagerParent::RecvAddSharedSu
 
 mozilla::ipc::IPCResult
 CompositorManagerParent::RecvRemoveSharedSurface(const wr::ExternalImageId& aId)
 {
   SharedSurfacesParent::Remove(aId);
   return IPC_OK();
 }
 
+mozilla::ipc::IPCResult
+CompositorManagerParent::RecvNotifyMemoryPressure()
+{
+  nsTArray<PCompositorBridgeParent*> compositorBridges;
+  ManagedPCompositorBridgeParent(compositorBridges);
+  for (auto bridge : compositorBridges) {
+    static_cast<CompositorBridgeParentBase*>(bridge)->NotifyMemoryPressure();
+  }
+  return IPC_OK();
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/CompositorManagerParent.h
+++ b/gfx/layers/ipc/CompositorManagerParent.h
@@ -39,16 +39,18 @@ public:
                                           const CompositorOptions& aOptions,
                                           bool aUseExternalSurfaceSize,
                                           const gfx::IntSize& aSurfaceSize);
 
   mozilla::ipc::IPCResult RecvAddSharedSurface(const wr::ExternalImageId& aId,
                                                const SurfaceDescriptorShared& aDesc) override;
   mozilla::ipc::IPCResult RecvRemoveSharedSurface(const wr::ExternalImageId& aId) override;
 
+  virtual mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
+
   void BindComplete();
   void ActorDestroy(ActorDestroyReason aReason) override;
 
   bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;
   PCompositorBridgeParent* AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt) override;
 
 private:
   static StaticRefPtr<CompositorManagerParent> sInstance;
--- a/gfx/layers/ipc/PCompositorManager.ipdl
+++ b/gfx/layers/ipc/PCompositorManager.ipdl
@@ -70,12 +70,14 @@ parent:
    * - A "same process widget" PCompositorBridge is requested by the combined
    *   GPU/UI process for each "top level browser window" as above.
    * See gfx/layers/ipc/PCompositorBridge.ipdl for more details.
    */
   async PCompositorBridge(CompositorBridgeOptions options);
 
   async AddSharedSurface(ExternalImageId aId, SurfaceDescriptorShared aDesc);
   async RemoveSharedSurface(ExternalImageId aId);
+
+  async NotifyMemoryPressure();
 };
 
 } // layers
 } // mozilla
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -466,16 +466,22 @@ FontPrefChanged(const char* aPref, void*
 
 void
 gfxPlatform::OnMemoryPressure(layers::MemoryPressureReason aWhy)
 {
     Factory::PurgeAllCaches();
     gfxGradientCache::PurgeAllCaches();
     PurgeSkiaFontCache();
     PurgeSkiaGPUCache();
+    if (XRE_IsParentProcess()) {
+      layers::CompositorManagerChild* manager = CompositorManagerChild::GetInstance();
+      if (manager) {
+        manager->SendNotifyMemoryPressure();
+      }
+    }
 }
 
 gfxPlatform::gfxPlatform()
   : mHasVariationFontSupport(false)
   , mAzureCanvasBackendCollector(this, &gfxPlatform::GetAzureBackendInfo)
   , mApzSupportCollector(this, &gfxPlatform::GetApzSupportInfo)
   , mTilesInfoCollector(this, &gfxPlatform::GetTilesSupportInfo)
   , mCompositorBackend(layers::LayersBackend::LAYERS_NONE)
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -498,16 +498,22 @@ WebRenderAPI::Resume()
     // implies that all frame data have been processed when the renderer runs this event.
     RunOnRenderThread(std::move(event));
 
     task.Wait();
     return result;
 }
 
 void
+WebRenderAPI::NotifyMemoryPressure()
+{
+  wr_api_notify_memory_pressure(mDocHandle);
+}
+
+void
 WebRenderAPI::WakeSceneBuilder()
 {
     wr_api_wake_scene_builder(mDocHandle);
 }
 
 void
 WebRenderAPI::FlushSceneBuilder()
 {
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -201,16 +201,18 @@ public:
   void ClearAllCaches();
 
   void Pause();
   bool Resume();
 
   void WakeSceneBuilder();
   void FlushSceneBuilder();
 
+  void NotifyMemoryPressure();
+
   wr::WrIdNamespace GetNamespace();
   uint32_t GetMaxTextureSize() const { return mMaxTextureSize; }
   bool GetUseANGLE() const { return mUseANGLE; }
   bool GetUseDComp() const { return mUseDComp; }
   layers::SyncHandle GetSyncHandle() const { return mSyncHandle; }
 
   void Capture();
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1024,16 +1024,21 @@ pub unsafe extern "C" fn wr_api_delete(d
 }
 
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_shut_down(dh: &mut DocumentHandle) {
     dh.api.shut_down();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn wr_api_notify_memory_pressure(dh: &mut DocumentHandle) {
+    dh.api.notify_memory_pressure();
+}
+
 /// cbindgen:postfix=WR_DESTRUCTOR_SAFE_FUNC
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_clear_all_caches(dh: &mut DocumentHandle) {
     dh.api.send_debug_cmd(DebugCommand::ClearCaches(ClearCache::all()));
 }
 
 fn make_transaction(do_async: bool) -> Transaction {
     let mut transaction = Transaction::new();
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1093,16 +1093,20 @@ WR_INLINE
 bool wr_api_hit_test(DocumentHandle *aDh,
                      WorldPoint aPoint,
                      WrPipelineId *aOutPipelineId,
                      uint64_t *aOutScrollId,
                      uint16_t *aOutHitInfo)
 WR_FUNC;
 
 WR_INLINE
+void wr_api_notify_memory_pressure(DocumentHandle *aDh)
+WR_FUNC;
+
+WR_INLINE
 void wr_api_send_external_event(DocumentHandle *aDh,
                                 uintptr_t aEvt)
 WR_DESTRUCTOR_SAFE_FUNC;
 
 WR_INLINE
 void wr_api_send_transaction(DocumentHandle *aDh,
                              Transaction *aTransaction,
                              bool aIsAsync)