Clean up Compositor destruction.
authorAli Juma <ajuma@mozilla.com>
Thu, 22 Dec 2011 10:59:53 -0500
changeset 92340 9a06644c9e86779eef3f211aa92f508c235c17bf
parent 92339 0d11124ed86e1d75d9404a94588cc524ddd21aa8
child 92341 bf899571b52b4249f6c382d09211ad69a947035b
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone11.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
Clean up Compositor destruction.
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/ipc/ShadowLayersParent.h
widget/src/xpwidgets/nsBaseWidget.cpp
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -62,16 +62,25 @@ CompositorChild::~CompositorChild()
 {
   MOZ_COUNT_DTOR(CompositorChild);
 }
 
 void
 CompositorChild::Destroy()
 {
   mLayerManager = NULL;
+  size_t numChildren = ManagedPLayersChild().Length();
+  NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
+                    "compositor must only have 0 or 1 layer forwarder");
+
+  if (numChildren) {
+    ShadowLayersChild* layers =
+      static_cast<ShadowLayersChild*>(ManagedPLayersChild()[0]);
+    layers->Destroy();
+  }
   SendStop();
 }
 
 CompositorChild*
 CompositorChild::CreateCompositor(LayerManager *aLayerManager,
                                   CompositorParent *aCompositorParent)
 {
   Thread* compositorThread = new Thread("CompositorThread");
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -41,50 +41,71 @@
 #include "CompositorParent.h"
 #include "ShadowLayersParent.h"
 #include "LayerManagerOGL.h"
 
 namespace mozilla {
 namespace layers {
 
 CompositorParent::CompositorParent()
+  : mStopped(false)
 {
 
   MOZ_COUNT_CTOR(CompositorParent);
 }
 
 CompositorParent::~CompositorParent()
 {
   MOZ_COUNT_DTOR(CompositorParent);
 }
 
+void
+CompositorParent::Destroy()
+{
+  size_t numChildren = ManagedPLayersParent().Length();
+  NS_ABORT_IF_FALSE(0 == numChildren || 1 == numChildren,
+                    "compositor must only have 0 or 1 layer manager");
+
+  if (numChildren) {
+    ShadowLayersParent* layers =
+      static_cast<ShadowLayersParent*>(ManagedPLayersParent()[0]);
+    layers->Destroy();
+  }
+}
+
 bool
 CompositorParent::RecvInit()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
   return true;
 }
 
 bool
 CompositorParent::RecvStop()
 {
+  mStopped = true;
+  Destroy();
   return true;
 }
 
 void
 CompositorParent::RequestComposition()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
 }
 
 void
 CompositorParent::Composite()
 {
+  if (mStopped) {
+    return;
+  }
+
   if (!mLayerManager) {
     CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
     MessageLoop::current()->PostDelayedTask(FROM_HERE, composeTask, 10);
     return;
   }
 
   mLayerManager->EndEmptyTransaction();
 }
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -61,25 +61,28 @@ public:
   bool RecvInit();
   bool RecvStop();
 
   void RequestComposition();
 
   virtual mozilla::layout::RenderFrameParent* GetRenderFrameParent() { return NULL; }
   virtual CompositorParent* GetCompositorParent() { return this; }
 
+  void Destroy();
+
 protected:
   virtual PLayersParent* AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget);
 
   virtual bool DeallocPLayers(PLayersParent* aLayers);
 
 private:
   void Composite();
 
   nsRefPtr<LayerManager> mLayerManager;
+  bool mStopped;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
 
 } // layers
 } // mozilla
 
 #endif // mozilla_layers_CompositorParent_h
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -139,17 +139,16 @@ void
 ShadowLayersParent::Destroy()
 {
   mDestroyed = true;
   for (size_t i = 0; i < ManagedPLayerParent().Length(); ++i) {
     ShadowLayerParent* slp =
       static_cast<ShadowLayerParent*>(ManagedPLayerParent()[i]);
     slp->Destroy();
   }
-  mHost = NULL;
 }
 
 bool
 ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
                                InfallibleTArray<EditReply>* reply)
 {
   MOZ_LAYERS_LOG(("[ParentSide] received txn with %d edits", cset.Length()));
 
--- a/gfx/layers/ipc/ShadowLayersParent.h
+++ b/gfx/layers/ipc/ShadowLayersParent.h
@@ -82,17 +82,17 @@ protected:
 
   NS_OVERRIDE virtual PLayerParent* AllocPLayer();
   NS_OVERRIDE virtual bool DeallocPLayer(PLayerParent* actor);
 
 private:
   RenderFrameParent* Frame();
 
   nsRefPtr<ShadowLayerManager> mLayerManager;
-  nsRefPtr<ShadowLayersHost> mHost;
+  ShadowLayersHost* mHost;
   // Hold the root because it might be grafted under various
   // containers in the "real" layer tree
   nsRefPtr<ContainerLayer> mRoot;
   // When the widget/frame/browser stuff in this process begins its
   // destruction process, we need to Disconnect() all the currently
   // live shadow layers, because some of them might be orphaned from
   // the layer tree.  This happens in Destroy() above.  After we
   // Destroy() ourself, there's a window in which that information
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -137,23 +137,22 @@ nsBaseWidget::nsBaseWidget()
 //-------------------------------------------------------------------------
 nsBaseWidget::~nsBaseWidget()
 {
   if (mLayerManager &&
       mLayerManager->GetBackendType() == LayerManager::LAYERS_BASIC) {
     static_cast<BasicLayerManager*>(mLayerManager.get())->ClearRetainerWidget();
   }
 
-
   if (mLayerManager) {
     mLayerManager->Destroy();
+    mLayerManager = NULL;
   }
 
   if (mCompositor) {
-    mLayerManager = NULL;
     mCompositor->Destroy();
   }
 
 #ifdef NOISY_WIDGET_LEAKS
   gNumWidgets--;
   printf("WIDGETS- = %d\n", gNumWidgets);
 #endif