Bug 737437 - Destroy the compositor's layer manager before the CompositorChild gets destroyed. r=cjones
☠☠ backed out by 5016d3f2b36d ☠ ☠
authorAli Juma <ajuma@mozilla.com>
Thu, 29 Mar 2012 09:59:22 -0400
changeset 90624 7bffc102114e6ada087d5a6abfd0f0c1a88100f6
parent 90623 1001d5a9f57a4b92d7dba13e13ecc04442f47ef4
child 90625 3e6a7f9fb34e265380c1905b7677684eff876bf6
push id22370
push userbmo@edmorley.co.uk
push dateFri, 30 Mar 2012 15:14:13 +0000
treeherdermozilla-central@0cfa44a13b25 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs737437
milestone14.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 737437 - Destroy the compositor's layer manager before the CompositorChild gets destroyed. r=cjones
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/PCompositor.ipdl
widget/xpwidgets/nsBaseWidget.cpp
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -73,24 +73,34 @@ CompositorParent::~CompositorParent()
 }
 
 void
 CompositorParent::Destroy()
 {
   NS_ABORT_IF_FALSE(ManagedPLayersParent().Length() == 0,
                     "CompositorParent destroyed before managed PLayersParent");
 
-  // Ensure that the layer manager is destroyed on the compositor thread.
+  // Ensure that the layer manager is destructed on the compositor thread.
   mLayerManager = NULL;
 }
 
 bool
+CompositorParent::RecvWillStop()
+{
+  mPaused = true;
+
+  // Ensure that the layer manager is destroyed before CompositorChild.
+  mLayerManager->Destroy();
+
+  return true;
+}
+
+bool
 CompositorParent::RecvStop()
 {
-  mPaused = true;
   Destroy();
   return true;
 }
 
 bool
 CompositorParent::RecvPause()
 {
   PauseComposition();
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -88,16 +88,17 @@ struct ViewTransform {
 class CompositorParent : public PCompositorParent,
                          public ShadowLayersManager
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorParent)
 public:
   CompositorParent(nsIWidget* aWidget, base::Thread* aCompositorThread);
   virtual ~CompositorParent();
 
+  virtual bool RecvWillStop() MOZ_OVERRIDE;
   virtual bool RecvStop() MOZ_OVERRIDE;
   virtual bool RecvPause() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
 
   virtual void ShadowLayersUpdated(bool isFirstPaint) MOZ_OVERRIDE;
   void Destroy();
 
   LayerManager* GetLayerManager() { return mLayerManager; }
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -56,17 +56,20 @@ namespace layers {
 // for Bug 716631.
 rpc protocol PCompositor
 {
   // A Compositor manages a single Layer Manager (PLayers)
   manages PLayers;
 
 parent:  
 
-  // Clean up in preparation for destruction.
+  // The child is about to be destroyed, so perform any necessary cleanup.
+  sync WillStop();
+
+  // Clean up in preparation for own destruction.
   sync Stop();
 
   // Pause/resume the compositor. These are intended to be used on mobile, when
   // the compositor needs to pause/resume in lockstep with the application.
   sync Pause();
   sync Resume();
 
   sync PLayers(LayersBackend backend);
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -148,16 +148,18 @@ nsBaseWidget::~nsBaseWidget()
   }
 
   if (mLayerManager) {
     mLayerManager->Destroy();
     mLayerManager = nsnull;
   }
 
   if (mCompositorChild) {
+    mCompositorChild->SendWillStop();
+    MessageLoop::current()->RunAllPending();
     mCompositorChild->Destroy();
     delete mCompositorThread;
   }
 
 #ifdef NOISY_WIDGET_LEAKS
   gNumWidgets--;
   printf("WIDGETS- = %d\n", gNumWidgets);
 #endif