Fix crash when deleting Compositor parent, and change RPC calls to sync calls..
authorAli Juma <ajuma@mozilla.com>
Tue, 20 Dec 2011 10:37:27 -0500
changeset 92337 f31cc58895d913cdaed2ef0aacb61d0313996469
parent 92336 616374c0e9ff15a062bfc6ab3aad9f495008ef20
child 92338 b8c022acb96ee8f2ced32e8d4646e06ba5fef6e6
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
Fix crash when deleting Compositor parent, and change RPC calls to sync calls..
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
widget/src/xpwidgets/nsBaseWidget.cpp
widget/src/xpwidgets/nsBaseWidget.h
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -61,38 +61,37 @@ CompositorChild::~CompositorChild()
 {
   printf("del compositor child\n");
   MOZ_COUNT_DTOR(CompositorChild);
 }
 
 void
 CompositorChild::Destroy()
 {
-  CallStop();
+  SendStop();
 }
 
 CompositorChild*
-CompositorChild::CreateCompositor(LayerManager *aLayerManager)
+CompositorChild::CreateCompositor(LayerManager *aLayerManager,
+                                  CompositorParent *aCompositorParent)
 {
   Thread* compositorThread = new Thread("CompositorThread");
   if (compositorThread->Start()) {
     MessageLoop *parentMessageLoop = MessageLoop::current();
     MessageLoop *childMessageLoop = compositorThread->message_loop();
-    CompositorParent* compositorParent = new CompositorParent();
     CompositorChild *compositorChild = new CompositorChild(compositorThread, aLayerManager);
     mozilla::ipc::AsyncChannel *parentChannel =
-      compositorParent->GetIPCChannel();
+      aCompositorParent->GetIPCChannel();
     mozilla::ipc::AsyncChannel *childChannel =
       compositorChild->GetIPCChannel();
     mozilla::ipc::AsyncChannel::Side childSide =
       mozilla::ipc::AsyncChannel::Child;
 
     compositorChild->Open(parentChannel, childMessageLoop, childSide);
-    compositorChild->CallInit();
-    compositorChild->mCompositorParent = compositorParent;
+    compositorChild->SendInit();
 
     return compositorChild;
   }
 
   return NULL;
 }
 
 bool
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -57,17 +57,18 @@ class CompositorParent;
 class CompositorChild : public PCompositorChild
 {
   NS_INLINE_DECL_REFCOUNTING(CompositorChild)
 public:
   virtual ~CompositorChild();
 
   void Destroy();
 
-  static CompositorChild* CreateCompositor(LayerManager *aLayerManager);
+  static CompositorChild* CreateCompositor(LayerManager *aLayerManager,
+                                           CompositorParent *aCompositorParent);
 
 protected:
   CompositorChild(Thread* aCompositorThread, LayerManager *aLayerManager);
 
   virtual PLayersChild* AllocPLayers(const LayersBackend &aBackend, const WidgetDescriptor &aWidget);
   virtual bool DeallocPLayers(PLayersChild *aChild);
 
   virtual bool RecvNativeContextCreated(const NativeContext &aNativeContext);
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -49,35 +49,30 @@ CompositorParent::CompositorParent()
 {
 
   MOZ_COUNT_CTOR(CompositorParent);
 }
 
 CompositorParent::~CompositorParent()
 {
   printf("delete parent\n");
-  delete mLayerManager;
   MOZ_COUNT_DTOR(CompositorParent);
 }
 
 bool
-CompositorParent::AnswerInit()
+CompositorParent::RecvInit()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
   return true;
 }
 
 bool
-CompositorParent::AnswerStop()
+CompositorParent::RecvStop()
 {
-  if (mLayerManager) {
-    delete mLayerManager;
-    mLayerManager = NULL;
-  }
   return true;
 }
 
 void
 CompositorParent::RequestComposition()
 {
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -52,33 +52,33 @@ namespace layers {
 class CompositorParent : public PCompositorParent,
                          public ShadowLayersHost
 {
   NS_INLINE_DECL_REFCOUNTING(CompositorParent)
 public:
   CompositorParent();
   virtual ~CompositorParent();
 
-  bool AnswerInit();
-  bool AnswerStop();
+  bool RecvInit();
+  bool RecvStop();
 
   void RequestComposition();
 
   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);
 
 private:
   void Composite();
 
-  LayerManager *mLayerManager;
+  nsRefPtr<LayerManager> mLayerManager;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
 
 } // layers
 } // mozilla
 
 #endif // mozilla_layers_CompositorParent_h
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -69,18 +69,18 @@ struct NativeContext {
  */
 rpc protocol PCompositor
 {
   // Compositor can manage many Layer Manager (PLayers)
   manages PLayers;
 
 parent:  
 
-  rpc Init();
-  rpc Stop();
+  sync Init();
+  sync 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/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -34,16 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/Util.h"
 
 #include "mozilla/layers/CompositorChild.h"
+#include "mozilla/layers/CompositorParent.h"
 #include "nsBaseWidget.h"
 #include "nsDeviceContext.h"
 #include "nsCOMPtr.h"
 #include "nsGfxCIID.h"
 #include "nsWidgetsCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIScreenManager.h"
 #include "nsAppDirectoryServiceDefs.h"
@@ -136,25 +137,26 @@ 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;
   }
 
+  if (mCompositor) {
+    mCompositor->Destroy();
+  }
+
 #ifdef NOISY_WIDGET_LEAKS
   gNumWidgets--;
   printf("WIDGETS- = %d\n", gNumWidgets);
 #endif
 
   NS_IF_RELEASE(mContext);
   delete mOriginalBounds;
 }
@@ -831,17 +833,18 @@ 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();
-        mCompositor = CompositorChild::CreateCompositor(lm);
+        mCompositorParent = new CompositorParent();
+        mCompositor = CompositorChild::CreateCompositor(lm, mCompositorParent);
 
         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 = mCompositor->SendPLayersConstructor(
                                           LayerManager::LAYERS_OPENGL,
--- a/widget/src/xpwidgets/nsBaseWidget.h
+++ b/widget/src/xpwidgets/nsBaseWidget.h
@@ -49,20 +49,22 @@
 
 class nsIContent;
 class nsAutoRollup;
 class gfxContext;
 
 namespace mozilla {
 namespace layers {
 class CompositorChild;
+class CompositorParent;
 }
 }
 
 using mozilla::layers::CompositorChild;
+using mozilla::layers::CompositorParent;
 
 /**
  * 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.)
@@ -272,16 +274,17 @@ protected:
   void*             mClientData;
   ViewWrapper*      mViewWrapperPtr;
   EVENT_CALLBACK    mEventCallback;
   EVENT_CALLBACK    mViewCallback;
   nsDeviceContext* mContext;
   nsRefPtr<LayerManager> mLayerManager;
   nsRefPtr<LayerManager> mBasicLayerManager;
   nsRefPtr<CompositorChild> mCompositor;
+  nsRefPtr<CompositorParent> mCompositorParent;
   nscolor           mBackground;
   nscolor           mForeground;
   nsCursor          mCursor;
   nsWindowType      mWindowType;
   nsBorderStyle     mBorderStyle;
   bool              mOnDestroyCalled;
   bool              mUseAcceleratedRendering;
   bool              mTemporarilyUseBasicLayerManager;