Support tab-switching in the GPU process. (bug 1298507, r=billm)
authorDavid Anderson <danderson@mozilla.com>
Fri, 23 Sep 2016 18:12:45 -0700
changeset 315217 faeda156db9b8b8e52c85f9e9bc44470798eb69c
parent 315216 0be22294cfd825fb949866185169621f500110ee
child 315218 566cc2b60a8ca27bff5a4737b1fb8598869730bd
push id32563
push userihsiao@mozilla.com
push dateMon, 26 Sep 2016 11:18:33 +0000
treeherderautoland@eb840c87b5fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1298507
milestone52.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
Support tab-switching in the GPU process. (bug 1298507, r=billm)
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/PCompositorBridge.ipdl
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -3000,26 +3000,16 @@ private:
     MOZ_ASSERT(NS_IsMainThread());
     if (RefPtr<TabParent> tabParent = TabParent::GetTabParentFromLayersId(mLayersId)) {
       tabParent->LayerTreeUpdate(mEpoch, mActive);
     }
     return NS_OK;
   }
 };
 
-/* static */ void
-TabParent::ObserveLayerUpdate(uint64_t aLayersId, uint64_t aEpoch, bool aActive)
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  RefPtr<LayerTreeUpdateRunnable> runnable =
-    new LayerTreeUpdateRunnable(aLayersId, aEpoch, aActive);
-  NS_DispatchToMainThread(runnable);
-}
-
 void
 TabParent::LayerTreeUpdate(uint64_t aEpoch, bool aActive)
 {
   // Ignore updates from old epochs. They might tell us that layers are
   // available when we've already sent a message to clear them. We can't trust
   // the update in that case since layers could disappear anytime after that.
   if (aEpoch != mLayerTreeEpoch || mIsDestroyed) {
     return;
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -561,17 +561,16 @@ public:
 
   bool IsInitedByParent() const { return mInitedByParent; }
 
   static TabParent* GetNextTabParent();
 
   bool SendLoadRemoteScript(const nsString& aURL,
                             const bool& aRunInGlobalScope);
 
-  static void ObserveLayerUpdate(uint64_t aLayersId, uint64_t aEpoch, bool aActive);
   void LayerTreeUpdate(uint64_t aEpoch, bool aActive);
 
   virtual bool
   RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
                         const uint32_t& aAction,
                         const OptionalShmem& aVisualDnDData,
                         const uint32_t& aWidth, const uint32_t& aHeight,
                         const uint32_t& aStride, const uint8_t& aFormat,
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -27,16 +27,17 @@
 #include "nsAutoPtr.h"
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsIObserver.h"                // for nsIObserver
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsTArray.h"                   // for nsTArray, nsTArray_Impl
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop, etc
 #include "FrameLayerBuilder.h"
 #include "mozilla/dom/TabChild.h"
+#include "mozilla/dom/TabParent.h"
 #include "mozilla/Unused.h"
 #include "mozilla/DebugOnly.h"
 #if defined(XP_WIN)
 #include "WinUtils.h"
 #endif
 #include "mozilla/widget/CompositorWidget.h"
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
 # include "mozilla/widget/CompositorWidgetChild.h"
@@ -862,16 +863,32 @@ CompositorBridgeChild::RecvParentAsyncMe
       default:
         NS_ERROR("unknown AsyncParentMessageData type");
         return false;
     }
   }
   return true;
 }
 
+bool
+CompositorBridgeChild::RecvObserveLayerUpdate(const uint64_t& aLayersId,
+                                              const uint64_t& aEpoch,
+                                              const bool& aActive)
+{
+  // This message is sent via the window compositor, not the tab compositor -
+  // however it still has a layers id.
+  MOZ_ASSERT(aLayersId);
+  MOZ_ASSERT(XRE_IsParentProcess());
+
+  if (RefPtr<dom::TabParent> tab = dom::TabParent::GetTabParentFromLayersId(aLayersId)) {
+    tab->LayerTreeUpdate(aEpoch, aActive);
+  }
+  return true;
+}
+
 void
 CompositorBridgeChild::HoldUntilCompositableRefReleasedIfNecessary(TextureClient* aClient)
 {
   if (!aClient) {
     return;
   }
 
   if (!(aClient->GetFlags() & TextureFlags::RECYCLE) &&
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -245,16 +245,20 @@ private:
                                                 const uint32_t& aAPZCId) override;
 
   virtual bool RecvReleaseSharedCompositorFrameMetrics(const ViewID& aId,
                                                        const uint32_t& aAPZCId) override;
 
   virtual bool
   RecvRemotePaintIsReady() override;
 
+  bool RecvObserveLayerUpdate(const uint64_t& aLayersId,
+                              const uint64_t& aEpoch,
+                              const bool& aActive) override;
+
   // Class used to store the shared FrameMetrics, mutex, and APZCId  in a hash table
   class SharedFrameMetricsData {
   public:
     SharedFrameMetricsData(
         const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
         const CrossProcessMutexHandle& handle,
         const uint64_t& aLayersId,
         const uint32_t& aAPZCId);
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -2707,17 +2707,19 @@ CrossProcessCompositorBridgeParent::Shad
 
   // Send the 'remote paint ready' message to the content thread if it has already asked.
   if(mNotifyAfterRemotePaint)  {
     Unused << SendRemotePaintIsReady();
     mNotifyAfterRemotePaint = false;
   }
 
   if (aLayerTree->ShouldParentObserveEpoch()) {
-    dom::TabParent::ObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
+    // Note that we send this through the window compositor, since this needs
+    // to reach the widget owning the tab.
+    Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), true);
   }
 
   aLayerTree->SetPendingTransactionId(aTransactionId);
 }
 
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
 //#define PLUGINS_LOG(...) printf_stderr("CP [%s]: ", __FUNCTION__);
 //                         printf_stderr(__VA_ARGS__);
@@ -2936,17 +2938,23 @@ CrossProcessCompositorBridgeParent::Forc
 }
 
 void
 CrossProcessCompositorBridgeParent::NotifyClearCachedResources(LayerTransactionParent* aLayerTree)
 {
   uint64_t id = aLayerTree->GetId();
   MOZ_ASSERT(id != 0);
 
-  dom::TabParent::ObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), false);
+  const CompositorBridgeParent::LayerTreeState* state =
+    CompositorBridgeParent::GetIndirectShadowTree(id);
+  if (state && state->mParent) {
+    // Note that we send this through the window compositor, since this needs
+    // to reach the widget owning the tab.
+    Unused << state->mParent->SendObserveLayerUpdate(id, aLayerTree->GetChildEpoch(), false);
+  }
 }
 
 bool
 CrossProcessCompositorBridgeParent::SetTestSampleTime(
   LayerTransactionParent* aLayerTree, const TimeStamp& aTime)
 {
   uint64_t id = aLayerTree->GetId();
   MOZ_ASSERT(id != 0);
--- a/gfx/layers/ipc/PCompositorBridge.ipdl
+++ b/gfx/layers/ipc/PCompositorBridge.ipdl
@@ -110,16 +110,18 @@ child:
   /**
    * Drop any buffers that might be retained on the child compositor
    * side.
    */
   async ClearCachedResources(uint64_t id);
 
   async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
 
+  async ObserveLayerUpdate(uint64_t aLayersId, uint64_t aEpoch, bool aActive);
+
 parent:
   // Must be called before Initialize().
   async PCompositorWidget(CompositorWidgetInitData aInitData);
 
   // When out-of-process, this must be called to finish initialization.
   sync Initialize(uint64_t rootLayerTreeId);
 
   // Returns whether this Compositor has APZ enabled or not.