gecko-dev/gfx/vr/ipc/VRManagerChild.cpp

195 строки
5.1 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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 "VRManagerChild.h"
#include "VRManagerParent.h"
#include "VRDeviceProxy.h"
#include "VRDeviceProxyOrientationFallBack.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/CompositorBridgeParent.h" // for CompositorBridgeParent
#include "mozilla/dom/Navigator.h"
namespace mozilla {
namespace gfx {
static StaticRefPtr<VRManagerChild> sVRManagerChildSingleton;
static StaticRefPtr<VRManagerParent> sVRManagerParentSingleton;
void ReleaseVRManagerParentSingleton() {
sVRManagerParentSingleton = nullptr;
}
VRManagerChild::VRManagerChild()
: mInputFrameID(-1)
{
MOZ_COUNT_CTOR(VRManagerChild);
MOZ_ASSERT(NS_IsMainThread());
}
VRManagerChild::~VRManagerChild()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_DTOR(VRManagerChild);
Transport* trans = GetTransport();
if (trans) {
MOZ_ASSERT(XRE_GetIOMessageLoop());
XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
new DeleteTask<Transport>(trans));
}
}
/*static*/ VRManagerChild*
VRManagerChild::Get()
{
MOZ_ASSERT(sVRManagerChildSingleton);
return sVRManagerChildSingleton;
}
/*static*/ VRManagerChild*
VRManagerChild::StartUpInChildProcess(Transport* aTransport, ProcessId aOtherPid)
{
MOZ_ASSERT(NS_IsMainThread());
// There's only one VRManager per child process.
MOZ_ASSERT(!sVRManagerChildSingleton);
RefPtr<VRManagerChild> child(new VRManagerChild());
if (!child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
return nullptr;
}
sVRManagerChildSingleton = child;
return sVRManagerChildSingleton;
}
/*static*/ void
VRManagerChild::StartUpSameProcess()
{
NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
if (sVRManagerChildSingleton == nullptr) {
sVRManagerChildSingleton = new VRManagerChild();
sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
mozilla::layers::CompositorBridgeParent::CompositorLoop(),
mozilla::ipc::ChildSide);
}
}
/*static*/ void
VRManagerChild::ShutDown()
{
MOZ_ASSERT(NS_IsMainThread());
if (sVRManagerChildSingleton) {
sVRManagerChildSingleton->Destroy();
sVRManagerChildSingleton = nullptr;
}
}
/*static*/ void
VRManagerChild::DeferredDestroy(RefPtr<VRManagerChild> aVRManagerChild)
{
aVRManagerChild->Close();
}
void
VRManagerChild::Destroy()
{
// This must not be called from the destructor!
MOZ_ASSERT(mRefCnt != 0);
// Keep ourselves alive until everything has been shut down
RefPtr<VRManagerChild> selfRef = this;
// The DeferredDestroyVRManager task takes ownership of
// the VRManagerChild and will release it when it runs.
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableFunction(DeferredDestroy, selfRef));
}
bool
VRManagerChild::RecvUpdateDeviceInfo(nsTArray<VRDeviceUpdate>&& aDeviceUpdates)
{
// mDevices could be a hashed container for more scalability, but not worth
// it now as we expect < 10 entries.
nsTArray<RefPtr<VRDeviceProxy> > devices;
for (auto& deviceUpdate: aDeviceUpdates) {
bool isNewDevice = true;
for (auto& device: mDevices) {
if (device->GetDeviceInfo().GetDeviceID() == deviceUpdate.mDeviceInfo.GetDeviceID()) {
device->UpdateDeviceInfo(deviceUpdate);
devices.AppendElement(device);
isNewDevice = false;
break;
}
}
if (isNewDevice) {
if (deviceUpdate.mDeviceInfo.GetUseMainThreadOrientation()) {
devices.AppendElement(new VRDeviceProxyOrientationFallBack(deviceUpdate));
} else {
devices.AppendElement(new VRDeviceProxy(deviceUpdate));
}
}
}
mDevices = devices;
for (auto& nav: mNavigatorCallbacks) {
nav->NotifyVRDevicesUpdated();
}
mNavigatorCallbacks.Clear();
return true;
}
bool
VRManagerChild::RecvUpdateDeviceSensors(nsTArray<VRSensorUpdate>&& aDeviceSensorUpdates)
{
// mDevices could be a hashed container for more scalability, but not worth
// it now as we expect < 10 entries.
for (auto& sensorUpdate: aDeviceSensorUpdates) {
for (auto& device: mDevices) {
if (device->GetDeviceInfo().GetDeviceID() == sensorUpdate.mDeviceID) {
device->UpdateSensorState(sensorUpdate.mSensorState);
mInputFrameID = sensorUpdate.mSensorState.inputFrameID;
break;
}
}
}
return true;
}
bool
VRManagerChild::GetVRDevices(nsTArray<RefPtr<VRDeviceProxy> >& aDevices)
{
aDevices = mDevices;
return true;
}
bool
VRManagerChild::RefreshVRDevicesWithCallback(dom::Navigator* aNavigator)
{
bool success = SendRefreshDevices();
if (success) {
mNavigatorCallbacks.AppendElement(aNavigator);
}
return success;
}
int
VRManagerChild::GetInputFrameID()
{
return mInputFrameID;
}
} // namespace gfx
} // namespace mozilla