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 105601 1df6cd42330dc2520947b5e4f5c92b76bf82fe80
parent 105600 13059586b02b1995f94e5334f7eb265669f42d6c
child 105602 100fd0a81f9ec5709db6c61e2e1af5d956601ed4
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersajuma, roc
bugs745148
milestone17.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
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;