Bug 1491442 - Add CompositorWidget::DoCompositorCleanup() to give the widget a chance to clean up any state from PreRender/PostRender on the correct thread. r=mattwoodrow
authorMarkus Stange <mstange@themasta.com>
Fri, 16 Aug 2019 01:09:26 +0000
changeset 488400 38705780d7f8cb91622359df841cf2549529c445
parent 488399 fb949ba38402edbe1decc678c5a8ee65f446a5a5
child 488401 9dcce9060dac1eb0dd77b46433eb27d576311ca5
push id113908
push userccoroiu@mozilla.com
push dateFri, 16 Aug 2019 09:57:53 +0000
treeherdermozilla-inbound@83fad6abe38a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1491442
milestone70.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 1491442 - Add CompositorWidget::DoCompositorCleanup() to give the widget a chance to clean up any state from PreRender/PostRender on the correct thread. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D40514
gfx/layers/Compositor.cpp
gfx/layers/Compositor.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/webrender_bindings/RendererOGL.cpp
widget/CompositorWidget.h
widget/InProcessCompositorWidget.cpp
widget/InProcessCompositorWidget.h
widget/nsBaseWidget.h
--- a/gfx/layers/Compositor.cpp
+++ b/gfx/layers/Compositor.cpp
@@ -71,16 +71,19 @@ Compositor::Compositor(widget::Composito
       mClearColor(0.0, 0.0, 0.0, 0.0),
       mDefaultClearColor(0.0, 0.0, 0.0, 0.0)
 #endif
 {
 }
 
 Compositor::~Compositor() { ReadUnlockTextures(); }
 
+// Called just before DetachWidget.
+void Compositor::DoWidgetCleanup() { mWidget->DoCompositorCleanup(); }
+
 void Compositor::Destroy() {
   TextureSourceProvider::Destroy();
   mIsDestroyed = true;
 }
 
 void Compositor::EndFrame() {
   ReadUnlockTextures();
   mLastCompositionEndTime = TimeStamp::Now();
--- a/gfx/layers/Compositor.h
+++ b/gfx/layers/Compositor.h
@@ -185,16 +185,17 @@ class Compositor : public TextureSourceP
  public:
   explicit Compositor(widget::CompositorWidget* aWidget,
                       CompositorBridgeParent* aParent = nullptr);
 
   virtual bool Initialize(nsCString* const out_failureReason) = 0;
   void Destroy() override;
   bool IsDestroyed() const { return mIsDestroyed; }
 
+  virtual void DoWidgetCleanup();
   virtual void DetachWidget() { mWidget = nullptr; }
 
   /**
    * Request a texture host identifier that may be used for creating textures
    * across process or thread boundaries that are compatible with this
    * compositor.
    */
   virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() = 0;
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -494,16 +494,17 @@ void CompositorBridgeParent::StopAndClea
     if (mAsyncImageManager) {
       mAsyncImageManager->Destroy();
       // WebRenderAPI should be already destructed
       mAsyncImageManager = nullptr;
     }
   }
 
   if (mCompositor) {
+    mCompositor->DoWidgetCleanup();
     mCompositor->DetachWidget();
     mCompositor->Destroy();
     mCompositor = nullptr;
   }
 
   // This must be destroyed now since it accesses the widget.
   if (mCompositorScheduler) {
     mCompositorScheduler->Destroy();
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -63,16 +63,17 @@ RendererOGL::RendererOGL(RefPtr<RenderTh
 RendererOGL::~RendererOGL() {
   MOZ_COUNT_DTOR(RendererOGL);
   if (!mCompositor->MakeCurrent()) {
     gfxCriticalNote
         << "Failed to make render context current during destroying.";
     // Leak resources!
     return;
   }
+  mCompositor->GetWidget()->DoCompositorCleanup();
   wr_renderer_delete(mRenderer);
 }
 
 wr::WrExternalImageHandler RendererOGL::GetExternalImageHandler() {
   return wr::WrExternalImageHandler{
       this,
   };
 }
--- a/widget/CompositorWidget.h
+++ b/widget/CompositorWidget.h
@@ -112,16 +112,23 @@ class CompositorWidget {
    * cancelled by a negative return value from PreRender.
    *
    * Always called from the compositing thread, which may be the main-thread if
    * OMTC is not enabled.
    */
   virtual void PostRender(WidgetRenderingContext* aContext) {}
 
   /**
+   * Called on the same thread as PreRender/PostRender during destruction.
+   * This method gives the widget a chance to do any cleanup for state that it
+   * created during PreRender / PostRender.
+   */
+  virtual void DoCompositorCleanup() {}
+
+  /**
    * Called before the LayerManager draws the layer tree.
    *
    * Always called from the compositing thread.
    */
   virtual void DrawWindowUnderlay(WidgetRenderingContext* aContext,
                                   LayoutDeviceIntRect aRect) {}
 
   /**
--- a/widget/InProcessCompositorWidget.cpp
+++ b/widget/InProcessCompositorWidget.cpp
@@ -39,16 +39,20 @@ InProcessCompositorWidget::InProcessComp
 bool InProcessCompositorWidget::PreRender(WidgetRenderingContext* aContext) {
   return mWidget->PreRender(aContext);
 }
 
 void InProcessCompositorWidget::PostRender(WidgetRenderingContext* aContext) {
   mWidget->PostRender(aContext);
 }
 
+void InProcessCompositorWidget::DoCompositorCleanup() {
+  mWidget->DoCompositorCleanup();
+}
+
 void InProcessCompositorWidget::DrawWindowUnderlay(
     WidgetRenderingContext* aContext, LayoutDeviceIntRect aRect) {
   mWidget->DrawWindowUnderlay(aContext, aRect);
 }
 
 void InProcessCompositorWidget::DrawWindowOverlay(
     WidgetRenderingContext* aContext, LayoutDeviceIntRect aRect) {
   mWidget->DrawWindowOverlay(aContext, aRect);
--- a/widget/InProcessCompositorWidget.h
+++ b/widget/InProcessCompositorWidget.h
@@ -14,16 +14,17 @@ namespace widget {
 // nsBaseWidget.
 class InProcessCompositorWidget : public CompositorWidget {
  public:
   explicit InProcessCompositorWidget(const layers::CompositorOptions& aOptions,
                                      nsBaseWidget* aWidget);
 
   virtual bool PreRender(WidgetRenderingContext* aManager) override;
   virtual void PostRender(WidgetRenderingContext* aManager) override;
+  virtual void DoCompositorCleanup() override;
   virtual void DrawWindowUnderlay(WidgetRenderingContext* aContext,
                                   LayoutDeviceIntRect aRect) override;
   virtual void DrawWindowOverlay(WidgetRenderingContext* aContext,
                                  LayoutDeviceIntRect aRect) override;
   virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawing() override;
   virtual already_AddRefed<gfx::DrawTarget> StartRemoteDrawingInRegion(
       LayoutDeviceIntRegion& aInvalidRegion,
       layers::BufferMode* aBufferMode) override;
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -443,16 +443,17 @@ class nsBaseWidget : public nsIWidget, p
  protected:
   // These are methods for CompositorWidgetWrapper, and should only be
   // accessed from that class. Derived widgets can choose which methods to
   // implement, or none if supporting out-of-process compositing.
   virtual bool PreRender(mozilla::widget::WidgetRenderingContext* aContext) {
     return true;
   }
   virtual void PostRender(mozilla::widget::WidgetRenderingContext* aContext) {}
+  virtual void DoCompositorCleanup() {}
   virtual void DrawWindowUnderlay(
       mozilla::widget::WidgetRenderingContext* aContext,
       LayoutDeviceIntRect aRect) {}
   virtual void DrawWindowOverlay(
       mozilla::widget::WidgetRenderingContext* aContext,
       LayoutDeviceIntRect aRect) {}
   virtual already_AddRefed<DrawTarget> StartRemoteDrawing();
   virtual already_AddRefed<DrawTarget> StartRemoteDrawingInRegion(