imported patch PCompositorProgress
authorAli Juma <ajuma@mozilla.com>
Thu, 15 Dec 2011 15:07:19 -0500
changeset 92324 a945782a1b3914bfe13949464708f4bf45c73eee
parent 92323 f129b37aa3a075b9531fcba48e452b2de36906df
child 92325 394b458e856b868aa69995f592aab2d20a71a600
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
imported patch PCompositorProgress
gfx/gl/GLContextProviderCGL.mm
gfx/layers/basic/BasicLayers.cpp
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/ShadowLayersParent.cpp
gfx/layers/opengl/LayerManagerOGL.cpp
widget/src/cocoa/nsChildView.mm
widget/src/xpwidgets/nsBaseWidget.cpp
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -43,16 +43,18 @@
 #include "gfxASurface.h"
 #include "gfxImageSurface.h"
 #include "gfxQuartzSurface.h"
 #include "gfxPlatform.h"
 #include "gfxFailure.h"
 #include "prenv.h"
 #include "mozilla/Preferences.h"
 
+NSOpenGLContext* nsGLContext;
+
 namespace mozilla {
 namespace gl {
 
 static bool gUseDoubleBufferedWindows = true;
 
 class CGLLibrary
 {
 public:
@@ -439,16 +441,17 @@ GLContextProviderCGL::CreateForWindow(ns
     GLContextCGL *shareContext = GetGlobalContextCGL();
 
     NSOpenGLContext *context = [[NSOpenGLContext alloc] 
                                 initWithFormat:sCGLLibrary.PixelFormat()
                                 shareContext:(shareContext ? shareContext->mContext : NULL)];
     if (!context) {
         return nsnull;
     }
+    nsGLContext = context;
 
     NSView *childView = (NSView *)aWidget->GetNativeData(NS_NATIVE_WIDGET);
     [context setView:childView];
 
     // make the context transparent
     nsRefPtr<GLContextCGL> glContext = new GLContextCGL(ContextFormat(ContextFormat::BasicRGB24),
                                                         shareContext,
                                                         context);
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -1608,17 +1608,17 @@ BasicLayerManager::EndTransactionInterna
         ApplyDoubleBuffering(mRoot, clipRect);
       }
     }
 
     PaintLayer(mTarget, mRoot, aCallback, aCallbackData, nsnull);
 
     if (!mTransactionIncomplete) {
       // Clear out target if we have a complete transaction.
-      mTarget = nsnull;
+      //mTarget = nsnull;
     }
   }
 
 #ifdef MOZ_LAYERS_HAVE_LOG
   Log();
   MOZ_LAYERS_LOG(("]----- EndTransaction"));
 #endif
 
@@ -2350,16 +2350,17 @@ BasicShadowableThebesLayer::PaintBuffer(
   } else {
     updatedRegion = aRegionToDraw;
   }
 
   NS_ASSERTION(mBuffer.BufferRect().Contains(aRegionToDraw.GetBounds()),
                "Update outside of buffer rect!");
   NS_ABORT_IF_FALSE(IsSurfaceDescriptorValid(mBackBuffer),
                     "should have a back buffer by now");
+
   BasicManager()->PaintedThebesBuffer(BasicManager()->Hold(this),
                                       updatedRegion,
                                       mBuffer.BufferRect(),
                                       mBuffer.BufferRotation(),
                                       mBackBuffer);
 }
 
 already_AddRefed<gfxASurface>
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set sw=4 ts=8 et tw=80 : */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=2 ts=2 et tw=80 : */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
  *
@@ -33,43 +33,69 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * 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 "CompositorChild.h"
+#include "CompositorParent.h"
 #include "mozilla/layers/ShadowLayersChild.h"
+#include "base/thread.h"
 
 using mozilla::layers::ShadowLayersChild;
 
 namespace mozilla {
 namespace layers {
 
-CompositorChild::CompositorChild()
+CompositorChild::CompositorChild(Thread *aCompositorThread)
+  : mCompositorThread(aCompositorThread)
 {
-    
-    MOZ_COUNT_CTOR(CompositorChild);
-	printf("Alloc CompositorChild\n");
+
+  MOZ_COUNT_CTOR(CompositorChild);
 }
 
 CompositorChild::~CompositorChild()
 {
-    MOZ_COUNT_DTOR(CompositorChild);
+  MOZ_COUNT_DTOR(CompositorChild);
+}
+
+CompositorChild*
+CompositorChild::CreateCompositor()
+{
+  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);
+    mozilla::ipc::AsyncChannel *parentChannel =
+      compositorParent->GetIPCChannel();
+    mozilla::ipc::AsyncChannel *childChannel =
+      compositorChild->GetIPCChannel();
+    mozilla::ipc::AsyncChannel::Side childSide =
+      mozilla::ipc::AsyncChannel::Child;
+
+    compositorChild->Open(parentChannel, childMessageLoop, childSide);
+    compositorChild->CallInit();
+    return compositorChild;
+  }
+
+  return NULL;
 }
 
 PLayersChild*
-CompositorChild::AllocPLayers(const LayersBackend &backend)
+CompositorChild::AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget)
 {
-    return new ShadowLayersChild();
+  return new ShadowLayersChild();
 }
 
 bool
 CompositorChild::DeallocPLayers(PLayersChild* actor)
 {
-	delete actor;
-    return true;
+  delete actor;
+  return true;
 }
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -37,27 +37,41 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_layers_CompositorChild_h
 #define mozilla_layers_CompositorChild_h
 
 #include "mozilla/layers/PCompositorChild.h"
 
+namespace base {
+  class Thread;
+}
+
+using base::Thread;
+
 namespace mozilla {
 namespace layers {
 
 class CompositorChild : public PCompositorChild
 {
 
 public:
-  CompositorChild();
   virtual ~CompositorChild();
 
+  static CompositorChild* CreateCompositor();
+
 protected:
-  virtual PLayersChild* AllocPLayers(const LayersBackend &backend);
+  CompositorChild(Thread* aCompositorThread);
+
+  virtual PLayersChild* AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget);
   virtual bool DeallocPLayers(PLayersChild *aChild);
+
+private:
+  Thread *mCompositorThread;
+
+  DISALLOW_EVIL_CONSTRUCTORS(CompositorChild);
 };
 
 } // lauers
 } // mozilla
 
 #endif // mozilla_layers_CompositorChild_h
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=2 ts=2 et tw=80 : */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Content App.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Benoit Girard <bgirard@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * 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 "CompositorParent.h"
+#include "ShadowLayersParent.h"
+#include "LayerManagerOGL.h"
+
+namespace mozilla {
+namespace layers {
+
+CompositorParent::CompositorParent()
+{
+
+  MOZ_COUNT_CTOR(CompositorParent);
+}
+
+CompositorParent::~CompositorParent()
+{
+  MOZ_COUNT_DTOR(CompositorParent);
+}
+
+bool
+CompositorParent::AnswerInit()
+{
+  CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
+  MessageLoop::current()->PostTask(FROM_HERE, composeTask);
+  return true;
+}
+
+LayerManagerOGL* lm = NULL;
+
+void
+CompositorParent::Composite()
+{
+  CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
+  MessageLoop::current()->PostTask(FROM_HERE, composeTask);
+  if (lm) {
+    lm->EndEmptyTransaction();
+  }
+}
+
+PLayersParent*
+CompositorParent::AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget)
+{
+  if (widget.type() != WidgetDescriptor::TMacChildViewWidget) {
+    NS_ERROR("Invalid widget descriptor\n");
+    return NULL;
+  }
+
+  if (backend == LayerManager::LAYERS_OPENGL) {
+    nsRefPtr<LayerManagerOGL> layerManager = new
+      LayerManagerOGL((nsIWidget*)widget.get_MacChildViewWidget().widgetPtr());
+    lm = layerManager;
+    if (!layerManager->Initialize()) {
+      NS_ERROR("Failed to init OGL Layers");
+      return NULL;
+    }
+
+    ShadowLayerManager* slm = layerManager->AsShadowManager();
+    if (!slm) {
+      return NULL;
+    }
+
+    return new ShadowLayersParent(slm);
+  } else {
+    NS_ERROR("Unsupported backend selected for Async Compositor");
+    return NULL;
+  }
+}
+
+bool
+CompositorParent::DeallocPLayers(PLayersParent* actor)
+{
+  delete actor;
+  return true;
+}
+
+} // namespace layers
+} // namespace mozilla
+
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -43,39 +43,30 @@
 #include "mozilla/layers/PCompositorParent.h"
 #include "mozilla/layers/PLayersParent.h"
 
 namespace mozilla {
 namespace layers {
 
 class CompositorParent : public PCompositorParent
 {
-
+  NS_INLINE_DECL_REFCOUNTING(CompositorParent)
 public:
-  CompositorParent() {}
-  virtual ~CompositorParent() {}
+  CompositorParent();
+  virtual ~CompositorParent();
 
-  bool AnswerInit() {
-    printf("Answer init\n");
-    return true;
-  }
+  bool AnswerInit();
 
 protected:
-  virtual PLayersParent* AllocPLayers(const LayersBackend &backend) {
-    printf("Alloc PLayers :)\n");
-    //ShadowLayerManager* slm = aLayerManager->AsShadowManager();
-    //if (!slm) {
-       return nsnull;
-    //}
+  virtual PLayersParent* AllocPLayers(const LayersBackend &backend, const WidgetDescriptor &widget);
+
+  virtual bool DeallocPLayers(PLayersParent* aLayers);
 
-    //return new ShadowLayersParent(slm);
-  }
+private:
+  void Composite();
 
-  virtual bool DeallocPLayers(PLayersParent* aLayers) {
-    delete aLayers;
-    return true;
-   }
+  DISALLOW_EVIL_CONSTRUCTORS(CompositorParent);
 };
 
 } // layers
 } // mozilla
 
 #endif // mozilla_layers_CompositorParent_h
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -36,34 +36,46 @@
  * 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 protocol PLayers;
 
 using mozilla::LayersBackend;
+using mozilla::null_t;
 
 namespace mozilla {
 namespace layers {
 
+// The Compositor needs to know about the widget to initialize the LayerManager.
+struct MacChildViewWidget {
+  uintptr_t widgetPtr;
+};
+
+// Gives platform specific information about the widget to initialize the LayerManager.
+union WidgetDescriptor {
+  MacChildViewWidget;
+  null_t;
+};
+
 /**
  * The PCompositor protocol is used to manage communication between
  * the main thread and the compositor thread context. It's primary
  * purpose is to manage the PLayers sub protocol.
  */
 rpc protocol PCompositor
 {
   // Compositor can manage many Layer Manager (PLayers)
   manages PLayers;
 
 parent:  
 
   rpc Init();
-  async PLayers(LayersBackend backend);
+  async PLayers(LayersBackend backend, WidgetDescriptor widgetDescriptor);
 
 //parent:
 //  rpc PLayers();
 
 };
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -276,16 +276,17 @@ ShadowLayersParent::RecvUpdate(const Inf
       break;
     }
 
       // Tree ops
     case Edit::TOpSetRoot: {
       MOZ_LAYERS_LOG(("[ParentSide] SetRoot"));
 
       mRoot = AsShadowLayer(edit.get_OpSetRoot())->AsContainer();
+      mLayerManager->SetRoot(mRoot);
       break;
     }
     case Edit::TOpInsertAfter: {
       MOZ_LAYERS_LOG(("[ParentSide] InsertAfter"));
 
       const OpInsertAfter& oia = edit.get_OpInsertAfter();
       ShadowContainer(oia)->AsContainer()->InsertAfter(
         ShadowChild(oia)->AsLayer(), ShadowAfter(oia)->AsLayer());
@@ -377,17 +378,19 @@ ShadowLayersParent::RecvUpdate(const Inf
     reply->AppendElements(&replyv.front(), replyv.size());
   }
 
   // Ensure that any pending operations involving back and front
   // buffers have completed, so that neither process stomps on the
   // other's buffer contents.
   ShadowLayerManager::PlatformSyncBeforeReplyUpdate();
 
-  Frame()->ShadowLayersUpdated();
+  if (Frame()) {
+    Frame()->ShadowLayersUpdated();
+  }
 
   return true;
 }
 
 PLayerParent*
 ShadowLayersParent::AllocPLayer()
 {
   return new ShadowLayerParent();
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -781,48 +781,62 @@ LayerManagerOGL::Render()
   SetupBackBuffer(width, height);
   SetupPipeline(width, height, ApplyWorldTransform);
 
   // Default blend function implements "OVER"
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE);
   mGLContext->fEnable(LOCAL_GL_BLEND);
 
-  const nsIntRect *clipRect = mRoot->GetClipRect();
+  const nsIntRect *clipRect = NULL;// = mRoot->GetClipRect();
 
   if (clipRect) {
     nsIntRect r = *clipRect;
     WorldTransformRect(r);
     mGLContext->fScissor(r.x, r.y, r.width, r.height);
   } else {
     mGLContext->fScissor(0, 0, width, height);
   }
 
-  mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
+  //mGLContext->fEnable(LOCAL_GL_SCISSOR_TEST);
 
   mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
   mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
 
+  ShadowLayer *shadow = RootLayer()->GetLayer()->AsShadowLayer();
+  if (shadow) {
+    shadow->SetShadowVisibleRegion(nsIntRect(0, 0, width, height));
+    for (Layer* child = RootLayer()->GetLayer()->GetFirstChild(); child; child = child->GetNextSibling()) {
+      for (Layer* child2 = child->GetFirstChild(); child2; child2 = child2->GetNextSibling()) {
+      for (Layer* child3 = child2->GetFirstChild(); child3; child3 = child3->GetNextSibling()) {
+       child3->AsShadowLayer()->SetShadowVisibleRegion(nsIntRect(0, 0, width, height));
+      }
+       child2->AsShadowLayer()->SetShadowVisibleRegion(nsIntRect(0, 0, width, height));
+      }
+     child->AsShadowLayer()->SetShadowVisibleRegion(nsIntRect(0, 0, width, height));
+    }
+  }
+
   // Render our layers.
   RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
                            nsIntPoint(0, 0));
                            
   mWidget->DrawOver(this, rect);
 
   if (mTarget) {
     CopyToTarget();
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   if (sDrawFPS) {
     mFPS.DrawFPS(mGLContext, GetCopy2DProgram());
   }
 
-  if (mGLContext->IsDoubleBuffered()) {
+  if (true || mGLContext->IsDoubleBuffered()) {
     mGLContext->SwapBuffers();
     mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     return;
   }
 
   mGLContext->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
   mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
--- a/widget/src/cocoa/nsChildView.mm
+++ b/widget/src/cocoa/nsChildView.mm
@@ -89,16 +89,18 @@
 #include "GLContext.h"
 
 #include "mozilla/Preferences.h"
 
 #include <dlfcn.h>
 
 #include <ApplicationServices/ApplicationServices.h>
 
+extern NSOpenGLContext* nsGLContext;
+
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 using namespace mozilla::widget;
 using namespace mozilla;
 
 #undef DEBUG_UPDATE
 #undef INVALIDATE_DEBUGGING  // flash areas as they are invalidated
@@ -2549,28 +2551,45 @@ 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(nsnull)->GetBackendType() == LayerManager::LAYERS_OPENGL) {
-    LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(mGeckoChild->GetLayerManager(nsnull));
-    manager->SetClippingRegion(paintEvent.region); 
+  if (mGeckoChild->GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_OPENGL ||
+      mGeckoChild->GetLayerManager(nsnull)->AsShadowManager() != NULL) {
+    //LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(mGeckoChild->GetLayerManager(nsnull));
+    //manager->SetClippingRegion(paintEvent.region);
     if (!mGLContext) {
-      mGLContext = (NSOpenGLContext *)manager->gl()->GetNativeData(mozilla::gl::GLContext::NativeGLContext);
+      //mGLContext = (NSOpenGLContext *)manager->gl()->GetNativeData(mozilla::gl::GLContext::NativeGLContext);
+      mGLContext = nsGLContext;
       [mGLContext retain];
     }
     mGeckoChild->DispatchWindowEvent(paintEvent);
 
     // Force OpenGL to refresh the very first time we draw. This works around a
     // Mac OS X bug that stops windows updating on OS X when we use OpenGL.
     if (!mDidForceRefreshOpenGL) {
+  // Create Cairo objects.
+  NSSize bufferSize = [self bounds].size;
+  nsRefPtr<gfxQuartzSurface> targetSurface =
+    new gfxQuartzSurface(aContext, gfxSize(bufferSize.width, bufferSize.height));
+  targetSurface->SetAllowUseAsSource(false);
+
+  nsRefPtr<gfxContext> targetContext = new gfxContext(targetSurface);
+
+  nsAutoRetainCocoaObject kungFuDeathGrip(self);
+  bool painted;
+  {
+    nsBaseWidget::AutoLayerManagerSetup *setupLayerManager = new nsBaseWidget::AutoLayerManagerSetup(mGeckoChild, targetContext, BasicLayerManager::BUFFER_NONE);
+    painted = mGeckoChild->DispatchWindowEvent(paintEvent);
+  }
+
       [self performSelector:@selector(forceRefreshOpenGL) withObject:nil afterDelay:0];
       mDidForceRefreshOpenGL = YES;
     }
 
     return;
   }
 
   // Create Cairo objects.
--- a/widget/src/xpwidgets/nsBaseWidget.cpp
+++ b/widget/src/xpwidgets/nsBaseWidget.cpp
@@ -840,48 +840,62 @@ LayerManager* nsBaseWidget::GetLayerMana
                                             bool* aAllowRetaining)
 {
   if (!mLayerManager) {
 
     mUseAcceleratedRendering = GetShouldAccelerate();
 
     if (mUseAcceleratedRendering) {
 
-      nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
-      /**
-       * XXX - On several OSes initialization is expected to fail for now.
-       * If we'd get a none-basic layer manager they'd crash. This is ok though
-       * since on those platforms it will fail. Anyone implementing new
-       * platforms on LayerManagerOGL should ensure their widget is able to
-       * deal with it though!
-       */
-      if (layerManager->Initialize()) {
-        mLayerManager = layerManager;
-        // TODO Refactor me to support one compositor to many layer manager
-        bool useCompositor =
-          Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
-        if (useCompositor) {
-          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();
-            mozilla::ipc::AsyncChannel *parentChannel = compositorParent->GetIPCChannel();
-            mozilla::ipc::AsyncChannel *childChannel = compositorChild->GetIPCChannel();
-            mozilla::ipc::AsyncChannel::Side childSide =
-              mozilla::ipc::AsyncChannel::Child;
+      // Try to use an async compositor first, if possible
+      bool useCompositor =
+        Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
+      if (useCompositor) {
+        CompositorChild *compositorChild = CompositorChild::CreateCompositor();
+
+        if (compositorChild) {
+          // 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 = MacChildViewWidget((uintptr_t)dynamic_cast<nsIWidget*>(this));
+          PLayersChild* shadowManager = compositorChild->SendPLayersConstructor(
+                                          LayerManager::LAYERS_OPENGL,
+                                          desc);
 
-            compositorChild->Open(parentChannel, childMessageLoop, childSide);
-            compositorChild->CallInit();
-            LayerManager::LayersBackend be;
-            PLayersChild* shadowManager = compositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL);
+          if (shadowManager) {
+            LayerManager* lm = CreateBasicLayerManager();
+            ShadowLayerForwarder* lf = lm->AsShadowForwarder();
+            if (!lf) {
+              delete lm;
+              delete compositorChild;
+            }
+            lf->SetShadowManager(shadowManager);
+            printf("Async layer manager\n");
+
+            mLayerManager = lm;
+          } else {
+            NS_WARNING("fail to construct LayersChild");
+            delete compositorChild;
           }
         }
       }
+
+      if (!mLayerManager) {
+        nsRefPtr<LayerManagerOGL> layerManager = new LayerManagerOGL(this);
+        /**
+         * XXX - On several OSes initialization is expected to fail for now.
+         * If we'd get a none-basic layer manager they'd crash. This is ok though
+         * since on those platforms it will fail. Anyone implementing new
+         * platforms on LayerManagerOGL should ensure their widget is able to
+         * deal with it though!
+         */
+        if (layerManager->Initialize()) {
+          mLayerManager = layerManager;
+        }
+      }
     }
     if (!mLayerManager) {
       mBasicLayerManager = mLayerManager = CreateBasicLayerManager();
     }
   }
   if (mTemporarilyUseBasicLayerManager && !mBasicLayerManager) {
     mBasicLayerManager = CreateBasicLayerManager();
   }