Bug 595277 - Part 2: Add parameter to specify requiring the permanent LayerManager. r=roc
authorBas Schouten <bschouten@mozilla.com>
Tue, 07 Dec 2010 03:05:52 +0100
changeset 58812 e58acf6e5bbcfaae7ddec281f20adb8f0882d6c5
parent 58811 9472b008238cd54cf37f4cfb2632e4213099a455
child 58813 a54c3af4c33d75d739ad9a56043460def6d99e5e
push id17439
push userbschouten@mozilla.com
push dateWed, 08 Dec 2010 02:25:42 +0000
treeherdermozilla-central@aa593835cb8d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs595277
milestone2.0b8pre
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 595277 - Part 2: Add parameter to specify requiring the permanent LayerManager. r=roc
content/base/public/nsContentUtils.h
content/base/src/nsContentUtils.cpp
widget/public/nsIWidget.h
widget/src/android/nsWindow.cpp
widget/src/android/nsWindow.h
widget/src/cocoa/nsChildView.mm
widget/src/cocoa/nsCocoaWindow.h
widget/src/cocoa/nsCocoaWindow.mm
widget/src/gtk2/nsWindow.cpp
widget/src/qt/nsWindow.cpp
widget/src/windows/nsWindow.cpp
widget/src/windows/nsWindow.h
widget/src/xpwidgets/PuppetWidget.cpp
widget/src/xpwidgets/PuppetWidget.h
widget/src/xpwidgets/nsBaseWidget.cpp
widget/src/xpwidgets/nsBaseWidget.h
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1678,16 +1678,33 @@ public:
    * If one can't be found, a BasicLayerManager is created and returned.
    *
    * @param aDoc the document for which to return a layer manager.
    */
   static already_AddRefed<mozilla::layers::LayerManager>
   LayerManagerForDocument(nsIDocument *aDoc);
 
   /**
+   * Returns a layer manager to use for the given document. Basically we
+   * look up the document hierarchy for the first document which has
+   * a presentation with an associated widget, and use that widget's
+   * layer manager. In addition to the normal layer manager lookup this will
+   * specifically request a persistent layer manager. This means that the layer
+   * manager is expected to remain the layer manager for the document in the
+   * forseeable future. This function should be used carefully as it may change
+   * the document's layer manager.
+   *
+   * If one can't be found, a BasicLayerManager is created and returned.
+   *
+   * @param aDoc the document for which to return a layer manager.
+   */
+  static already_AddRefed<mozilla::layers::LayerManager>
+  PersistentLayerManagerForDocument(nsIDocument *aDoc);
+
+  /**
    * Determine whether a content node is focused or not,
    *
    * @param aContent the content node to check
    * @return true if the content node is focused, false otherwise.
    */
   static PRBool IsFocusedContent(const nsIContent *aContent);
 
   /**
@@ -1710,17 +1727,16 @@ public:
 
   /**
    * Returns true if content with the given principal is allowed to use XUL
    * and XBL and false otherwise.
    */
   static bool AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal);
 
 private:
-
   static PRBool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
   static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
   static void DropScriptObject(PRUint32 aLangID, void *aObject, void *aClosure);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -6365,18 +6365,18 @@ nsContentUtils::PlatformToDOMLineBreaks(
                              NS_LITERAL_STRING("\n").get());
 
     // Mac linebreaks: Map any remaining CR to LF:
     aString.ReplaceSubstring(NS_LITERAL_STRING("\r").get(),
                              NS_LITERAL_STRING("\n").get());
   }
 }
 
-already_AddRefed<LayerManager>
-nsContentUtils::LayerManagerForDocument(nsIDocument *aDoc)
+static already_AddRefed<LayerManager>
+LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent)
 {
   nsIDocument* doc = aDoc;
   nsIDocument* displayDoc = doc->GetDisplayDocument();
   if (displayDoc) {
     doc = displayDoc;
   }
 
   nsIPresShell* shell = doc->GetShell();
@@ -6400,26 +6400,41 @@ nsContentUtils::LayerManagerForDocument(
   }
 
   if (shell) {
     nsIFrame* rootFrame = shell->FrameManager()->GetRootFrame();
     if (rootFrame) {
       nsIWidget* widget =
         nsLayoutUtils::GetDisplayRootFrame(rootFrame)->GetNearestWidget();
       if (widget) {
-        nsRefPtr<LayerManager> manager = widget->GetLayerManager();
+        nsRefPtr<LayerManager> manager =
+          static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget)->
+            GetLayerManager(aRequirePersistent ? nsIWidget_MOZILLA_2_0_BRANCH::LAYER_MANAGER_PERSISTENT : 
+                                                 nsIWidget_MOZILLA_2_0_BRANCH::LAYER_MANAGER_CURRENT);
         return manager.forget();
       }
     }
   }
 
   nsRefPtr<LayerManager> manager = new BasicLayerManager();
   return manager.forget();
 }
 
+already_AddRefed<LayerManager>
+nsContentUtils::LayerManagerForDocument(nsIDocument *aDoc)
+{
+  return LayerManagerForDocumentInternal(aDoc, false);
+}
+
+already_AddRefed<LayerManager>
+nsContentUtils::PersistentLayerManagerForDocument(nsIDocument *aDoc)
+{
+  return LayerManagerForDocumentInternal(aDoc, true);
+}
+
 bool
 nsContentUtils::AllowXULXBLForPrincipal(nsIPrincipal* aPrincipal)
 {
   if (IsSystemPrincipal(aPrincipal)) {
     return true;
   }
   
   nsCOMPtr<nsIURI> princURI;
--- a/widget/public/nsIWidget.h
+++ b/widget/public/nsIWidget.h
@@ -1364,25 +1364,36 @@ protected:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget, NS_IWIDGET_IID)
 
 class nsIWidget_MOZILLA_2_0_BRANCH : public nsIWidget {
   public:
     NS_DECLARE_STATIC_IID_ACCESSOR(NS_IWIDGET_MOZILLA_2_0_BRANCH_IID)
 
+    typedef mozilla::layers::LayerManager LayerManager;
+
     /*
      * Notifies the IME if the input context changes.
      *
      * aContext cannot be null.
      * Set mStatus to 'Enabled' or 'Disabled' or 'Password'.
      */
     NS_IMETHOD SetInputMode(const IMEContext& aContext) = 0;
 
     /*
      * Get IME is 'Enabled' or 'Disabled' or 'Password' and other input context
      */
     NS_IMETHOD GetInputMode(IMEContext& aContext) = 0;
+
+    enum LayerManagerPersistence
+    {
+      LAYER_MANAGER_CURRENT = 0,
+      LAYER_MANAGER_PERSISTENT
+    };
+
+    virtual LayerManager *GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
+                                          bool* aAllowRetaining = nsnull) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIWidget_MOZILLA_2_0_BRANCH, NS_IWIDGET_MOZILLA_2_0_BRANCH_IID)
 
 #endif // nsIWidget_h__
--- a/widget/src/android/nsWindow.cpp
+++ b/widget/src/android/nsWindow.cpp
@@ -652,17 +652,17 @@ nsWindow::MakeFullScreen(PRBool aFullScr
 
 NS_IMETHODIMP
 nsWindow::SetWindowClass(const nsAString& xulWinType)
 {
     return NS_OK;
 }
 
 mozilla::layers::LayerManager*
-nsWindow::GetLayerManager(bool* aAllowRetaining)
+nsWindow::GetLayerManager(LayerManagerPersistence, bool* aAllowRetaining)
 {
     if (aAllowRetaining) {
         *aAllowRetaining = true;
     }
     if (mLayerManager) {
         return mLayerManager;
     }
 
@@ -863,17 +863,17 @@ nsWindow::DrawTo(gfxASurface *targetSurf
     }
 
     // If we have no covering child, then we need to render this.
     if (coveringChildIndex == -1) {
         ALOG("nsWindow[%p]::DrawTo no covering child, drawing this", (void*) this);
 
         nsPaintEvent event(PR_TRUE, NS_PAINT, this);
         event.region = boundsRect;
-        switch (GetLayerManager()->GetBackendType()) {
+        switch (GetLayerManager(nsnull)->GetBackendType()) {
             case LayerManager::LAYERS_BASIC: {
                 nsRefPtr<gfxContext> ctx = new gfxContext(targetSurface);
 
                 {
                     AutoLayerManagerSetup
                       setupLayerManager(this, ctx, BasicLayerManager::BUFFER_NONE);
                     status = DispatchEvent(&event);
                 }
@@ -886,17 +886,17 @@ nsWindow::DrawTo(gfxASurface *targetSurf
 #endif
 
                 // XXX if we got an ignore for the parent, do we still want to draw the children?
                 // We don't really have a good way not to...
                 break;
             }
 
             case LayerManager::LAYERS_OPENGL: {
-                static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager())->
+                static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nsnull))->
                     SetClippingRegion(nsIntRegion(boundsRect));
 
                 status = DispatchEvent(&event);
                 break;
             }
 
             default:
                 NS_ERROR("Invalid layer manager");
@@ -955,17 +955,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
     AndroidBridge::AutoLocalJNIFrame jniFrame;
 
     AndroidGeckoSurfaceView& sview(AndroidBridge::Bridge()->SurfaceView());
 
     NS_ASSERTION(!sview.isNull(), "SurfaceView is null!");
 
     AndroidBridge::Bridge()->HideProgressDialogOnce();
 
-    if (GetLayerManager()->GetBackendType() == LayerManager::LAYERS_BASIC) {
+    if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_BASIC) {
         jobject bytebuf = sview.GetSoftwareDrawBuffer();
         if (!bytebuf) {
             ALOG("no buffer to draw into - skipping draw");
             return;
         }
 
         void *buf = AndroidBridge::JNI()->GetDirectBufferAddress(bytebuf);
         int cap = AndroidBridge::JNI()->GetDirectBufferCapacity(bytebuf);
--- a/widget/src/android/nsWindow.h
+++ b/widget/src/android/nsWindow.h
@@ -50,16 +50,18 @@ namespace mozilla {
     class AndroidGeckoEvent;
     class AndroidKeyEvent;
 }
 
 class nsWindow :
     public nsBaseWidget
 {
 public:
+    using nsBaseWidget::GetLayerManager;
+
     nsWindow();
     virtual ~nsWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
 
     static void OnGlobalAndroidEvent(mozilla::AndroidGeckoEvent *ae);
     static void SetInitialAndroidBounds(const gfxIntSize& sz);
     static gfxIntSize GetAndroidBounds();
@@ -157,17 +159,18 @@ public:
     NS_IMETHOD GetInputMode(IMEContext& aContext);
     NS_IMETHOD CancelIMEComposition();
 
     NS_IMETHOD OnIMEFocusChange(PRBool aFocus);
     NS_IMETHOD OnIMETextChange(PRUint32 aStart, PRUint32 aOldEnd, PRUint32 aNewEnd);
     NS_IMETHOD OnIMESelectionChange(void);
     virtual nsIMEUpdatePreference GetIMEUpdatePreference();
 
-    LayerManager* GetLayerManager(bool* aAllowRetaining = nsnull);
+    LayerManager* GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
+                                  bool* aAllowRetaining = nsnull);
     gfxASurface* GetThebesSurface();
 
     NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
 protected:
     void BringToFront();
     nsWindow *FindTopLevel();
     PRBool DrawTo(gfxASurface *targetSurface);
     PRBool IsTopLevel();
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -2713,18 +2713,18 @@ NSEvent* gLastDragMouseDownEvent = nil;
     if ([cview isPluginView] && [cview pluginDrawingModel] == NPDrawingModelQuickDraw) {
       NSRect frame = [view frame];
       paintEvent.region.Sub(paintEvent.region,
         nsIntRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height));
     }
   }
 #endif
 
-  if (mGeckoChild->GetLayerManager()->GetBackendType() == LayerManager::LAYERS_OPENGL) {
-    LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(mGeckoChild->GetLayerManager());
+  if (mGeckoChild->GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_OPENGL) {
+    LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(mGeckoChild->GetLayerManager(nsnull));
     manager->SetClippingRegion(paintEvent.region); 
     if (!mGLContext) {
       mGLContext = (NSOpenGLContext *)manager->gl()->GetNativeData(mozilla::gl::GLContext::NativeGLContext);
       [mGLContext retain];
     }
     mGeckoChild->DispatchWindowEvent(paintEvent);
     return;
   }
--- a/widget/src/cocoa/nsCocoaWindow.h
+++ b/widget/src/cocoa/nsCocoaWindow.h
@@ -253,17 +253,18 @@ public:
     NS_IMETHOD              SetCursor(nsCursor aCursor);
     NS_IMETHOD              SetCursor(imgIContainer* aCursor, PRUint32 aHotspotX, PRUint32 aHotspotY);
 
     NS_IMETHOD              SetTitle(const nsAString& aTitle);
 
     NS_IMETHOD Invalidate(const nsIntRect &aRect, PRBool aIsSynchronous);
     NS_IMETHOD Update();
     virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations);
-    virtual LayerManager* GetLayerManager(bool* aAllowRetaining = nsnull);
+    virtual LayerManager* GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
+                                          bool* aAllowRetaining = nsnull);
     NS_IMETHOD DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus) ;
     NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
                                    PRBool aDoCapture, PRBool aConsumeRollupEvent);
     NS_IMETHOD GetAttention(PRInt32 aCycleCount);
     virtual PRBool HasPendingInputEvent();
     virtual nsTransparencyMode GetTransparencyMode();
     virtual void SetTransparencyMode(nsTransparencyMode aMode);
     NS_IMETHOD SetWindowShadowStyle(PRInt32 aStyle);
--- a/widget/src/cocoa/nsCocoaWindow.mm
+++ b/widget/src/cocoa/nsCocoaWindow.mm
@@ -927,17 +927,17 @@ nsCocoaWindow::ConfigureChildren(const n
 {
   if (mPopupContentView) {
     mPopupContentView->ConfigureChildren(aConfigurations);
   }
   return NS_OK;
 }
 
 LayerManager*
-nsCocoaWindow::GetLayerManager(bool* aAllowRetaining)
+nsCocoaWindow::GetLayerManager(LayerManagerPersistence, bool* aAllowRetaining)
 {
   if (mPopupContentView) {
     return mPopupContentView->GetLayerManager(aAllowRetaining);
   }
   return nsnull;
 }
 
 nsTransparencyMode nsCocoaWindow::GetTransparencyMode()
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -2149,19 +2149,19 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
         }
     }
 
     if (event.region.IsEmpty()) {
         g_free(rects);
         return TRUE;
     }
 
-    if (GetLayerManager()->GetBackendType() == LayerManager::LAYERS_OPENGL)
+    if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_OPENGL)
     {
-        LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(GetLayerManager());
+        LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(GetLayerManager(nsnull));
         manager->SetClippingRegion(event.region);
 
         nsEventStatus status;
         DispatchEvent(&event, status);
         g_free(rects);
         return TRUE;
     }
             
--- a/widget/src/qt/nsWindow.cpp
+++ b/widget/src/qt/nsWindow.cpp
@@ -1009,22 +1009,22 @@ nsWindow::DoPaint(QPainter* aPainter, co
         return nsEventStatus_eIgnore;
 
     if (!mDirtyScrollArea.isEmpty())
         mDirtyScrollArea = QRegion();
 
     nsEventStatus status;
     nsIntRect rect(r.x(), r.y(), r.width(), r.height());
 
-    if (GetLayerManager()->GetBackendType() == LayerManager::LAYERS_OPENGL) {
+    if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_OPENGL) {
         nsPaintEvent event(PR_TRUE, NS_PAINT, this);
         event.refPoint.x = r.x();
         event.refPoint.y = r.y();
         event.region = nsIntRegion(rect);
-        static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager())->
+        static_cast<mozilla::layers::LayerManagerOGL*>(GetLayerManager(nsnull))->
             SetClippingRegion(event.region);
         return DispatchEvent(&event);
     }
 
     gfxQtPlatform::RenderMode renderMode = gfxQtPlatform::GetPlatform()->GetRenderMode();
     int depth = aPainter->device()->depth();
 
     nsRefPtr<gfxASurface> targetSurface = nsnull;
--- a/widget/src/windows/nsWindow.cpp
+++ b/widget/src/windows/nsWindow.cpp
@@ -3203,17 +3203,17 @@ nsWindow::HasPendingInputEvent()
  *
  * SECTION: nsIWidget::GetLayerManager
  *
  * Get the layer manager associated with this widget.
  *
  **************************************************************/
 
 mozilla::layers::LayerManager*
-nsWindow::GetLayerManager(bool* aAllowRetaining)
+nsWindow::GetLayerManager(LayerManagerPersistence aPersistence, bool* aAllowRetaining)
 {
   if (aAllowRetaining) {
     *aAllowRetaining = true;
   }
 
 #ifndef WINCE
 #ifdef MOZ_ENABLE_D3D10_LAYER
   if (mLayerManager) {
--- a/widget/src/windows/nsWindow.h
+++ b/widget/src/windows/nsWindow.h
@@ -161,17 +161,17 @@ public:
   virtual nsIntSize       ClientToWindowSize(const nsIntSize& aClientSize);
   NS_IMETHOD              DispatchEvent(nsGUIEvent* event, nsEventStatus & aStatus);
   NS_IMETHOD              EnableDragDrop(PRBool aEnable);
   NS_IMETHOD              CaptureMouse(PRBool aCapture);
   NS_IMETHOD              CaptureRollupEvents(nsIRollupListener * aListener, nsIMenuRollup * aMenuRollup,
                                               PRBool aDoCapture, PRBool aConsumeRollupEvent);
   NS_IMETHOD              GetAttention(PRInt32 aCycleCount);
   virtual PRBool          HasPendingInputEvent();
-  virtual LayerManager*   GetLayerManager(bool* aAllowRetaining = nsnull);
+  virtual LayerManager*   GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT, bool* aAllowRetaining = nsnull);
   gfxASurface             *GetThebesSurface();
   NS_IMETHOD              OnDefaultButtonLoaded(const nsIntRect &aButtonRect);
   NS_IMETHOD              OverrideSystemMouseScrollSpeed(PRInt32 aOriginalDelta, PRBool aIsHorizontal, PRInt32 &aOverriddenDelta);
 
   virtual nsresult        SynthesizeNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
                                                    PRInt32 aNativeKeyCode,
                                                    PRUint32 aModifierFlags,
                                                    const nsAString& aCharacters,
--- a/widget/src/xpwidgets/PuppetWidget.cpp
+++ b/widget/src/xpwidgets/PuppetWidget.cpp
@@ -310,17 +310,17 @@ PuppetWidget::DispatchEvent(nsGUIEvent* 
     event->widget = mChild;
     mChild->DispatchEvent(event, aStatus);
   }
 
   return NS_OK;
 }
 
 LayerManager*
-PuppetWidget::GetLayerManager(bool* aAllowRetaining)
+PuppetWidget::GetLayerManager(LayerManagerPersistence, bool* aAllowRetaining)
 {
   if (!mLayerManager) {
     mLayerManager = new BasicShadowLayerManager(this);
   }
   if (aAllowRetaining) {
     *aAllowRetaining = true;
   }
   return mLayerManager;
--- a/widget/src/xpwidgets/PuppetWidget.h
+++ b/widget/src/xpwidgets/PuppetWidget.h
@@ -159,17 +159,18 @@ public:
                                  PRBool aDoCapture, PRBool aConsumeRollupEvent)
   { return NS_ERROR_UNEXPECTED; }
 
   //
   // nsBaseWidget methods we override
   //
 
 //NS_IMETHOD              CaptureMouse(PRBool aCapture);
-  virtual LayerManager*     GetLayerManager(bool* aAllowRetaining = nsnull);
+  virtual LayerManager*     GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
+                                            bool* aAllowRetaining = nsnull);
 //  virtual nsIDeviceContext* GetDeviceContext();
   virtual gfxASurface*      GetThebesSurface();
 
   NS_IMETHOD ResetInputState();
   NS_IMETHOD SetIMEOpenState(PRBool aState);
   NS_IMETHOD GetIMEOpenState(PRBool *aState);
   NS_IMETHOD SetInputMode(const IMEContext& aContext);
   NS_IMETHOD GetInputMode(IMEContext& aContext);
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -742,28 +742,28 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScre
 }
 
 nsBaseWidget::AutoLayerManagerSetup::AutoLayerManagerSetup(
     nsBaseWidget* aWidget, gfxContext* aTarget,
     BasicLayerManager::BufferMode aDoubleBuffering)
   : mWidget(aWidget)
 {
   BasicLayerManager* manager =
-    static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
+    static_cast<BasicLayerManager*>(mWidget->GetLayerManager(nsnull));
   if (manager) {
     NS_ASSERTION(manager->GetBackendType() == LayerManager::LAYERS_BASIC,
       "AutoLayerManagerSetup instantiated for non-basic layer backend!");
     manager->SetDefaultTarget(aTarget, aDoubleBuffering);
   }
 }
 
 nsBaseWidget::AutoLayerManagerSetup::~AutoLayerManagerSetup()
 {
   BasicLayerManager* manager =
-    static_cast<BasicLayerManager*>(mWidget->GetLayerManager());
+    static_cast<BasicLayerManager*>(mWidget->GetLayerManager(nsnull));
   if (manager) {
     NS_ASSERTION(manager->GetBackendType() == LayerManager::LAYERS_BASIC,
       "AutoLayerManagerSetup instantiated for non-basic layer backend!");
     manager->SetDefaultTarget(nsnull, BasicLayerManager::BUFFER_NONE);
   }
 }
 
 nsBaseWidget::AutoUseBasicLayerManager::AutoUseBasicLayerManager(nsBaseWidget* aWidget)
@@ -807,16 +807,22 @@ nsBaseWidget::GetShouldAccelerate()
   if (accelerateByDefault)
     return PR_TRUE;
 
   return mUseAcceleratedRendering;
 }
 
 LayerManager* nsBaseWidget::GetLayerManager(bool* aAllowRetaining)
 {
+  return GetLayerManager(LAYER_MANAGER_CURRENT, aAllowRetaining);
+}
+
+LayerManager* nsBaseWidget::GetLayerManager(LayerManagerPersistence,
+                                            bool* aAllowRetaining)
+{
   if (!mLayerManager) {
     nsCOMPtr<nsIPrefBranch2> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
 
     mUseAcceleratedRendering = GetShouldAccelerate();
 
     if (mUseAcceleratedRendering) {
       nsRefPtr<LayerManagerOGL> layerManager =
         new mozilla::layers::LayerManagerOGL(this);
--- a/widget/src/xpwidgets/nsBaseWidget.h
+++ b/widget/src/xpwidgets/nsBaseWidget.h
@@ -110,17 +110,19 @@ public:
   virtual nsTransparencyMode GetTransparencyMode();
   virtual void            GetWindowClipRegion(nsTArray<nsIntRect>* aRects);
   NS_IMETHOD              SetWindowShadowStyle(PRInt32 aStyle);
   virtual void            SetShowsToolbarButton(PRBool aShow) {}
   NS_IMETHOD              HideWindowChrome(PRBool aShouldHide);
   NS_IMETHOD              MakeFullScreen(PRBool aFullScreen);
   virtual nsIDeviceContext* GetDeviceContext();
   virtual nsIToolkit*     GetToolkit();
-  virtual LayerManager*   GetLayerManager(bool* aAllowRetaining = nsnull);
+  virtual LayerManager*   GetLayerManager(bool *aAllowRetaining = nsnull);
+  virtual LayerManager*   GetLayerManager(LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT,
+                                          bool* aAllowRetaining = nsnull);
   virtual gfxASurface*    GetThebesSurface();
   NS_IMETHOD              SetModal(PRBool aModal); 
   NS_IMETHOD              SetWindowClass(const nsAString& xulWinType);
   NS_IMETHOD              SetBounds(const nsIntRect &aRect);
   NS_IMETHOD              GetBounds(nsIntRect &aRect);
   NS_IMETHOD              GetClientBounds(nsIntRect &aRect);
   NS_IMETHOD              GetScreenBounds(nsIntRect &aRect);
   virtual nsIntPoint      GetClientOffset();