bool
GPUProcessManager::AllocateAndConnectLayerTreeId(PCompositorBridgeChild* aCompositorBridge,
                                                 base::ProcessId aOtherPid,
                                                 uint64_t* aOutLayersId,
                                                 CompositorOptions* aOutCompositorOptions)
{
  uint64_t layersId = AllocateLayerTreeId();
  *aOutLayersId = layersId;

  if (!mGPUChild || !aCompositorBridge) {
    // If we're not remoting to another process, or there is no compositor,
    // then we'll send at most one message. In this case we can just keep
    // the old behavior of making sure the mapping occurs, and maybe sending
    // a creation notification.
    MapLayerTreeId(layersId, aOtherPid);
    if (!aCompositorBridge) {
      return false;
    }
    return aCompositorBridge->SendNotifyChildCreated(layersId, aOutCompositorOptions);
  }

  // Use the combined message path.
  LayerTreeOwnerTracker::Get()->Map(layersId, aOtherPid);
  return aCompositorBridge->SendMapAndNotifyChildCreated(layersId, aOtherPid, aOutCompositorOptions);
}
CompositorParent::CompositorParent(nsIWidget* aWidget,
                                   bool aUseExternalSurfaceSize,
                                   int aSurfaceWidth, int aSurfaceHeight)
  : mWidget(aWidget)
  , mCurrentCompositeTask(nullptr)
  , mIsTesting(false)
  , mPendingTransaction(0)
  , mPaused(false)
  , mUseExternalSurfaceSize(aUseExternalSurfaceSize)
  , mEGLSurfaceSize(aSurfaceWidth, aSurfaceHeight)
  , mPauseCompositionMonitor("PauseCompositionMonitor")
  , mResumeCompositionMonitor("ResumeCompositionMonitor")
  , mOverrideComposeReadiness(false)
  , mForceCompositionTask(nullptr)
{
  MOZ_ASSERT(sCompositorThread != nullptr,
             "The compositor thread must be Initialized before instanciating a CmpositorParent.");
  MOZ_COUNT_CTOR(CompositorParent);
  mCompositorID = 0;
  // FIXME: This holds on the the fact that right now the only thing that
  // can destroy this instance is initialized on the compositor thread after
  // this task has been processed.
  CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(&AddCompositor,
                                                          this, &mCompositorID));

  CompositorLoop()->PostTask(FROM_HERE, NewRunnableFunction(SetThreadPriority));

  mRootLayerTreeID = AllocateLayerTreeId();
  sIndirectLayerTrees[mRootLayerTreeID].mParent = this;

  mApzcTreeManager = new APZCTreeManager();
  ++sCompositorThreadRefCount;
}
RefPtr<CompositorSession>
GPUProcessManager::CreateTopLevelCompositor(nsBaseWidget* aWidget,
                                            LayerManager* aLayerManager,
                                            CSSToLayoutDeviceScale aScale,
                                            const CompositorOptions& aOptions,
                                            bool aUseExternalSurfaceSize,
                                            const gfx::IntSize& aSurfaceSize)
{
  uint64_t layerTreeId = AllocateLayerTreeId();

  EnsureImageBridgeChild();
  EnsureVRManager();

  RefPtr<CompositorSession> session;

  if (EnsureGPUReady()) {
    session = CreateRemoteSession(
      aWidget,
      aLayerManager,
      layerTreeId,
      aScale,
      aOptions,
      aUseExternalSurfaceSize,
      aSurfaceSize);
    if (!session) {
      // We couldn't create a remote compositor, so abort the process.
      DisableGPUProcess("Failed to create remote compositor");
    }
  }

  if (!session) {
    session = InProcessCompositorSession::Create(
      aWidget,
      aLayerManager,
      layerTreeId,
      aScale,
      aOptions,
      aUseExternalSurfaceSize,
      aSurfaceSize,
      AllocateNamespace());
  }

#if defined(MOZ_WIDGET_ANDROID)
  if (session) {
    // Nothing to do if controller gets a nullptr
    RefPtr<UiCompositorControllerChild> controller = CreateUiCompositorController(aWidget, session->RootLayerTreeId());
    session->SetUiCompositorControllerChild(controller);
  }
#endif // defined(MOZ_WIDGET_ANDROID)

  return session;
}