Bug 745148, part 6: Allow layer trees to be given IDs so that the referent can be used in another context. r=ajuma sr=roc
authorChris Jones <jones.chris.g@gmail.com>
Tue, 17 Jul 2012 16:59:45 -0700
changeset 102722 1df6cd42330dc2520947b5e4f5c92b76bf82fe80
parent 102721 13059586b02b1995f94e5334f7eb265669f42d6c
child 102723 100fd0a81f9ec5709db6c61e2e1af5d956601ed4
push id1989
push userakeybl@mozilla.com
push dateTue, 28 Aug 2012 00:20:43 +0000
treeherdermozilla-aurora@a8e95ae10ea7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajuma, roc
bugs745148
milestone17.0a1
Bug 745148, part 6: Allow layer trees to be given IDs so that the referent can be used in another context. r=ajuma sr=roc
dom/ipc/TabChild.cpp
gfx/layers/Layers.h
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/ipc/ShadowLayersParent.h
layout/ipc/PRenderFrame.ipdl
layout/ipc/RenderFrameChild.cpp
layout/ipc/RenderFrameChild.h
layout/ipc/RenderFrameParent.cpp
layout/ipc/RenderFrameParent.h
widget/xpwidgets/nsBaseWidget.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -1026,17 +1026,18 @@ TabChild::InitWidget(const nsIntSize& si
       NS_WARNING("failed to construct RenderFrame");
       return false;
     }
 
     NS_ABORT_IF_FALSE(0 == remoteFrame->ManagedPLayersChild().Length(),
                       "shouldn't have a shadow manager yet");
     LayerManager::LayersBackend be;
     PRInt32 maxTextureSize;
-    PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be, &maxTextureSize);
+    uint64_t id;
+    PLayersChild* shadowManager = remoteFrame->SendPLayersConstructor(&be, &maxTextureSize, &id);
     if (!shadowManager) {
       NS_WARNING("failed to construct LayersChild");
       // This results in |remoteFrame| being deleted.
       PRenderFrameChild::Send__delete__(remoteFrame);
       return false;
     }
 
     ShadowLayerForwarder* lf =
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -203,17 +203,17 @@ public:
     LAYERS_NONE = 0,
     LAYERS_BASIC,
     LAYERS_OPENGL,
     LAYERS_D3D9,
     LAYERS_D3D10,
     LAYERS_LAST
   };
 
-  LayerManager() : mDestroyed(false), mSnapEffectiveTransforms(true)
+  LayerManager() : mDestroyed(false), mSnapEffectiveTransforms(true), mId(0)
   {
     InitLog();
   }
   virtual ~LayerManager() {}
 
   /**
    * Release layers and resources held by this layer manager, and mark
    * it as destroyed.  Should do any cleanup necessary in preparation
@@ -513,16 +513,17 @@ protected:
   bool mSnapEffectiveTransforms;
 
   // Print interesting information about this into aTo.  Internally
   // used to implement Dump*() and Log*().
   virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
 
   static void InitLog();
   static PRLogModuleInfo* sLog;
+  uint64_t mId;
 private:
   TimeStamp mLastFrameTime;
   nsTArray<float> mFrameTimes;
 };
 
 class ThebesLayer;
 
 /**
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -37,17 +37,17 @@ CompositorChild::Destroy()
     ShadowLayersChild* layers =
       static_cast<ShadowLayersChild*>(ManagedPLayersChild()[0]);
     layers->Destroy();
   }
   SendStop();
 }
 
 PLayersChild*
-CompositorChild::AllocPLayers(const LayersBackend &aBackend, int* aMaxTextureSize)
+CompositorChild::AllocPLayers(const LayersBackend &aBackend, const uint64_t& aId, int* aMaxTextureSize)
 {
   return new ShadowLayersChild();
 }
 
 bool
 CompositorChild::DeallocPLayers(PLayersChild* actor)
 {
   delete actor;
--- a/gfx/layers/ipc/CompositorChild.h
+++ b/gfx/layers/ipc/CompositorChild.h
@@ -20,17 +20,17 @@ class CompositorChild : public PComposit
   NS_INLINE_DECL_REFCOUNTING(CompositorChild)
 public:
   CompositorChild(LayerManager *aLayerManager);
   virtual ~CompositorChild();
 
   void Destroy();
 
 protected:
-  virtual PLayersChild* AllocPLayers(const LayersBackend &aBackend, int* aMaxTextureSize);
+  virtual PLayersChild* AllocPLayers(const LayersBackend &aBackend, const uint64_t& aId, int* aMaxTextureSize);
   virtual bool DeallocPLayers(PLayersChild *aChild);
 
 private:
   nsRefPtr<LayerManager> mLayerManager;
 
   DISALLOW_EVIL_CONSTRUCTORS(CompositorChild);
 };
 
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -534,18 +534,22 @@ CompositorParent::ShadowLayersUpdated(Sh
   mLayerManager->SetRoot(root);
   if (root) {
     SetShadowProperties(root);
   }
   ScheduleComposition();
 }
 
 PLayersParent*
-CompositorParent::AllocPLayers(const LayersBackend& aBackendType, int* aMaxTextureSize)
+CompositorParent::AllocPLayers(const LayersBackend& aBackendType,
+                               const uint64_t& aId,
+                               int32_t* aMaxTextureSize)
 {
+  MOZ_ASSERT(aId == 0);
+
   // mWidget doesn't belong to the compositor thread, so it should be set to
   // NULL before returning from this method, to avoid accessing it elsewhere.
   nsIntRect rect;
   mWidget->GetBounds(rect);
   mWidgetSize.width = rect.width;
   mWidgetSize.height = rect.height;
 
   if (aBackendType == LayerManager::LAYERS_OPENGL) {
@@ -564,27 +568,27 @@ CompositorParent::AllocPLayers(const Lay
       return NULL;
     }
 
     ShadowLayerManager* slm = layerManager->AsShadowManager();
     if (!slm) {
       return NULL;
     }
     *aMaxTextureSize = layerManager->GetMaxTextureSize();
-    return new ShadowLayersParent(slm, this);
+    return new ShadowLayersParent(slm, this, 0);
   } else if (aBackendType == LayerManager::LAYERS_BASIC) {
     nsRefPtr<LayerManager> layerManager = new BasicShadowLayerManager(mWidget);
     mWidget = NULL;
     mLayerManager = layerManager;
     ShadowLayerManager* slm = layerManager->AsShadowManager();
     if (!slm) {
       return NULL;
     }
     *aMaxTextureSize = layerManager->GetMaxTextureSize();
-    return new ShadowLayersParent(slm, this);
+    return new ShadowLayersParent(slm, this, 0);
   } else {
     NS_ERROR("Unsupported backend selected for Async Compositor");
     return NULL;
   }
 }
 
 bool
 CompositorParent::DeallocPLayers(PLayersParent* actor)
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -102,17 +102,17 @@ public:
   static void StartUp();
 
   /**
    * Destroys the compositor thread and the global compositor map.
    */
   static void ShutDown();
 
 protected:
-  virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, int* aMaxTextureSize);
+  virtual PLayersParent* AllocPLayers(const LayersBackend& aBackendType, const uint64_t& aId, int32_t* aMaxTextureSize);
   virtual bool DeallocPLayers(PLayersParent* aLayers);
   virtual void ScheduleTask(CancelableTask*, int);
   virtual void Composite();
   virtual void SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom, const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect);
   virtual void SetPageRect(const gfx::Rect& aCssPageRect);
   virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
                                 nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
   void SetEGLSurfaceSize(int width, int height);
--- a/gfx/layers/ipc/PCompositor.ipdl
+++ b/gfx/layers/ipc/PCompositor.ipdl
@@ -33,14 +33,14 @@ 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();
 
-  sync PLayers(LayersBackend backend)
-    returns (int maxTextureSize);
+  sync PLayers(LayersBackend backend, uint64_t id)
+    returns (int32_t maxTextureSize);
 };
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -85,18 +85,22 @@ static ShadowLayerParent*
 ShadowChild(const OpRemoveChild& op)
 {
   return cast(op.childLayerParent());
 }
 
 //--------------------------------------------------
 // ShadowLayersParent
 ShadowLayersParent::ShadowLayersParent(ShadowLayerManager* aManager,
-                                       ShadowLayersManager* aLayersManager)
-  : mLayerManager(aManager), mShadowLayersManager(aLayersManager), mDestroyed(false)
+                                       ShadowLayersManager* aLayersManager,
+                                       uint64_t aId)
+  : mLayerManager(aManager)
+  , mShadowLayersManager(aLayersManager)
+  , mId(aId)
+  , mDestroyed(false)
 {
   MOZ_COUNT_CTOR(ShadowLayersParent);
 }
 
 ShadowLayersParent::~ShadowLayersParent()
 {
   MOZ_COUNT_DTOR(ShadowLayersParent);
 }
--- a/gfx/layers/ipc/ShadowLayersParent.h
+++ b/gfx/layers/ipc/ShadowLayersParent.h
@@ -26,23 +26,26 @@ class ShadowLayerManager;
 class ShadowLayersParent : public PLayersParent,
                            public ISurfaceDeAllocator
 {
   typedef mozilla::layout::RenderFrameParent RenderFrameParent;
   typedef InfallibleTArray<Edit> EditArray;
   typedef InfallibleTArray<EditReply> EditReplyArray;
 
 public:
-  ShadowLayersParent(ShadowLayerManager* aManager, ShadowLayersManager* aLayersManager);
+  ShadowLayersParent(ShadowLayerManager* aManager,
+                     ShadowLayersManager* aLayersManager,
+                     uint64_t aId);
   ~ShadowLayersParent();
 
   void Destroy();
 
   ShadowLayerManager* layer_manager() const { return mLayerManager; }
 
+  uint64_t GetId() const { return mId; }
   ContainerLayer* GetRoot() const { return mRoot; }
 
   virtual void DestroySharedSurface(gfxSharedImageSurface* aSurface);
   virtual void DestroySharedSurface(SurfaceDescriptor* aSurface);
 
 protected:
   virtual bool RecvUpdate(const EditArray& cset,
                           const bool& isFirstPaint,
@@ -64,16 +67,21 @@ protected:
   virtual bool DeallocPLayer(PLayerParent* actor) MOZ_OVERRIDE;
 
 private:
   nsRefPtr<ShadowLayerManager> mLayerManager;
   ShadowLayersManager* mShadowLayersManager;
   // Hold the root because it might be grafted under various
   // containers in the "real" layer tree
   nsRefPtr<ContainerLayer> mRoot;
+  // When this is nonzero, it refers to a layer tree owned by the
+  // compositor thread.  It is always true that
+  //   mId != 0 => mRoot == null
+  // because the "real tree" is owned by the compositor.
+  uint64_t mId;
   // When the widget/frame/browser stuff in this process begins its
   // destruction process, we need to Disconnect() all the currently
   // live shadow layers, because some of them might be orphaned from
   // the layer tree.  This happens in Destroy() above.  After we
   // Destroy() ourself, there's a window in which that information
   // hasn't yet propagated back to the child side and it might still
   // send us layer transactions.  We want to ignore those transactions
   // because they refer to "zombie layers" on this side.  So, we track
--- a/layout/ipc/PRenderFrame.ipdl
+++ b/layout/ipc/PRenderFrame.ipdl
@@ -23,18 +23,29 @@ namespace layout {
  * only makes sense wrt documents loaded by the child.
  */
 sync protocol PRenderFrame
 {
     manager PBrowser;
     manages PLayers;
 
 parent:
-    sync PLayers()
-      returns (LayersBackend backend, int maxTextureSize);
+    /**
+     * Shadow layer trees can be grafted into the parent's in one of
+     * two ways
+     *  - direct shadow tree: updates are sent to parent
+     *  - indirect: the parent holds a reference (ID) to a shadow tree
+     *    that's managed by the compositor.  During composition, the
+     *    shadow tree is looked up and grafted appropriately
+     *
+     * |id| is set to 0 in the "direct" case, and to a whole number
+     * in the "indirect" case.
+     */
+     sync PLayers()
+       returns (LayersBackend backend, int32_t maxTextureSize, uint64_t layersId);
 
     async __delete__();
 
 state EMPTY:
     recv PLayers goto HAVE_CONTENT;
 state HAVE_CONTENT:
     recv __delete__;
 };
--- a/layout/ipc/RenderFrameChild.cpp
+++ b/layout/ipc/RenderFrameChild.cpp
@@ -28,17 +28,18 @@ RenderFrameChild::Destroy()
     // |layers| was just deleted, take care
   }
 
   Send__delete__(this);
   // WARNING: |this| is dead, hands off
 }
 
 PLayersChild*
-RenderFrameChild::AllocPLayers(LayerManager::LayersBackend* aBackendType, int* aMaxTextureSize)
+RenderFrameChild::AllocPLayers(LayerManager::LayersBackend* aBackendType,
+                               int* aMaxTextureSize, uint64_t* aId)
 {
   return new ShadowLayersChild();
 }
 
 bool
 RenderFrameChild::DeallocPLayers(PLayersChild* aLayers)
 {
   delete aLayers;
--- a/layout/ipc/RenderFrameChild.h
+++ b/layout/ipc/RenderFrameChild.h
@@ -18,17 +18,18 @@ class RenderFrameChild : public PRenderF
 public:
   RenderFrameChild() {}
   virtual ~RenderFrameChild() {}
 
   void Destroy();
 
 protected:
   NS_OVERRIDE
-  virtual PLayersChild* AllocPLayers(LayerManager::LayersBackend* aBackendType, int* aMaxTextureSize);
+  virtual PLayersChild* AllocPLayers(LayerManager::LayersBackend* aBackendType,
+                                     int* aMaxTextureSize, uint64_t* aId);
   NS_OVERRIDE
   virtual bool DeallocPLayers(PLayersChild* aLayers);
 };
 
 } // namespace layout
 } // namespace mozilla
 
 #endif  // mozilla_dom_RenderFrameChild_h
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -604,35 +604,44 @@ RenderFrameParent::ActorDestroy(ActorDes
     // better, especially as nothing guarantees another Update() from
     // the "next" remote layer tree.
     mFrameLoader->SetCurrentRemoteFrame(nsnull);
   }
   mFrameLoader = nsnull;
 }
 
 PLayersParent*
-RenderFrameParent::AllocPLayers(LayerManager::LayersBackend* aBackendType, int* aMaxTextureSize)
+RenderFrameParent::AllocPLayers(LayerManager::LayersBackend* aBackendType,
+                                int* aMaxTextureSize,
+                                uint64_t* aId)
 {
+  *aBackendType = LayerManager::LAYERS_NONE;
+  *aMaxTextureSize = 0;
+  *aId = 0;
+
   if (!mFrameLoader || mFrameLoaderDestroyed) {
-    *aBackendType = LayerManager::LAYERS_NONE;
-    *aMaxTextureSize = 0;
     return nsnull;
   }
 
-  nsRefPtr<LayerManager> lm = 
-    nsContentUtils::LayerManagerForDocument(mFrameLoader->GetOwnerDoc());
+  nsIDocument* doc = mFrameLoader->GetOwnerDoc();
+  nsRefPtr<LayerManager> lm = nsContentUtils::LayerManagerForDocument(doc);
   ShadowLayerManager* slm = lm->AsShadowManager();
   if (!slm) {
-    *aBackendType = LayerManager::LAYERS_NONE;
-    *aMaxTextureSize = 0;
      return nsnull;
   }
   *aBackendType = lm->GetBackendType();
   *aMaxTextureSize = lm->GetMaxTextureSize();
-  return new ShadowLayersParent(slm, this);
+#if 0 // Enabled in later patch
+  if (CompositorParent::CompositorLoop()) {
+    // Our remote frame will push layers updates to the compositor,
+    // and we'll keep an indirect reference to that tree.
+    *aId = CompositorParent::AllocateLayerTreeId();
+  }
+#endif
+  return new ShadowLayersParent(slm, this, *aId);
 }
 
 bool
 RenderFrameParent::DeallocPLayers(PLayersParent* aLayers)
 {
   delete aLayers;
   return true;
 }
@@ -676,16 +685,23 @@ RenderFrameParent::GetShadowLayers() con
 {
   const nsTArray<PLayersParent*>& shadowParents = ManagedPLayersParent();
   NS_ABORT_IF_FALSE(shadowParents.Length() <= 1,
                     "can only support at most 1 ShadowLayersParent");
   return (shadowParents.Length() == 1) ?
     static_cast<ShadowLayersParent*>(shadowParents[0]) : nsnull;
 }
 
+uint64_t
+RenderFrameParent::GetLayerTreeId() const
+{
+  ShadowLayersParent* shadowLayers = GetShadowLayers();
+  return shadowLayers ? shadowLayers->GetId() : 0;
+}
+
 ContainerLayer*
 RenderFrameParent::GetRootLayer() const
 {
   ShadowLayersParent* shadowLayers = GetShadowLayers();
   return shadowLayers ? shadowLayers->GetRoot() : nsnull;
 }
 
 NS_IMETHODIMP
--- a/layout/ipc/RenderFrameParent.h
+++ b/layout/ipc/RenderFrameParent.h
@@ -66,26 +66,28 @@ public:
                                      LayerManager* aManager,
                                      const nsIntRect& aVisibleRect);
 
   void OwnerContentChanged(nsIContent* aContent);
 
   void SetBackgroundColor(nscolor aColor) { mBackgroundColor = gfxRGBA(aColor); };
 
 protected:
-  NS_OVERRIDE void ActorDestroy(ActorDestroyReason why);
+  void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
-  NS_OVERRIDE virtual PLayersParent* AllocPLayers(LayerManager::LayersBackend* aBackendType,
-                                                  int* aMaxTextureSize);
-  NS_OVERRIDE virtual bool DeallocPLayers(PLayersParent* aLayers);
+  virtual PLayersParent*
+  AllocPLayers(LayerManager::LayersBackend* aBackendType,
+               int* aMaxTextureSize, uint64_t* aLayersId) MOZ_OVERRIDE;
+  virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
 
 private:
   void BuildViewMap();
 
   ShadowLayersParent* GetShadowLayers() const;
+  uint64_t GetLayerTreeId() const;
   ContainerLayer* GetRootLayer() const;
 
   nsRefPtr<nsFrameLoader> mFrameLoader;
   nsRefPtr<ContainerLayer> mContainer;
 
   // This contains the views for all the scrollable frames currently in the
   // painted region of our remote content.
   ViewMap mContentViews;
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -174,19 +174,19 @@ nsBaseWidget::~nsBaseWidget()
 void nsBaseWidget::BaseCreate(nsIWidget *aParent,
                               const nsIntRect &aRect,
                               EVENT_CALLBACK aHandleEventFunction,
                               nsDeviceContext *aContext,
                               nsWidgetInitData *aInitData)
 {
   static bool gDisableNativeThemeCached = false;
   if (!gDisableNativeThemeCached) {
-    mozilla::Preferences::AddBoolVarCache(&gDisableNativeTheme,
-                                          "mozilla.widget.disable-native-theme",
-                                          gDisableNativeTheme);
+    Preferences::AddBoolVarCache(&gDisableNativeTheme,
+                                 "mozilla.widget.disable-native-theme",
+                                 gDisableNativeTheme);
     gDisableNativeThemeCached = true;
   }
 
   // save the event callback function
   mEventCallback = aHandleEventFunction;
   
   // keep a reference to the device context
   if (aContext) {
@@ -874,19 +874,19 @@ void nsBaseWidget::CreateCompositor()
   MessageLoop *childMessageLoop = CompositorParent::CompositorLoop();
   mCompositorChild = new CompositorChild(lm);
   AsyncChannel *parentChannel = mCompositorParent->GetIPCChannel();
   AsyncChannel::Side childSide = mozilla::ipc::AsyncChannel::Child;
   mCompositorChild->Open(parentChannel, childMessageLoop, childSide);
   PRInt32 maxTextureSize;
   PLayersChild* shadowManager;
   if (mUseAcceleratedRendering) {
-    shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL, &maxTextureSize);
+    shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_OPENGL, 0, &maxTextureSize);
   } else {
-    shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_BASIC, &maxTextureSize);
+    shadowManager = mCompositorChild->SendPLayersConstructor(LayerManager::LAYERS_BASIC, 0, &maxTextureSize);
   }
 
   if (shadowManager) {
     ShadowLayerForwarder* lf = lm->AsShadowForwarder();
     if (!lf) {
       delete lm;
       mCompositorChild = nsnull;
       return;