Bug 879475 - Part 007. Allow nested remote mozbrowsers to push layer transactions to the compositor r=mattwoodrow
author"Kan-Ru Chen (陳侃如)" <kanru@kanru.info>
Wed, 11 Jun 2014 13:44:39 +0800
changeset 188074 a72228f459ec5273fb593347cba47b9a73b59837
parent 188073 96ddd6ea6abd60f775438e232e3161940ed92c01
child 188075 277bacd9f2f8b3383ff4b3096450069decc121e8
push id44728
push userkchen@mozilla.com
push dateWed, 11 Jun 2014 05:45:18 +0000
treeherdermozilla-inbound@a72228f459ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs879475
milestone33.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 879475 - Part 007. Allow nested remote mozbrowsers to push layer transactions to the compositor r=mattwoodrow Based on original patch by David Zbarsky <dzbarsky@gmail.com>
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
gfx/layers/composite/AsyncCompositionManager.cpp
layout/ipc/RenderFrameParent.cpp
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1390,16 +1390,49 @@ ContentParent::ProcessingError(Result wh
     if (MsgDropped == what) {
         // Messages sent after crashes etc. are not a big deal.
         return;
     }
     // Other errors are big deals.
     KillHard();
 }
 
+typedef std::pair<ContentParent*, std::set<uint64_t> > IDPair;
+static std::map<ContentParent*, std::set<uint64_t> > sNestedBrowserIds;
+
+bool
+ContentParent::RecvAllocateLayerTreeId(uint64_t* aId)
+{
+    *aId = CompositorParent::AllocateLayerTreeId();
+
+    auto iter = sNestedBrowserIds.find(this);
+    if (iter == sNestedBrowserIds.end()) {
+        std::set<uint64_t> ids;
+        ids.insert(*aId);
+        sNestedBrowserIds.insert(IDPair(this, ids));
+    } else {
+        iter->second.insert(*aId);
+    }
+    return true;
+}
+
+bool
+ContentParent::RecvDeallocateLayerTreeId(const uint64_t& aId)
+{
+    auto iter = sNestedBrowserIds.find(this);
+    if (iter != sNestedBrowserIds.end() &&
+        iter->second.find(aId) != iter->second.end()) {
+        CompositorParent::DeallocateLayerTreeId(aId);
+    } else {
+        // You can't deallocate layer tree ids that you didn't allocate
+        KillHard();
+    }
+    return true;
+}
+
 namespace {
 
 void
 DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
 {
     XRE_GetIOMessageLoop()
         ->PostTask(FROM_HERE,
                    new DeleteTask<GeckoChildProcessHost>(aSubprocess));
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -586,16 +586,19 @@ private:
 
     virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) MOZ_OVERRIDE;
 
     virtual bool RecvKeywordToURI(const nsCString& aKeyword, OptionalInputStreamParams* aPostData,
                                   OptionalURIParams* aURI) MOZ_OVERRIDE;
 
     virtual void ProcessingError(Result what) MOZ_OVERRIDE;
 
+    virtual bool RecvAllocateLayerTreeId(uint64_t* aId) MOZ_OVERRIDE;
+    virtual bool RecvDeallocateLayerTreeId(const uint64_t& aId) MOZ_OVERRIDE;
+
     virtual bool RecvGetGraphicsFeatureStatus(const int32_t& aFeature,
                                               int32_t* aStatus,
                                               bool* aSuccess) MOZ_OVERRIDE;
 
     virtual bool RecvAddIdleObserver(const uint64_t& observerId,
                                      const uint32_t& aIdleTimeInS) MOZ_OVERRIDE;
     virtual bool RecvRemoveIdleObserver(const uint64_t& observerId,
                                         const uint32_t& aIdleTimeInS) MOZ_OVERRIDE;
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -591,16 +591,21 @@ parent:
 
     // called by the child (test code only) to propagate volume changes to the parent
     async CreateFakeVolume(nsString fsName, nsString mountPoint);
     async SetFakeVolumeState(nsString fsName, int32_t fsState);
 
     sync KeywordToURI(nsCString keyword)
         returns (OptionalInputStreamParams postData, OptionalURIParams uri);
 
+    // Tell the compositor to allocate a layer tree id for nested remote mozbrowsers.
+    sync AllocateLayerTreeId()
+        returns (uint64_t id);
+    async DeallocateLayerTreeId(uint64_t id);
+
     sync SpeakerManagerForceSpeaker(bool aEnable);
 
     sync SpeakerManagerGetSpeakerStatus()
         returns (bool value);
 
     /**
      * Notifies the parent about a recording device is starting or shutdown.
      * @param recordingStatus starting or shutdown
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -79,16 +79,17 @@ WalkTheTree(Layer* aLayer,
             aReady = false;
           }
         }
 
         if (OP == Resolve) {
           ref->ConnectReferentLayer(referent);
         } else {
           ref->DetachReferentLayer(referent);
+          WalkTheTree<OP>(referent, aReady, aTargetConfig);
         }
       }
     }
   }
   for (Layer* child = aLayer->GetFirstChild();
        child; child = child->GetNextSibling()) {
     WalkTheTree<OP>(child, aReady, aTargetConfig);
   }
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -8,16 +8,17 @@
 #include "base/basictypes.h"
 
 #include "BasicLayers.h"
 #include "gfx3DMatrix.h"
 #ifdef MOZ_ENABLE_D3D9_LAYER
 # include "LayerManagerD3D9.h"
 #endif //MOZ_ENABLE_D3D9_LAYER
 #include "mozilla/BrowserElementParent.h"
+#include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/LayerTransactionParent.h"
 #include "nsContentUtils.h"
 #include "nsFrameLoader.h"
 #include "nsIObserver.h"
 #include "nsSubDocumentFrame.h"
@@ -744,16 +745,19 @@ RenderFrameParent::RenderFrameParent(nsF
     if (lm && lm->GetBackendType() == LayersBackend::LAYERS_CLIENT) {
       ClientLayerManager *clientManager = static_cast<ClientLayerManager*>(lm.get());
       clientManager->GetRemoteRenderer()->SendNotifyChildCreated(mLayersId);
     }
     if (aScrollingBehavior == ASYNC_PAN_ZOOM) {
       mContentController = new RemoteContentController(this);
       CompositorParent::SetControllerForLayerTree(mLayersId, mContentController);
     }
+  } else if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    ContentChild::GetSingleton()->SendAllocateLayerTreeId(aId);
+    mLayersId = *aId;
   }
   // Set a default RenderFrameParent
   mFrameLoader->SetCurrentRemoteFrame(this);
   *aSuccess = true;
 }
 
 APZCTreeManager*
 RenderFrameParent::GetApzcTreeManager()
@@ -941,17 +945,21 @@ RenderFrameParent::NotifyInputEvent(Widg
   }
   return nsEventStatus_eIgnore;
 }
 
 void
 RenderFrameParent::ActorDestroy(ActorDestroyReason why)
 {
   if (mLayersId != 0) {
-    CompositorParent::DeallocateLayerTreeId(mLayersId);
+    if (XRE_GetProcessType() == GeckoProcessType_Content) {
+      ContentChild::GetSingleton()->SendDeallocateLayerTreeId(mLayersId);
+    } else {
+      CompositorParent::DeallocateLayerTreeId(mLayersId);
+    }
     if (mContentController) {
       // Stop our content controller from requesting repaints of our
       // content.
       mContentController->ClearRenderFrame();
       // TODO: notify the compositor?
     }
   }