More clean up. Shutdown down a window no longer crashes
authorBenoit Girard <b56girard@gmail.com>
Fri, 16 Dec 2011 19:21:51 -0500
changeset 92330 154e2da9922581f16fac82e3c7375802912900d2
parent 92328 df720caee3c59c528aee6e3cd6017836c5c07cd1
child 92331 4480de3847fa1da40f651890f6026d8f06ed0e15
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
More clean up. Shutdown down a window no longer crashes
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorChild.h
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/PCompositor.ipdl
gfx/layers/ipc/ShadowLayersChild.cpp
widget/src/xpwidgets/nsBaseWidget.cpp
widget/src/xpwidgets/nsBaseWidget.h
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -54,19 +54,26 @@ CompositorChild::CompositorChild(Thread 
   : mCompositorThread(aCompositorThread)
   , mLayerManager(aLayerManager)
 {
   MOZ_COUNT_CTOR(CompositorChild);
 }
 
 CompositorChild::~CompositorChild()
 {
+  printf("del\n");
   MOZ_COUNT_DTOR(CompositorChild);
 }
 
+void
+CompositorChild::Destroy()
+{
+  CallStop();
+}
+
 CompositorChild*
 CompositorChild::CreateCompositor(LayerManager *aLayerManager)
 {
   Thread* compositorThread = new Thread("CompositorThread");
   if (compositorThread->Start()) {
     MessageLoop *parentMessageLoop = MessageLoop::current();
     MessageLoop *childMessageLoop = compositorThread->message_loop();
     CompositorParent *compositorParent = new CompositorParent();
@@ -100,15 +107,16 @@ PLayersChild*
 CompositorChild::AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget)
 {
   return new ShadowLayersChild();;
 }
 
 bool
 CompositorChild::DeallocPLayers(PLayersChild* actor)
 {
+  printf("actor destroy\n");
   delete actor;
   return true;
 }
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -51,20 +51,22 @@ using base::Thread;
 
 namespace mozilla {
 namespace layers {
 
 class LayerManager;
 
 class CompositorChild : public PCompositorChild
 {
-
+  NS_INLINE_DECL_REFCOUNTING(CompositorChild)
 public:
   virtual ~CompositorChild();
 
+  void Destroy();
+
   static CompositorChild* CreateCompositor(LayerManager *aLayerManager);
 
 protected:
   CompositorChild(Thread* aCompositorThread, LayerManager *aLayerManager);
 
   virtual PLayersChild* AllocPLayers(const LayersBackend &aBackend, const WidgetDescriptor &aWidget);
   virtual bool DeallocPLayers(PLayersChild *aChild);
 
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -40,40 +40,52 @@
 #include "CompositorParent.h"
 #include "ShadowLayersParent.h"
 #include "LayerManagerOGL.h"
 
 namespace mozilla {
 namespace layers {
 
 CompositorParent::CompositorParent()
+  : mLayerManager(NULL)
 {
 
   MOZ_COUNT_CTOR(CompositorParent);
 }
 
 CompositorParent::~CompositorParent()
 {
+  printf("delete parent\n");
   delete mLayerManager;
   MOZ_COUNT_DTOR(CompositorParent);
 }
 
 bool
 CompositorParent::AnswerInit()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
   return true;
 }
 
+bool
+CompositorParent::AnswerStop()
+{
+  if (mLayerManager) {
+    delete mLayerManager;
+    mLayerManager = NULL;
+  }
+  return true;
+}
+
 void
 CompositorParent::Composite()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
-  MessageLoop::current()->PostTask(FROM_HERE, composeTask);
+  MessageLoop::current()->PostDelayedTask(FROM_HERE, composeTask, 100);
 
   if (!mLayerManager)
     return;
 
   mLayerManager->EndEmptyTransaction();
 
 }
 
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -53,16 +53,17 @@ class CompositorParent : public PComposi
                          public ShadowLayersHost
 {
   NS_INLINE_DECL_REFCOUNTING(CompositorParent)
 public:
   CompositorParent();
   virtual ~CompositorParent();
 
   bool AnswerInit();
+  bool AnswerStop();
 
   virtual mozilla::layout::RenderFrameParent* GetRenderFrameParent() { return NULL; }
   virtual CompositorParent* GetCompositorParent() { return this; }
 
 protected:
   virtual PLayersParent* AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget);
 
   virtual bool DeallocPLayers(PLayersParent* aLayers);
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -70,16 +70,18 @@ struct NativeContext {
 rpc protocol PCompositor
 {
   // Compositor can manage many Layer Manager (PLayers)
   manages PLayers;
 
 parent:  
 
   rpc Init();
+  rpc Stop();
+
   async PLayers(LayersBackend backend, WidgetDescriptor widgetDescriptor);
 
 child:
 
   // We create the LayerManager async thus we need to notify
   // content that we have a native context to attach to the widget.
   async NativeContextCreated(NativeContext aNativeContext);
 
--- a/gfx/layers/ipc/ShadowLayersChild.cpp
+++ b/gfx/layers/ipc/ShadowLayersChild.cpp
@@ -42,16 +42,17 @@
 #include "ShadowLayersChild.h"
 
 namespace mozilla {
 namespace layers {
 
 void
 ShadowLayersChild::Destroy()
 {
+  printf("Destroy shadow layers\n");
   NS_ABORT_IF_FALSE(0 == ManagedPLayerChild().Length(),
                     "layers should have been cleaned up by now");
   PLayersChild::Send__delete__(this);
   // WARNING: |this| has gone to the great heap in the sky
 }
 
 PLayerChild*
 ShadowLayersChild::AllocPLayer()
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -136,18 +136,23 @@ nsBaseWidget::nsBaseWidget()
 //-------------------------------------------------------------------------
 nsBaseWidget::~nsBaseWidget()
 {
   if (mLayerManager &&
       mLayerManager->GetBackendType() == LayerManager::LAYERS_BASIC) {
     static_cast<BasicLayerManager*>(mLayerManager.get())->ClearRetainerWidget();
   }
 
+  if (mCompositor) {
+    mCompositor->Destroy();
+  }
+
   if (mLayerManager) {
     mLayerManager->Destroy();
+    mLayerManager = NULL;
   }
 
 #ifdef NOISY_WIDGET_LEAKS
   gNumWidgets--;
   printf("WIDGETS- = %d\n", gNumWidgets);
 #endif
 
   NS_IF_RELEASE(mContext);
@@ -841,39 +846,39 @@ LayerManager* nsBaseWidget::GetLayerMana
 
     if (mUseAcceleratedRendering) {
 
       // Try to use an async compositor first, if possible
       bool useCompositor =
         Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
       if (useCompositor) {
         LayerManager* lm = CreateBasicLayerManager();
-        CompositorChild *compositorChild = CompositorChild::CreateCompositor(lm);
+        mCompositor = CompositorChild::CreateCompositor(lm);
 
-        if (compositorChild) {
+        if (mCompositor) {
           // e10s uses the parameter to pass in the shadow manager from the TabChild
           // so we don't expect to see it there since this doesn't support e10s.
           NS_ASSERTION(aShadowManager == NULL, "Async Compositor not supported with e10s");
           WidgetDescriptor desc = ViewWidget((uintptr_t)dynamic_cast<nsIWidget*>(this));
-          PLayersChild* shadowManager = compositorChild->SendPLayersConstructor(
+          PLayersChild* shadowManager = mCompositor->SendPLayersConstructor(
                                           LayerManager::LAYERS_OPENGL,
                                           desc);
 
           if (shadowManager) {
             ShadowLayerForwarder* lf = lm->AsShadowForwarder();
             if (!lf) {
               delete lm;
-              delete compositorChild;
+              mCompositor = NULL;
             }
             lf->SetShadowManager(shadowManager);
 
             mLayerManager = lm;
           } else {
             NS_WARNING("fail to construct LayersChild");
-            delete compositorChild;
+            mCompositor = NULL;
           }
         }
       }
 
       if (!mLayerManager) {
         nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
         /**
          * XXX - On several OSes initialization is expected to fail for now.
--- a/widget/src/xpwidgets/nsBaseWidget.h
+++ b/widget/src/xpwidgets/nsBaseWidget.h
@@ -46,16 +46,24 @@
 #include "nsGUIEvent.h"
 #include "nsAutoPtr.h"
 #include "BasicLayers.h"
 
 class nsIContent;
 class nsAutoRollup;
 class gfxContext;
 
+namespace mozilla {
+namespace layers {
+class CompositorChild;
+}
+}
+
+using mozilla::layers::CompositorChild;
+
 /**
  * Common widget implementation used as base class for native
  * or crossplatform implementations of Widgets. 
  * All cross-platform behavior that all widgets need to implement 
  * should be placed in this class. 
  * (Note: widget implementations are not required to use this
  * class, but it gives them a head start.)
  */
@@ -264,16 +272,17 @@ protected:
 protected:
   void*             mClientData;
   ViewWrapper*      mViewWrapperPtr;
   EVENT_CALLBACK    mEventCallback;
   EVENT_CALLBACK    mViewCallback;
   nsDeviceContext* mContext;
   nsRefPtr<LayerManager> mLayerManager;
   nsRefPtr<LayerManager> mBasicLayerManager;
+  nsRefPtr<CompositorChild> mCompositor;
   nscolor           mBackground;
   nscolor           mForeground;
   nsCursor          mCursor;
   nsWindowType      mWindowType;
   nsBorderStyle     mBorderStyle;
   bool              mOnDestroyCalled;
   bool              mUseAcceleratedRendering;
   bool              mTemporarilyUseBasicLayerManager;