Bug 1335895 - part 7: Update UiCompositorControllerParent to support added methods and to be instanced per session instead of a single instance r=dvander draft
authorRandall Barker <rbarker@mozilla.com>
Wed, 05 Apr 2017 15:57:06 -0700
changeset 565556 495e3332c0966dd6f04f8e3dbe70049f47952515
parent 565555 a492379b275b15fcea7bc4e881745fd3c076f867
child 565557 b705a11c6a7a6795e46c8d70ace828c5c0d2f663
push id54904
push userbmo:rbarker@mozilla.com
push dateThu, 20 Apr 2017 02:39:58 +0000
reviewersdvander
bugs1335895
milestone55.0a1
Bug 1335895 - part 7: Update UiCompositorControllerParent to support added methods and to be instanced per session instead of a single instance r=dvander
gfx/layers/ipc/UiCompositorControllerParent.cpp
gfx/layers/ipc/UiCompositorControllerParent.h
--- a/gfx/layers/ipc/UiCompositorControllerParent.cpp
+++ b/gfx/layers/ipc/UiCompositorControllerParent.cpp
@@ -1,118 +1,299 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "UiCompositorControllerParent.h"
+#include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/Compositor.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
+#include "mozilla/layers/LayerManagerComposite.h"
+#include "mozilla/gfx/Types.h"
+#include "mozilla/Move.h"
+#include "mozilla/Unused.h"
 
 namespace mozilla {
 namespace layers {
 
-RefPtr<UiCompositorControllerParent>
-UiCompositorControllerParent::Start(Endpoint<PUiCompositorControllerParent>&& aEndpoint)
+typedef CompositorBridgeParent::LayerTreeState LayerTreeState;
+
+/* static */ RefPtr<UiCompositorControllerParent>
+UiCompositorControllerParent::GetFromRootLayerTreeId(const uint64_t& aRootLayerTreeId)
 {
-  RefPtr<UiCompositorControllerParent> parent = new UiCompositorControllerParent();
+  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(aRootLayerTreeId);
+  if (state) {
+    return state->mUiControllerParent;
+  }
+
+  return nullptr;
+}
+
+/* static */ RefPtr<UiCompositorControllerParent>
+UiCompositorControllerParent::Start(const uint64_t& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint)
+{
+  RefPtr<UiCompositorControllerParent> parent = new UiCompositorControllerParent(aRootLayerTreeId);
 
   RefPtr<Runnable> task = NewRunnableMethod<Endpoint<PUiCompositorControllerParent>&&>(
     parent, &UiCompositorControllerParent::Open, Move(aEndpoint));
   CompositorThreadHolder::Loop()->PostTask(task.forget());
 
   return parent;
 }
 
-UiCompositorControllerParent::UiCompositorControllerParent()
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvPause()
+{
+  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
+  if (parent) {
+    parent->PauseComposition();
+  }
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvResume()
+{
+  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
+  if (parent) {
+    parent->ResumeComposition();
+  }
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvResumeAndResize(const int32_t& aWidth,
+                                                  const int32_t& aHeight)
+{
+  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
+  if (parent) {
+    parent->ResumeCompositionAndResize(aWidth, aHeight);
+  }
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvInvalidateAndRender()
+{
+  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(mRootLayerTreeId);
+  if (parent) {
+    parent->Invalidate();
+    parent->ScheduleComposition();
+  }
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvMaxToolbarHeight(const int32_t& aHeight)
+{
+  mMaxToolbarHeight = aHeight;
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    mAnimator->SetMaxToolbarHeight(mMaxToolbarHeight);
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvPinned(const bool& aPinned, const int32_t& aReason)
+{
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    mAnimator->SetPinned(aPinned, aReason);
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvToolbarAnimatorMessageFromUI(const int32_t& aMessage)
+{
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    mAnimator->ToolbarAnimatorMessageFromUI(aMessage);
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvDefaultClearColor(const uint32_t& aColor)
+{
+  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
+
+  if (state && state->mLayerManager) {
+    Compositor* compositor = state->mLayerManager->GetCompositor();
+    if (compositor) {
+      // Android Color is ARGB which is apparently unusual.
+      compositor->SetDefaultClearColor(gfx::Color::UnusualFromARGB(aColor));
+    }
+  }
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvRequestScreenPixels()
+{
+#if defined(MOZ_WIDGET_ANDROID)
+  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
+
+  if (state && state->mLayerManager && state->mParent) {
+    state->mLayerManager->RequestScreenPixels(this);
+    state->mParent->Invalidate();
+    state->mParent->ScheduleComposition();
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvEnableLayerUpdateNotifications(const bool& aEnable)
+{
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    mAnimator->EnableLayersUpdateNotifications(aEnable);
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+mozilla::ipc::IPCResult
+UiCompositorControllerParent::RecvToolbarPixelsToCompositor(Shmem&& aMem, const ScreenIntSize& aSize)
+{
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    // By adopting the Shmem, the animator is responsible for deallocating.
+    mAnimator->AdoptToolbarPixels(Move(aMem), aSize);
+  } else {
+    DeallocShmem(aMem);
+  }
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  return IPC_OK();
+}
+
+void
+UiCompositorControllerParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+void
+UiCompositorControllerParent::DeallocPUiCompositorControllerParent()
+{
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+  Shutdown();
+  Release(); // For AddRef in Initialize()
+}
+
+#if defined(MOZ_WIDGET_ANDROID)
+void
+UiCompositorControllerParent::RegisterAndroidDynamicToolbarAnimator(AndroidDynamicToolbarAnimator* aAnimator)
+{
+  MOZ_ASSERT(!mAnimator);
+  mAnimator = aAnimator;
+  if (mAnimator) {
+    mAnimator->SetMaxToolbarHeight(mMaxToolbarHeight);
+  }
+}
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+void
+UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor(int32_t aMessage)
+{
+  // This function can be call from ether compositor or controller thread.
+  if (!CompositorThreadHolder::IsInCompositorThread()) {
+    CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod<int32_t>(this, &UiCompositorControllerParent::ToolbarAnimatorMessageFromCompositor, aMessage));
+    return;
+  }
+
+  Unused << SendToolbarAnimatorMessageFromCompositor(aMessage);
+}
+
+bool
+UiCompositorControllerParent::AllocPixelBuffer(const int32_t aSize, ipc::Shmem* aMem)
+{
+  MOZ_ASSERT(aSize > 0);
+  return AllocShmem(aSize, ipc::SharedMemory::TYPE_BASIC, aMem);
+}
+
+UiCompositorControllerParent::UiCompositorControllerParent(const uint64_t& aRootLayerTreeId)
+  : mRootLayerTreeId(aRootLayerTreeId)
+  , mMaxToolbarHeight(0)
 {
   MOZ_COUNT_CTOR(UiCompositorControllerParent);
 }
 
 UiCompositorControllerParent::~UiCompositorControllerParent()
 {
   MOZ_COUNT_DTOR(UiCompositorControllerParent);
 }
 
 void
+UiCompositorControllerParent::InitializeForSameProcess()
+{
+  // This function is called by UiCompositorControllerChild in the main thread.
+  // So dispatch to the compositor thread to Initialize.
+  if (!CompositorThreadHolder::IsInCompositorThread()) {
+    CompositorThreadHolder::Loop()->PostTask(NewRunnableMethod(this, &UiCompositorControllerParent::InitializeForSameProcess));
+    return;
+  }
+
+  Initialize();
+}
+
+void
+UiCompositorControllerParent::InitializeForOutOfProcess()
+{
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+  Initialize();
+}
+
+void
+UiCompositorControllerParent::Initialize()
+{
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+  AddRef();
+  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
+  MOZ_ASSERT(state);
+  MOZ_ASSERT(state->mParent);
+  state->mUiControllerParent = this;
+#if defined(MOZ_WIDGET_ANDROID)
+  state->mParent->GetAPZCTreeManager()->InitializeDynamicToolbarAnimator(mRootLayerTreeId);
+#endif
+}
+
+void
 UiCompositorControllerParent::Open(Endpoint<PUiCompositorControllerParent>&& aEndpoint)
 {
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   if (!aEndpoint.Bind(this)) {
     // We can't recover from this.
     MOZ_CRASH("Failed to bind UiCompositorControllerParent to endpoint");
   }
-  AddRef();
-}
-
-mozilla::ipc::IPCResult
-UiCompositorControllerParent::RecvPause(const uint64_t& aLayersId)
-{
-  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(aLayersId);
-  if (parent) {
-    parent->PauseComposition();
-  }
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-UiCompositorControllerParent::RecvResume(const uint64_t& aLayersId)
-{
-  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(aLayersId);
-  if (parent) {
-    parent->ResumeComposition();
-  }
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-UiCompositorControllerParent::RecvResumeAndResize(const uint64_t& aLayersId,
-                                                  const int32_t& aHeight,
-                                                  const int32_t& aWidth)
-{
-  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(aLayersId);
-  if (parent) {
-    parent->ResumeCompositionAndResize(aHeight, aWidth);
-  }
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-UiCompositorControllerParent::RecvInvalidateAndRender(const uint64_t& aLayersId)
-{
-  CompositorBridgeParent* parent = CompositorBridgeParent::GetCompositorBridgeParentFromLayersId(aLayersId);
-  if (parent) {
-    parent->Invalidate();
-    parent->ScheduleComposition();
-  }
-  return IPC_OK();
+  InitializeForOutOfProcess();
 }
 
 void
 UiCompositorControllerParent::Shutdown()
 {
-  MessageLoop* ccloop = CompositorThreadHolder::Loop();
-  if (MessageLoop::current() != ccloop) {
-    ccloop->PostTask(NewRunnableMethod(this, &UiCompositorControllerParent::ShutdownImpl));
-    return;
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+#if defined(MOZ_WIDGET_ANDROID)
+  if (mAnimator) {
+    mAnimator->Shutdown();
   }
-
-  ShutdownImpl();
-}
-
-void
-UiCompositorControllerParent::ShutdownImpl()
-{
-  Close();
-}
-
-void
-UiCompositorControllerParent::ActorDestroy(ActorDestroyReason aWhy)
-{
-}
-
-void
-UiCompositorControllerParent::DeallocPUiCompositorControllerParent()
-{
-  Release();
+#endif // defined(MOZ_WIDGET_ANDROID)
+  LayerTreeState* state = CompositorBridgeParent::GetIndirectShadowTree(mRootLayerTreeId);
+  if (state) {
+    state->mUiControllerParent = nullptr;
+  }
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/UiCompositorControllerParent.h
+++ b/gfx/layers/ipc/UiCompositorControllerParent.h
@@ -1,47 +1,73 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef include_gfx_ipc_UiCompositorControllerParent_h
 #define include_gfx_ipc_UiCompositorControllerParent_h
 
+#include "mozilla/layers/PUiCompositorControllerParent.h"
+#if defined(MOZ_WIDGET_ANDROID)
+#include "mozilla/layers/AndroidDynamicToolbarAnimator.h"
+#endif // defined(MOZ_WIDGET_ANDROID)
+#include "mozilla/ipc/Shmem.h"
 #include "mozilla/RefPtr.h"
-#include "mozilla/layers/PUiCompositorControllerParent.h"
 
 namespace mozilla {
 namespace layers {
 
 class UiCompositorControllerParent final : public PUiCompositorControllerParent
 {
+// UiCompositorControllerChild needs to call the private constructor when running in process.
+friend class UiCompositorControllerChild;
 public:
-  UiCompositorControllerParent();
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UiCompositorControllerParent)
 
-  static RefPtr<UiCompositorControllerParent> Start(Endpoint<PUiCompositorControllerParent>&& aEndpoint);
+  static RefPtr<UiCompositorControllerParent> GetFromRootLayerTreeId(const uint64_t& aRootLayerTreeId);
+  static RefPtr<UiCompositorControllerParent> Start(const uint64_t& aRootLayerTreeId, Endpoint<PUiCompositorControllerParent>&& aEndpoint);
 
-  mozilla::ipc::IPCResult RecvPause(const uint64_t& aLayersId) override;
-  mozilla::ipc::IPCResult RecvResume(const uint64_t& aLayersId) override;
-  mozilla::ipc::IPCResult RecvResumeAndResize(const uint64_t& aLayersId,
-                                              const int32_t& aHeight,
+  // PUiCompositorControllerParent functions
+  mozilla::ipc::IPCResult RecvPause() override;
+  mozilla::ipc::IPCResult RecvResume() override;
+  mozilla::ipc::IPCResult RecvResumeAndResize(const int32_t& aHeight,
                                               const int32_t& aWidth) override;
-  mozilla::ipc::IPCResult RecvInvalidateAndRender(const uint64_t& aLayersId) override;
-
+  mozilla::ipc::IPCResult RecvInvalidateAndRender() override;
+  mozilla::ipc::IPCResult RecvMaxToolbarHeight(const int32_t& aHeight) override;
+  mozilla::ipc::IPCResult RecvPinned(const bool& aPinned, const int32_t& aReason) override;
+  mozilla::ipc::IPCResult RecvToolbarAnimatorMessageFromUI(const int32_t& aMessage) override;
+  mozilla::ipc::IPCResult RecvDefaultClearColor(const uint32_t& aColor) override;
+  mozilla::ipc::IPCResult RecvRequestScreenPixels() override;
+  mozilla::ipc::IPCResult RecvEnableLayerUpdateNotifications(const bool& aEnable) override;
+  mozilla::ipc::IPCResult RecvToolbarPixelsToCompositor(Shmem&& aMem, const ScreenIntSize& aSize) override;
   void ActorDestroy(ActorDestroyReason aWhy) override;
   void DeallocPUiCompositorControllerParent() override;
 
-  void Shutdown();
+  // Class specific functions
+#if defined(MOZ_WIDGET_ANDROID)
+  void RegisterAndroidDynamicToolbarAnimator(AndroidDynamicToolbarAnimator* aAnimator);
+#endif // MOZ_WIDGET_ANDROID
+  void ToolbarAnimatorMessageFromCompositor(int32_t aMessage);
+  bool AllocPixelBuffer(const int32_t aSize, Shmem* aMem);
 
 private:
+  explicit UiCompositorControllerParent(const uint64_t& aRootLayerTreeId);
   ~UiCompositorControllerParent();
-
+  void InitializeForSameProcess();
+  void InitializeForOutOfProcess();
+  void Initialize();
   void Open(Endpoint<PUiCompositorControllerParent>&& aEndpoint);
-  void ShutdownImpl();
+  void Shutdown();
+
+  uint64_t mRootLayerTreeId;
 
-private:
+#if defined(MOZ_WIDGET_ANDROID)
+  RefPtr<AndroidDynamicToolbarAnimator> mAnimator;
+#endif // defined(MOZ_WIDGET_ANDROID)
+
+  int32_t mMaxToolbarHeight;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // include_gfx_ipc_UiCompositorControllerParent_h