Bug 889515 - Get rid of static sCompositorParent. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 11 Jul 2013 22:32:09 -0400
changeset 139204 3e969b1777a7db826491fdb887693909c77e3898
parent 139203 d220422b5e8da3bb187e5aa1f42dc86c16bc412d
child 139205 dabdd7ceb43eb52cae4aef7a030d65e7b48959e5
push idunknown
push userunknown
push dateunknown
reviewersnical
bugs889515
milestone25.0a1
Bug 889515 - Get rid of static sCompositorParent. r=nical
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
gfx/layers/ipc/PCompositor.ipdl
gfx/layers/ipc/ShadowLayers.cpp
layout/ipc/RenderFrameParent.cpp
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -227,24 +227,34 @@ ClientLayerManager::EndEmptyTransaction(
   if (mWidget) {
     mWidget->PrepareWindowEffects();
   }
   ForwardTransaction();
   MakeSnapshotIfRequired();
   return true;
 }
 
+CompositorChild *
+ClientLayerManager::GetRemoteRenderer()
+{
+  if (!mWidget) {
+    return nullptr;
+  }
+
+  return mWidget->GetRemoteRenderer();
+}
+
 void 
 ClientLayerManager::MakeSnapshotIfRequired()
 {
   if (!mShadowTarget) {
     return;
   }
   if (mWidget) {
-    if (CompositorChild* remoteRenderer = mWidget->GetRemoteRenderer()) {
+    if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
       nsIntRect bounds;
       mWidget->GetBounds(bounds);
       SurfaceDescriptor inSnapshot, snapshot;
       if (AllocSurfaceDescriptor(bounds.Size(),
                                  gfxASurface::CONTENT_COLOR_ALPHA,
                                  &inSnapshot) &&
           // The compositor will usually reuse |snapshot| and return
           // it through |outSnapshot|, but if it doesn't, it's
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -48,16 +48,21 @@ public:
 
   virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
   virtual already_AddRefed<CanvasLayer> CreateCanvasLayer();
   virtual already_AddRefed<ColorLayer> CreateColorLayer();
   virtual already_AddRefed<RefLayer> CreateRefLayer();
 
+  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
+  {
+    return mTextureFactoryIdentifier;
+  }
+
   virtual void FlushRendering() MOZ_OVERRIDE;
 
   virtual bool NeedsWidgetInvalidation() MOZ_OVERRIDE { return false; }
 
   ShadowableLayer* Hold(Layer* aLayer);
 
   bool HasShadowManager() const { return ShadowLayerForwarder::HasShadowManager(); }
 
@@ -84,16 +89,18 @@ public:
   bool CompositorMightResample() { return mCompositorMightResample; } 
   
   DrawThebesLayerCallback GetThebesLayerCallback() const
   { return mThebesLayerCallback; }
 
   void* GetThebesLayerCallbackData() const
   { return mThebesLayerCallbackData; }
 
+  CompositorChild *GetRemoteRenderer();
+
   /**
    * Called for each iteration of a progressive tile update. Fills
    * aViewport, aScaleX and aScaleY with the current scale and viewport
    * being used to composite the layers in this manager, to determine what area
    * intersects with the target render rectangle. aDrawingCritical will be
    * true if the current drawing operation is using the critical displayport.
    * Returns true if the update should continue, or false if it should be
    * cancelled.
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -35,20 +35,16 @@ class BasicTiledLayerBuffer;
 class CompositableForwarder : public ISurfaceAllocator
 {
   friend class AutoOpenSurface;
   friend class DeprecatedTextureClientShmem;
 public:
   typedef gfxASurface::gfxContentType gfxContentType;
 
   CompositableForwarder()
-  : mMaxTextureSize(0)
-  , mCompositorBackend(layers::LAYERS_NONE)
-  , mSupportsTextureBlitting(false)
-  , mSupportsPartialUploads(false)
   {}
 
   /**
    * Setup the IPDL actor for aCompositable to be part of layers
    * transactions.
    */
   virtual void Connect(CompositableClient* aCompositable) = 0;
 
@@ -145,43 +141,40 @@ public:
    */
   virtual void DestroyedThebesBuffer(const SurfaceDescriptor& aBackBufferToDestroy) = 0;
 
   void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier);
 
   /**
    * Returns the maximum texture size supported by the compositor.
    */
-  virtual int32_t GetMaxTextureSize() const { return mMaxTextureSize; }
+  virtual int32_t GetMaxTextureSize() const { return mTextureFactoryIdentifier.mMaxTextureSize; }
 
   bool IsOnCompositorSide() const MOZ_OVERRIDE { return false; }
 
   /**
    * Returns the type of backend that is used off the main thread.
    * We only don't allow changing the backend type at runtime so this value can
    * be queried once and will not change until Gecko is restarted.
    */
   LayersBackend GetCompositorBackendType() const
   {
-    return mCompositorBackend;
+    return mTextureFactoryIdentifier.mParentBackend;
   }
 
   bool SupportsTextureBlitting() const
   {
-    return mSupportsTextureBlitting;
+    return mTextureFactoryIdentifier.mSupportsTextureBlitting;
   }
 
   bool SupportsPartialUploads() const
   {
-    return mSupportsPartialUploads;
+    return mTextureFactoryIdentifier.mSupportsPartialUploads;
   }
 
 protected:
-  uint32_t mMaxTextureSize;
-  LayersBackend mCompositorBackend;
-  bool mSupportsTextureBlitting;
-  bool mSupportsPartialUploads;
+  TextureFactoryIdentifier mTextureFactoryIdentifier;
 };
 
 } // namespace
 } // namespace
 
 #endif
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -31,17 +31,16 @@ using namespace mozilla::ipc;
 using namespace std;
 
 namespace mozilla {
 namespace layers {
 
 // FIXME/bug 774386: we're assuming that there's only one
 // CompositorParent, but that's not always true.  This assumption only
 // affects CrossProcessCompositorParent below.
-static CompositorParent* sCurrentCompositor;
 static Thread* sCompositorThread = nullptr;
 // manual reference count of the compositor thread.
 static int sCompositorThreadRefCount = 0;
 static MessageLoop* sMainLoop = nullptr;
 // When ContentParent::StartUp() is called, we use the Thread global.
 // When StartUpWithExistingThread() is used, we have to use the two
 // duplicated globals, because there's no API to make a Thread from an
 // existing thread.
@@ -148,35 +147,29 @@ CompositorParent::CompositorParent(nsIWi
   MOZ_COUNT_CTOR(CompositorParent);
   mCompositorID = 0;
   // FIXME: This holds on the the fact that right now the only thing that
   // can destroy this instance is initialized on the compositor thread after
   // this task has been processed.
   CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&AddCompositor,
                                                           this, &mCompositorID));
 
-  if (!sCurrentCompositor) {
-    sCurrentCompositor = this;
-  }
   ++sCompositorThreadRefCount;
 }
 
 PlatformThreadId
 CompositorParent::CompositorThreadID()
 {
   return sCompositorThread ? sCompositorThread->thread_id() : sCompositorThreadID;
 }
 
 CompositorParent::~CompositorParent()
 {
   MOZ_COUNT_DTOR(CompositorParent);
 
-  if (this == sCurrentCompositor) {
-    sCurrentCompositor = NULL;
-  }
   ReleaseCompositorThread();
 }
 
 void
 CompositorParent::Destroy()
 {
   NS_ABORT_IF_FALSE(ManagedPLayerTransactionParent().Length() == 0,
                     "CompositorParent destroyed before managed PLayerTransactionParent");
@@ -672,16 +665,29 @@ CompositorParent::SetTimeAndSampleAnimat
     it->second->mTestTime = aTime;
     it->second->mCompositionManager->TransformShadowTree(aTime);
   }
 }
 
 typedef map<uint64_t, CompositorParent::LayerTreeState> LayerTreeMap;
 static LayerTreeMap sIndirectLayerTrees;
 
+bool
+CompositorParent::RecvNotifyChildCreated(const uint64_t& child)
+{
+  NotifyChildCreated(child);
+  return true;
+}
+
+void
+CompositorParent::NotifyChildCreated(uint64_t aChild)
+{
+  sIndirectLayerTrees[aChild].mParent = this;
+}
+
 /*static*/ uint64_t
 CompositorParent::AllocateLayerTreeId()
 {
   MOZ_ASSERT(CompositorLoop());
   MOZ_ASSERT(NS_IsMainThread());
   static uint64_t ids;
   return ++ids;
 }
@@ -705,17 +711,17 @@ UpdateControllerForLayersId(uint64_t aLa
                             AsyncPanZoomController* aController)
 {
   // Adopt ref given to us by SetPanZoomControllerForLayerTree()
   sIndirectLayerTrees[aLayersId].mController =
     already_AddRefed<AsyncPanZoomController>(aController);
 
   // Notify the AsyncPanZoomController about the current compositor so that it
   // can request composites off the compositor thread.
-  aController->SetCompositorParent(sCurrentCompositor);
+  aController->SetCompositorParent(sIndirectLayerTrees[aLayersId].mParent);
 }
 
 /*static*/ void
 CompositorParent::SetPanZoomControllerForLayerTree(uint64_t aLayersId,
                                                    AsyncPanZoomController* aController)
 {
   // This ref is adopted by UpdateControllerForLayersId().
   aController->AddRef();
@@ -747,16 +753,17 @@ public:
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   // FIXME/bug 774388: work out what shutdown protocol we need.
   virtual bool RecvWillStop() MOZ_OVERRIDE { return true; }
   virtual bool RecvStop() MOZ_OVERRIDE { return true; }
   virtual bool RecvPause() MOZ_OVERRIDE { return true; }
   virtual bool RecvResume() MOZ_OVERRIDE { return true; }
+  virtual bool RecvNotifyChildCreated(const uint64_t& child) MOZ_OVERRIDE;
   virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
                                 SurfaceDescriptor* aOutSnapshot)
   { return true; }
   virtual bool RecvFlushRendering() MOZ_OVERRIDE { return true; }
 
   virtual PLayerTransactionParent*
     AllocPLayerTransactionParent(const LayersBackend& aBackendType,
                                  const uint64_t& aId,
@@ -846,45 +853,57 @@ CrossProcessCompositorParent::ActorDestr
 
 PLayerTransactionParent*
 CrossProcessCompositorParent::AllocPLayerTransactionParent(const LayersBackend& aBackendType,
                                                            const uint64_t& aId,
                                                            TextureFactoryIdentifier* aTextureFactoryIdentifier)
 {
   MOZ_ASSERT(aId != 0);
 
-  nsRefPtr<LayerManager> lm = sCurrentCompositor->GetLayerManager();
-  *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
-  return new LayerTransactionParent(lm->AsLayerManagerComposite(), this, aId);
+  if (sIndirectLayerTrees[aId].mParent) {
+    nsRefPtr<LayerManager> lm = sIndirectLayerTrees[aId].mParent->GetLayerManager();
+    *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
+    return new LayerTransactionParent(lm->AsLayerManagerComposite(), this, aId);
+  }
+
+  NS_WARNING("Created child without a matching parent?");
+  return new LayerTransactionParent(nullptr, this, aId);
 }
 
 bool
 CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
 {
   LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
   RemoveIndirectTree(slp->GetId());
   delete aLayers;
   return true;
 }
 
+bool
+CrossProcessCompositorParent::RecvNotifyChildCreated(const uint64_t& child)
+{
+  sIndirectLayerTrees[child].mParent->NotifyChildCreated(child);
+  return true;
+}
+
 void
 CrossProcessCompositorParent::ShadowLayersUpdated(
   LayerTransactionParent* aLayerTree,
   const TargetConfig& aTargetConfig,
   bool isFirstPaint)
 {
   uint64_t id = aLayerTree->GetId();
   MOZ_ASSERT(id != 0);
   Layer* shadowRoot = aLayerTree->GetRoot();
   if (shadowRoot) {
     SetShadowProperties(shadowRoot);
   }
   UpdateIndirectTree(id, shadowRoot, aTargetConfig, isFirstPaint);
 
-  sCurrentCompositor->NotifyShadowTreeTransaction();
+  sIndirectLayerTrees[id].mParent->NotifyShadowTreeTransaction();
 }
 
 void
 CrossProcessCompositorParent::DeferredDestroy()
 {
   mSelfRef = nullptr;
   // |this| was just destroyed, hands off
 }
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -48,16 +48,17 @@ public:
                    int aSurfaceWidth = -1, int aSurfaceHeight = -1);
 
   virtual ~CompositorParent();
 
   virtual bool RecvWillStop() MOZ_OVERRIDE;
   virtual bool RecvStop() MOZ_OVERRIDE;
   virtual bool RecvPause() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
+  virtual bool RecvNotifyChildCreated(const uint64_t& child) MOZ_OVERRIDE;
   virtual bool RecvMakeSnapshot(const SurfaceDescriptor& aInSnapshot,
                                 SurfaceDescriptor* aOutSnapshot);
   virtual bool RecvFlushRendering() MOZ_OVERRIDE;
 
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
   virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
                                    const TargetConfig& aTargetConfig,
@@ -69,16 +70,18 @@ public:
    * The information refresh happens because the compositor will call
    * SetFirstPaintViewport on the next frame of composition.
    */
   void ForceIsFirstPaint();
   void Destroy();
 
   LayerManagerComposite* GetLayerManager() { return mLayerManager; }
 
+  void NotifyChildCreated(uint64_t aChild);
+
   void AsyncRender();
 
   // Can be called from any thread
   void ScheduleRenderOnCompositorThread();
   void SchedulePauseOnCompositorThread();
   /**
    * Returns true if a surface was obtained and the resume succeeded; false
    * otherwise.
@@ -147,16 +150,17 @@ public:
    * extra synchronization and call ::Composite() right from toolkit::Paint event
    */
   static void StartUpWithExistingThread(MessageLoop* aMsgLoop,
                                         PlatformThreadId aThreadID);
 
   struct LayerTreeState {
     nsRefPtr<Layer> mRoot;
     nsRefPtr<AsyncPanZoomController> mController;
+    CompositorParent *mParent;
     TargetConfig mTargetConfig;
   };
 
   /**
    * Lookup the indirect shadow tree for |aId| and return it if it
    * exists.  Otherwise null is returned.  This must only be called on
    * the compositor thread.
    */
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -38,16 +38,18 @@ parent:
   // Clean up in preparation for own destruction.
   sync Stop();
 
   // Pause/resume the compositor. These are intended to be used on mobile, when
   // the compositor needs to pause/resume in lockstep with the application.
   sync Pause();
   sync Resume();
 
+  async NotifyChildCreated(uint64_t id);
+
   // Make a snapshot of the content that would have been drawn to our
   // render target at the time this message is received.  If the size
   // or format of |inSnapshot| doesn't match our render target,
   // results are undefined.
   //
   // NB: this message will result in animations, transforms, effects,
   // and so forth being interpolated.  That's what we want to happen.
   sync MakeSnapshot(SurfaceDescriptor inSnapshot)
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -155,20 +155,17 @@ struct AutoTxnEnd {
   AutoTxnEnd(Transaction* aTxn) : mTxn(aTxn) {}
   ~AutoTxnEnd() { mTxn->End(); }
   Transaction* mTxn;
 };
 
 void
 CompositableForwarder::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
 {
-  mMaxTextureSize = aIdentifier.mMaxTextureSize;
-  mCompositorBackend = aIdentifier.mParentBackend;
-  mSupportsTextureBlitting = aIdentifier.mSupportsTextureBlitting;
-  mSupportsPartialUploads = aIdentifier.mSupportsPartialUploads;
+  mTextureFactoryIdentifier = aIdentifier;
 }
 
 ShadowLayerForwarder::ShadowLayerForwarder()
  : mShadowManager(NULL)
  , mIsFirstPaint(false)
  , mDrawColoredBorders(false)
  , mWindowOverlayChanged(false)
 {
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -21,16 +21,18 @@
 #include "nsContentUtils.h"
 #include "nsFrameLoader.h"
 #include "nsIObserver.h"
 #include "nsSubDocumentFrame.h"
 #include "nsView.h"
 #include "nsViewportFrame.h"
 #include "RenderFrameParent.h"
 #include "mozilla/layers/LayerManagerComposite.h"
+#include "mozilla/layers/CompositorChild.h"
+#include "ClientLayerManager.h"
 
 typedef nsContentView::ViewConfig ViewConfig;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 namespace mozilla {
 namespace layout {
 
@@ -597,26 +599,30 @@ RenderFrameParent::RenderFrameParent(nsF
 {
   mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
     new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID);
 
   *aId = 0;
 
   nsRefPtr<LayerManager> lm = GetFrom(mFrameLoader);
   // Perhaps the document containing this frame currently has no presentation?
-  if (lm && lm->AsLayerManagerComposite()) {
+  if (lm && lm->GetBackendType() == LAYERS_CLIENT) {
     *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
   } else {
     *aTextureFactoryIdentifier = TextureFactoryIdentifier();
   }
 
   if (CompositorParent::CompositorLoop()) {
     // Our remote frame will push layers updates to the compositor,
     // and we'll keep an indirect reference to that tree.
     *aId = mLayersId = CompositorParent::AllocateLayerTreeId();
+    if (lm && lm->GetBackendType() == LAYERS_CLIENT) {
+      ClientLayerManager *clientManager = static_cast<ClientLayerManager*>(lm.get());
+      clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
+    }
     if (aScrollingBehavior == ASYNC_PAN_ZOOM) {
       mContentController = new RemoteContentController(this);
       mPanZoomController = new AsyncPanZoomController(
         mContentController, AsyncPanZoomController::USE_GESTURE_DETECTOR);
       CompositorParent::SetPanZoomControllerForLayerTree(mLayersId,
                                                          mPanZoomController);
     }
   }