Bug 595277 - Part 0: Clear out user data on destroy. r=roc
authorBas Schouten <bschouten@mozilla.com>
Tue, 07 Dec 2010 03:05:25 +0100
changeset 58810 8e216406592f9228288fea5e78eb11b2319f093b
parent 58809 3c8debfeb6f9cefcd60d11216e12c009ba179539
child 58811 9472b008238cd54cf37f4cfb2632e4213099a455
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersroc
bugs595277
milestone2.0b8pre
Bug 595277 - Part 0: Clear out user data on destroy. r=roc
gfx/layers/Layers.h
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindowGfx.cpp
widget/src/xpwidgets/PuppetWidget.cpp
widget/src/xpwidgets/nsBaseWidget.cpp
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -185,16 +185,25 @@ public:
   /**
    * This getter can be used anytime. Ownership is retained by this object.
    */
   LayerUserData* Get(void* aKey)
   {
     return mKey == aKey ? mValue.get() : nsnull;
   }
 
+  /**
+   * Clear out current user data.
+   */
+  void Clear()
+  {
+    mKey = nsnull;
+    mValue = nsnull;
+  }
+
 private:
   void* mKey;
   nsAutoPtr<LayerUserData> mValue;
 };
 
 /**
  * A LayerManager controls a tree of layers. All layers in the tree
  * must use the same LayerManager.
@@ -236,17 +245,17 @@ public:
   virtual ~LayerManager() {}
 
   /**
    * Release layers and resources held by this layer manager, and mark
    * it as destroyed.  Should do any cleanup necessary in preparation
    * for its widget going away.  After this call, only user data calls
    * are valid on the layer manager.
    */
-  virtual void Destroy() { mDestroyed = PR_TRUE; }
+  virtual void Destroy() { mDestroyed = PR_TRUE; mUserData.Clear(); }
   PRBool IsDestroyed() { return mDestroyed; }
 
   /**
    * Start a new transaction. Nested transactions are not allowed so
    * there must be no transaction currently in progress.
    * This transaction will update the state of the window from which
    * this LayerManager was obtained.
    */
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -3191,16 +3191,17 @@ nsWindow::GetLayerManager(bool* aAllowRe
     if (mLayerManager->GetBackendType() ==
         mozilla::layers::LayerManager::LAYERS_D3D10)
     {
       mozilla::layers::LayerManagerD3D10 *layerManagerD3D10 =
         static_cast<mozilla::layers::LayerManagerD3D10*>(mLayerManager.get());
       if (layerManagerD3D10->device() !=
           gfxWindowsPlatform::GetPlatform()->GetD3D10Device())
       {
+        mLayerManager->Destroy();
         mLayerManager = nsnull;
       }
     }
   }
 #endif
 
   if (!mLayerManager) {
     nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
--- a/widget/src/windows/nsWindowGfx.cpp
+++ b/widget/src/windows/nsWindowGfx.cpp
@@ -603,16 +603,17 @@ PRBool nsWindow::OnPaint(HDC aDC, PRUint
 #ifdef MOZ_ENABLE_D3D9_LAYER
       case LayerManager::LAYERS_D3D9:
         {
           LayerManagerD3D9 *layerManagerD3D9 =
             static_cast<mozilla::layers::LayerManagerD3D9*>(GetLayerManager());
           layerManagerD3D9->SetClippingRegion(event.region);
           result = DispatchWindowEvent(&event, eventStatus);
           if (layerManagerD3D9->DeviceWasRemoved()) {
+            mLayerManager->Destroy();
             mLayerManager = nsnull;
             // When our device was removed, we should have gfxWindowsPlatform
             // check if its render mode is up to date!
             gfxWindowsPlatform::GetPlatform()->UpdateRenderMode();
             Invalidate(PR_FALSE);
           }
         }
         break;
--- a/widget/src/xpwidgets/PuppetWidget.cpp
+++ b/widget/src/xpwidgets/PuppetWidget.cpp
@@ -149,16 +149,19 @@ PuppetWidget::CreateChild(const nsIntRec
 }
 
 NS_IMETHODIMP
 PuppetWidget::Destroy()
 {
   Base::Destroy();
   mPaintTask.Revoke();
   mChild = nsnull;
+  if (mLayerManager) {
+    mLayerManager->Destroy();
+  }
   mLayerManager = nsnull;
   mTabChild = nsnull;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PuppetWidget::Show(PRBool aState)
 {
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -132,16 +132,20 @@ nsBaseWidget::nsBaseWidget()
 //-------------------------------------------------------------------------
 nsBaseWidget::~nsBaseWidget()
 {
   if (mLayerManager &&
       mLayerManager->GetBackendType() == LayerManager::LAYERS_BASIC) {
     static_cast<BasicLayerManager*>(mLayerManager.get())->ClearRetainerWidget();
   }
 
+  if (mLayerManager) {
+    mLayerManager->Destroy();
+  }
+
 #ifdef NOISY_WIDGET_LEAKS
   gNumWidgets--;
   printf("WIDGETS- = %d\n", gNumWidgets);
 #endif
 
   NS_IF_RELEASE(mToolkit);
   NS_IF_RELEASE(mContext);
   if (mOriginalBounds)
@@ -1022,16 +1026,19 @@ nsBaseWidget::ShowsResizeIndicator(nsInt
 
 NS_IMETHODIMP
 nsBaseWidget::SetAcceleratedRendering(PRBool aEnabled)
 {
   if (mUseAcceleratedRendering == aEnabled) {
     return NS_OK;
   }
   mUseAcceleratedRendering = aEnabled;
+  if (mLayerManager) {
+    mLayerManager->Destroy();
+  }
   mLayerManager = NULL;
   return NS_OK;
 }
 
 PRBool
 nsBaseWidget::GetAcceleratedRendering()
 {
   return mUseAcceleratedRendering;