Bug 879475 - Part 007. Allow nested remote mozbrowsers to push layer transactions to the compositor r=mattwoodrow
☠☠ backed out by da23ba53e4af ☠ ☠
author"Kan-Ru Chen (陳侃如)" <kanru@kanru.info>
Mon, 09 Jun 2014 16:49:12 +0800
changeset 207840 00c2ba04f8d439ba9bb8624c10f058e287a57948
parent 207839 820e34a746471f160e41f393c00f7bc4e1333c0a
child 207841 c5f9a189da8bc6f53bf6a3d931b7167607ef9daa
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs879475
milestone32.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
@@ -1392,16 +1392,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?
     }
   }