import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

27
gfx/vr/ipc/PVRLayer.ipdl Normal file
View file

@ -0,0 +1,27 @@
/* -*- 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 protocol PVRManager;
include protocol PTexture;
namespace mozilla {
namespace gfx {
async protocol PVRLayer
{
manager PVRManager;
parent:
async SubmitFrame(PTexture aTexture);
async Destroy();
child:
async __delete__();
};
} // gfx
} // mozilla

View file

@ -0,0 +1,86 @@
/* -*- 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 LayersSurfaces;
include protocol PLayer;
include protocol PTexture;
include protocol PVRLayer;
include LayersMessages;
include GamepadEventTypes;
include "VRMessageUtils.h";
using struct mozilla::gfx::VRFieldOfView from "gfxVR.h";
using struct mozilla::gfx::VRDisplayInfo from "gfxVR.h";
using struct mozilla::gfx::VRSensorUpdate from "gfxVR.h";
using struct mozilla::gfx::VRHMDSensorState from "gfxVR.h";
using struct mozilla::gfx::VRControllerInfo from "gfxVR.h";
using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h";
using mozilla::layers::TextureFlags from "mozilla/layers/CompositorTypes.h";
namespace mozilla {
namespace gfx {
/**
* The PVRManager protocol is used to enable communication of VR display
* enumeration and sensor state between the compositor thread and
* content threads/processes.
*/
sync protocol PVRManager
{
manages PTexture;
manages PVRLayer;
parent:
async PTexture(SurfaceDescriptor aSharedData, LayersBackend aBackend,
TextureFlags aTextureFlags, uint64_t aSerial);
async PVRLayer(uint32_t aDisplayID, float aLeftEyeX, float aLeftEyeY, float aLeftEyeWidth, float aLeftEyeHeight, float aRightEyeX, float aRightEyeY, float aRightEyeWidth, float aRightEyeHeight);
// (Re)Enumerate VR Displays. An updated list of VR displays will be returned
// asynchronously to children via UpdateDisplayInfo.
async RefreshDisplays();
// GetDisplays synchronously returns the VR displays that have already been
// enumerated by RefreshDisplays() but does not enumerate new ones.
sync GetDisplays() returns(VRDisplayInfo[] aDisplayInfo);
// Reset the sensor of the display identified by aDisplayID so that the current
// sensor state is the "Zero" position.
async ResetSensor(uint32_t aDisplayID);
sync GetSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
sync GetImmediateSensorState(uint32_t aDisplayID) returns(VRHMDSensorState aState);
sync SetHaveEventListener(bool aHaveEventListener);
async ControllerListenerAdded();
async ControllerListenerRemoved();
// GetControllers synchronously returns the VR controllers that have already been
// enumerated by RefreshVRControllers() but does not enumerate new ones.
sync GetControllers() returns(VRControllerInfo[] aControllerInfo);
child:
async ParentAsyncMessages(AsyncParentMessageData[] aMessages);
// Notify children of updated VR display enumeration and details. This will
// be sent to all children when the parent receives RefreshDisplays, even
// if no changes have been detected. This ensures that Promises exposed
// through DOM calls are always resolved.
async UpdateDisplayInfo(VRDisplayInfo[] aDisplayUpdates);
async NotifyVSync();
async NotifyVRVSync(uint32_t aDisplayID);
async GamepadUpdate(GamepadChangeEvent aGamepadEvent);
async __delete__();
};
} // gfx
} // mozilla

View file

@ -0,0 +1,86 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "VRLayerChild.h"
#include "GLScreenBuffer.h"
#include "mozilla/layers/TextureClientSharedSurface.h"
#include "SharedSurface.h" // for SharedSurface
#include "SharedSurfaceGL.h" // for SharedSurface
#include "mozilla/layers/LayersMessages.h" // for TimedTexture
#include "nsICanvasRenderingContextInternal.h"
#include "mozilla/dom/HTMLCanvasElement.h"
namespace mozilla {
namespace gfx {
VRLayerChild::VRLayerChild(uint32_t aVRDisplayID, VRManagerChild* aVRManagerChild)
: mVRDisplayID(aVRDisplayID)
, mCanvasElement(nullptr)
, mShSurfClient(nullptr)
, mFront(nullptr)
{
MOZ_COUNT_CTOR(VRLayerChild);
}
VRLayerChild::~VRLayerChild()
{
if (mCanvasElement) {
mCanvasElement->StopVRPresentation();
}
ClearSurfaces();
MOZ_COUNT_DTOR(VRLayerChild);
}
void
VRLayerChild::Initialize(dom::HTMLCanvasElement* aCanvasElement)
{
MOZ_ASSERT(aCanvasElement);
mCanvasElement = aCanvasElement;
mCanvasElement->StartVRPresentation();
VRManagerChild *vrmc = VRManagerChild::Get();
vrmc->RunFrameRequestCallbacks();
}
void
VRLayerChild::SubmitFrame()
{
if (!mCanvasElement) {
return;
}
mShSurfClient = mCanvasElement->GetVRFrame();
if (!mShSurfClient) {
return;
}
gl::SharedSurface* surf = mShSurfClient->Surf();
if (surf->mType == gl::SharedSurfaceType::Basic) {
gfxCriticalError() << "SharedSurfaceType::Basic not supported for WebVR";
return;
}
mFront = mShSurfClient;
mShSurfClient = nullptr;
mFront->SetAddedToCompositableClient();
VRManagerChild* vrmc = VRManagerChild::Get();
mFront->SyncWithObject(vrmc->GetSyncObject());
MOZ_ALWAYS_TRUE(mFront->InitIPDLActor(vrmc));
SendSubmitFrame(mFront->GetIPDLActor());
}
void
VRLayerChild::ClearSurfaces()
{
mFront = nullptr;
mShSurfClient = nullptr;
}
} // namespace gfx
} // namespace mozilla

53
gfx/vr/ipc/VRLayerChild.h Normal file
View file

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 GFX_VR_LAYERCHILD_H
#define GFX_VR_LAYERCHILD_H
#include "VRManagerChild.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/PVRLayerChild.h"
#include "GLContext.h"
#include "gfxVR.h"
class nsICanvasRenderingContextInternal;
namespace mozilla {
class WebGLContext;
namespace dom {
class HTMLCanvasElement;
}
namespace layers {
class SharedSurfaceTextureClient;
}
namespace gl {
class SurfaceFactory;
}
namespace gfx {
class VRLayerChild : public PVRLayerChild {
NS_INLINE_DECL_REFCOUNTING(VRLayerChild)
public:
VRLayerChild(uint32_t aVRDisplayID, VRManagerChild* aVRManagerChild);
void Initialize(dom::HTMLCanvasElement* aCanvasElement);
void SubmitFrame();
protected:
virtual ~VRLayerChild();
void ClearSurfaces();
uint32_t mVRDisplayID;
RefPtr<dom::HTMLCanvasElement> mCanvasElement;
RefPtr<layers::SharedSurfaceTextureClient> mShSurfClient;
RefPtr<layers::TextureClient> mFront;
};
} // namespace gfx
} // namespace mozilla
#endif

View file

@ -0,0 +1,59 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 "VRLayerParent.h"
#include "mozilla/Unused.h"
namespace mozilla {
namespace gfx {
VRLayerParent::VRLayerParent(uint32_t aVRDisplayID, const Rect& aLeftEyeRect, const Rect& aRightEyeRect)
: mIPCOpen(true)
, mVRDisplayID(aVRDisplayID)
, mLeftEyeRect(aLeftEyeRect)
, mRightEyeRect(aRightEyeRect)
{
MOZ_COUNT_CTOR(VRLayerParent);
}
VRLayerParent::~VRLayerParent()
{
MOZ_COUNT_DTOR(VRLayerParent);
}
bool
VRLayerParent::RecvDestroy()
{
Destroy();
return true;
}
void
VRLayerParent::ActorDestroy(ActorDestroyReason aWhy)
{
mIPCOpen = false;
}
void
VRLayerParent::Destroy()
{
if (mIPCOpen) {
Unused << PVRLayerParent::Send__delete__(this);
}
}
bool
VRLayerParent::RecvSubmitFrame(PTextureParent* texture)
{
VRManager* vm = VRManager::Get();
vm->SubmitFrame(this, texture, mLeftEyeRect, mRightEyeRect);
return true;
}
} // namespace gfx
} // namespace mozilla

View file

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* 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 GFX_VR_LAYERPARENT_H
#define GFX_VR_LAYERPARENT_H
#include "VRManager.h"
#include "mozilla/RefPtr.h"
#include "mozilla/gfx/PVRLayerParent.h"
#include "gfxVR.h"
namespace mozilla {
namespace gfx {
class VRLayerParent : public PVRLayerParent {
NS_INLINE_DECL_REFCOUNTING(VRLayerParent)
public:
VRLayerParent(uint32_t aVRDisplayID, const Rect& aLeftEyeRect, const Rect& aRightEyeRect);
virtual bool RecvSubmitFrame(PTextureParent* texture) override;
virtual bool RecvDestroy() override;
uint32_t GetDisplayID() const { return mVRDisplayID; }
protected:
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual ~VRLayerParent();
void Destroy();
bool mIPCOpen;
uint32_t mVRDisplayID;
gfx::IntSize mSize;
gfx::Rect mLeftEyeRect;
gfx::Rect mRightEyeRect;
};
} // namespace gfx
} // namespace mozilla
#endif

View file

@ -0,0 +1,593 @@
/* -*- 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 "VRDisplayClient.h"
#include "nsGlobalWindow.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/layers/CompositorThread.h" // for CompositorThread
#include "mozilla/dom/Navigator.h"
#include "mozilla/dom/VREventObserver.h"
#include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback
#include "mozilla/dom/ContentChild.h"
#include "mozilla/layers/TextureClient.h"
#include "nsContentUtils.h"
#ifdef MOZ_GAMEPAD
#include "mozilla/dom/GamepadManager.h"
#endif
using layers::TextureClient;
namespace {
const nsTArray<RefPtr<dom::VREventObserver>>::index_type kNoIndex =
nsTArray<RefPtr<dom::VREventObserver> >::NoIndex;
} // namespace
namespace mozilla {
namespace gfx {
static StaticRefPtr<VRManagerChild> sVRManagerChildSingleton;
static StaticRefPtr<VRManagerParent> sVRManagerParentSingleton;
void ReleaseVRManagerParentSingleton() {
sVRManagerParentSingleton = nullptr;
}
VRManagerChild::VRManagerChild()
: TextureForwarder()
, mDisplaysInitialized(false)
, mInputFrameID(-1)
, mMessageLoop(MessageLoop::current())
, mFrameRequestCallbackCounter(0)
, mBackend(layers::LayersBackend::LAYERS_NONE)
{
MOZ_COUNT_CTOR(VRManagerChild);
MOZ_ASSERT(NS_IsMainThread());
mStartTimeStamp = TimeStamp::Now();
}
VRManagerChild::~VRManagerChild()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_COUNT_DTOR(VRManagerChild);
}
/*static*/ void
VRManagerChild::IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier)
{
if (sVRManagerChildSingleton) {
sVRManagerChildSingleton->mBackend = aIdentifier.mParentBackend;
sVRManagerChildSingleton->mSyncObject = SyncObject::CreateSyncObject(aIdentifier.mSyncHandle);
}
}
layers::LayersBackend
VRManagerChild::GetBackendType() const
{
return mBackend;
}
/*static*/ VRManagerChild*
VRManagerChild::Get()
{
MOZ_ASSERT(sVRManagerChildSingleton);
return sVRManagerChildSingleton;
}
/* static */ bool
VRManagerChild::IsCreated()
{
return !!sVRManagerChildSingleton;
}
/* static */ bool
VRManagerChild::InitForContent(Endpoint<PVRManagerChild>&& aEndpoint)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sVRManagerChildSingleton);
RefPtr<VRManagerChild> child(new VRManagerChild());
if (!aEndpoint.Bind(child)) {
NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
return false;
}
sVRManagerChildSingleton = child;
return true;
}
/* static */ bool
VRManagerChild::ReinitForContent(Endpoint<PVRManagerChild>&& aEndpoint)
{
MOZ_ASSERT(NS_IsMainThread());
ShutDown();
return InitForContent(Move(aEndpoint));
}
/*static*/ void
VRManagerChild::InitSameProcess()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sVRManagerChildSingleton);
sVRManagerChildSingleton = new VRManagerChild();
sVRManagerParentSingleton = VRManagerParent::CreateSameProcess();
sVRManagerChildSingleton->Open(sVRManagerParentSingleton->GetIPCChannel(),
mozilla::layers::CompositorThreadHolder::Loop(),
mozilla::ipc::ChildSide);
}
/* static */ void
VRManagerChild::InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sVRManagerChildSingleton);
sVRManagerChildSingleton = new VRManagerChild();
if (!aEndpoint.Bind(sVRManagerChildSingleton)) {
NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
return;
}
}
/*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()
{
mTexturesWaitingRecycled.Clear();
// 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(
NewRunnableFunction(DeferredDestroy, selfRef));
}
layers::PTextureChild*
VRManagerChild::AllocPTextureChild(const SurfaceDescriptor&,
const LayersBackend&,
const TextureFlags&,
const uint64_t&)
{
return TextureClient::CreateIPDLActor();
}
bool
VRManagerChild::DeallocPTextureChild(PTextureChild* actor)
{
return TextureClient::DestroyIPDLActor(actor);
}
PVRLayerChild*
VRManagerChild::AllocPVRLayerChild(const uint32_t& aDisplayID,
const float& aLeftEyeX,
const float& aLeftEyeY,
const float& aLeftEyeWidth,
const float& aLeftEyeHeight,
const float& aRightEyeX,
const float& aRightEyeY,
const float& aRightEyeWidth,
const float& aRightEyeHeight)
{
RefPtr<VRLayerChild> layer = new VRLayerChild(aDisplayID, this);
return layer.forget().take();
}
bool
VRManagerChild::DeallocPVRLayerChild(PVRLayerChild* actor)
{
delete actor;
return true;
}
void
VRManagerChild::UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates)
{
bool bDisplayConnected = false;
bool bDisplayDisconnected = false;
// Check if any displays have been disconnected
for (auto& display : mDisplays) {
bool found = false;
for (auto& displayUpdate : aDisplayUpdates) {
if (display->GetDisplayInfo().GetDisplayID() == displayUpdate.GetDisplayID()) {
found = true;
break;
}
}
if (!found) {
display->NotifyDisconnected();
bDisplayDisconnected = true;
}
}
// mDisplays could be a hashed container for more scalability, but not worth
// it now as we expect < 10 entries.
nsTArray<RefPtr<VRDisplayClient>> displays;
for (VRDisplayInfo& displayUpdate : aDisplayUpdates) {
bool isNewDisplay = true;
for (auto& display : mDisplays) {
const VRDisplayInfo& prevInfo = display->GetDisplayInfo();
if (prevInfo.GetDisplayID() == displayUpdate.GetDisplayID()) {
if (displayUpdate.GetIsConnected() && !prevInfo.GetIsConnected()) {
bDisplayConnected = true;
}
if (!displayUpdate.GetIsConnected() && prevInfo.GetIsConnected()) {
bDisplayDisconnected = true;
}
display->UpdateDisplayInfo(displayUpdate);
displays.AppendElement(display);
isNewDisplay = false;
break;
}
}
if (isNewDisplay) {
displays.AppendElement(new VRDisplayClient(displayUpdate));
bDisplayConnected = true;
}
}
mDisplays = displays;
if (bDisplayConnected) {
FireDOMVRDisplayConnectEvent();
}
if (bDisplayDisconnected) {
FireDOMVRDisplayDisconnectEvent();
}
mDisplaysInitialized = true;
}
bool
VRManagerChild::RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates)
{
UpdateDisplayInfo(aDisplayUpdates);
for (auto& windowId : mNavigatorCallbacks) {
/** We must call NotifyVRDisplaysUpdated for every
* window's Navigator in mNavigatorCallbacks to ensure that
* the promise returned by Navigator.GetVRDevices
* can resolve. This must happen even if no changes
* to VRDisplays have been detected here.
*/
nsGlobalWindow* window = nsGlobalWindow::GetInnerWindowWithId(windowId);
if (!window) {
continue;
}
ErrorResult result;
dom::Navigator* nav = window->GetNavigator(result);
if (NS_WARN_IF(result.Failed())) {
continue;
}
nav->NotifyVRDisplaysUpdated();
}
mNavigatorCallbacks.Clear();
return true;
}
bool
VRManagerChild::GetVRDisplays(nsTArray<RefPtr<VRDisplayClient>>& aDisplays)
{
if (!mDisplaysInitialized) {
/**
* If we haven't received any asynchronous callback after requesting
* display enumeration with RefreshDisplays, get the existing displays
* that have already been enumerated by other VRManagerChild instances.
*/
nsTArray<VRDisplayInfo> displays;
Unused << SendGetDisplays(&displays);
UpdateDisplayInfo(displays);
}
aDisplays = mDisplays;
return true;
}
bool
VRManagerChild::RefreshVRDisplaysWithCallback(uint64_t aWindowId)
{
bool success = SendRefreshDisplays();
if (success) {
mNavigatorCallbacks.AppendElement(aWindowId);
}
return success;
}
int
VRManagerChild::GetInputFrameID()
{
return mInputFrameID;
}
bool
VRManagerChild::RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages)
{
for (InfallibleTArray<AsyncParentMessageData>::index_type i = 0; i < aMessages.Length(); ++i) {
const AsyncParentMessageData& message = aMessages[i];
switch (message.type()) {
case AsyncParentMessageData::TOpNotifyNotUsed: {
const OpNotifyNotUsed& op = message.get_OpNotifyNotUsed();
NotifyNotUsed(op.TextureId(), op.fwdTransactionId());
break;
}
default:
NS_ERROR("unknown AsyncParentMessageData type");
return false;
}
}
return true;
}
PTextureChild*
VRManagerChild::CreateTexture(const SurfaceDescriptor& aSharedData,
LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial)
{
return SendPTextureConstructor(aSharedData, aLayersBackend, aFlags, aSerial);
}
void
VRManagerChild::CancelWaitForRecycle(uint64_t aTextureId)
{
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
if (!client) {
return;
}
mTexturesWaitingRecycled.Remove(aTextureId);
}
void
VRManagerChild::NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId)
{
RefPtr<TextureClient> client = mTexturesWaitingRecycled.Get(aTextureId);
if (!client) {
return;
}
mTexturesWaitingRecycled.Remove(aTextureId);
}
bool
VRManagerChild::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
return PVRManagerChild::AllocShmem(aSize, aType, aShmem);
}
bool
VRManagerChild::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
return PVRManagerChild::AllocUnsafeShmem(aSize, aType, aShmem);
}
bool
VRManagerChild::DeallocShmem(ipc::Shmem& aShmem)
{
return PVRManagerChild::DeallocShmem(aShmem);
}
PVRLayerChild*
VRManagerChild::CreateVRLayer(uint32_t aDisplayID, const Rect& aLeftEyeRect, const Rect& aRightEyeRect)
{
return SendPVRLayerConstructor(aDisplayID,
aLeftEyeRect.x, aLeftEyeRect.y, aLeftEyeRect.width, aLeftEyeRect.height,
aRightEyeRect.x, aRightEyeRect.y, aRightEyeRect.width, aRightEyeRect.height);
}
// XXX TODO - VRManagerChild::FrameRequest is the same as nsIDocument::FrameRequest, should we consolodate these?
struct VRManagerChild::FrameRequest
{
FrameRequest(mozilla::dom::FrameRequestCallback& aCallback,
int32_t aHandle) :
mCallback(&aCallback),
mHandle(aHandle)
{}
// Conversion operator so that we can append these to a
// FrameRequestCallbackList
operator const RefPtr<mozilla::dom::FrameRequestCallback>& () const {
return mCallback;
}
// Comparator operators to allow RemoveElementSorted with an
// integer argument on arrays of FrameRequest
bool operator==(int32_t aHandle) const {
return mHandle == aHandle;
}
bool operator<(int32_t aHandle) const {
return mHandle < aHandle;
}
RefPtr<mozilla::dom::FrameRequestCallback> mCallback;
int32_t mHandle;
};
nsresult
VRManagerChild::ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
int32_t *aHandle)
{
if (mFrameRequestCallbackCounter == INT32_MAX) {
// Can't increment without overflowing; bail out
return NS_ERROR_NOT_AVAILABLE;
}
int32_t newHandle = ++mFrameRequestCallbackCounter;
DebugOnly<FrameRequest*> request =
mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle));
NS_ASSERTION(request, "This is supposed to be infallible!");
*aHandle = newHandle;
return NS_OK;
}
void
VRManagerChild::CancelFrameRequestCallback(int32_t aHandle)
{
// mFrameRequestCallbacks is stored sorted by handle
mFrameRequestCallbacks.RemoveElementSorted(aHandle);
}
bool
VRManagerChild::RecvNotifyVSync()
{
for (auto& display : mDisplays) {
display->NotifyVsync();
}
return true;
}
bool
VRManagerChild::RecvNotifyVRVSync(const uint32_t& aDisplayID)
{
for (auto& display : mDisplays) {
if (display->GetDisplayInfo().GetDisplayID() == aDisplayID) {
display->NotifyVRVsync();
}
}
return true;
}
bool
VRManagerChild::RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
{
#ifdef MOZ_GAMEPAD
// VRManagerChild could be at other processes, but GamepadManager
// only exists at the content process or the same process
// in non-e10s mode.
MOZ_ASSERT(XRE_IsContentProcess() || IsSameProcess());
RefPtr<GamepadManager> gamepadManager(GamepadManager::GetService());
if (gamepadManager) {
gamepadManager->Update(aGamepadEvent);
}
#endif
return true;
}
void
VRManagerChild::RunFrameRequestCallbacks()
{
TimeStamp nowTime = TimeStamp::Now();
mozilla::TimeDuration duration = nowTime - mStartTimeStamp;
DOMHighResTimeStamp timeStamp = duration.ToMilliseconds();
nsTArray<FrameRequest> callbacks;
callbacks.AppendElements(mFrameRequestCallbacks);
mFrameRequestCallbacks.Clear();
for (auto& callback : callbacks) {
callback.mCallback->Call(timeStamp);
}
}
void
VRManagerChild::FireDOMVRDisplayConnectEvent()
{
nsContentUtils::AddScriptRunner(NewRunnableMethod(this,
&VRManagerChild::FireDOMVRDisplayConnectEventInternal));
}
void
VRManagerChild::FireDOMVRDisplayDisconnectEvent()
{
nsContentUtils::AddScriptRunner(NewRunnableMethod(this,
&VRManagerChild::FireDOMVRDisplayDisconnectEventInternal));
}
void
VRManagerChild::FireDOMVRDisplayPresentChangeEvent()
{
nsContentUtils::AddScriptRunner(NewRunnableMethod(this,
&VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal));
}
void
VRManagerChild::FireDOMVRDisplayConnectEventInternal()
{
for (auto& listener : mListeners) {
listener->NotifyVRDisplayConnect();
}
}
void
VRManagerChild::FireDOMVRDisplayDisconnectEventInternal()
{
for (auto& listener : mListeners) {
listener->NotifyVRDisplayDisconnect();
}
}
void
VRManagerChild::FireDOMVRDisplayPresentChangeEventInternal()
{
for (auto& listener : mListeners) {
listener->NotifyVRDisplayPresentChange();
}
}
void
VRManagerChild::AddListener(dom::VREventObserver* aObserver)
{
MOZ_ASSERT(aObserver);
if (mListeners.IndexOf(aObserver) != kNoIndex) {
return; // already exists
}
mListeners.AppendElement(aObserver);
if (mListeners.Length() == 1) {
Unused << SendSetHaveEventListener(true);
}
}
void
VRManagerChild::RemoveListener(dom::VREventObserver* aObserver)
{
MOZ_ASSERT(aObserver);
mListeners.RemoveElement(aObserver);
if (mListeners.IsEmpty()) {
Unused << SendSetHaveEventListener(false);
}
}
void
VRManagerChild::HandleFatalError(const char* aName, const char* aMsg) const
{
dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid());
}
} // namespace gfx
} // namespace mozilla

185
gfx/vr/ipc/VRManagerChild.h Normal file
View file

@ -0,0 +1,185 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_VR_VRMANAGERCHILD_H
#define MOZILLA_GFX_VR_VRMANAGERCHILD_H
#include "mozilla/gfx/PVRManagerChild.h"
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersTypes.h" // for LayersBackend
#include "mozilla/layers/TextureForwarder.h"
namespace mozilla {
namespace dom {
class GamepadManager;
class Navigator;
class VRDisplay;
class VREventObserver;
} // namespace dom
namespace layers {
class PCompositableChild;
class TextureClient;
}
namespace gfx {
class VRLayerChild;
class VRDisplayClient;
class VRManagerChild : public PVRManagerChild
, public layers::TextureForwarder
, public layers::KnowsCompositor
{
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRManagerChild, override);
TextureForwarder* GetTextureForwarder() override { return this; }
LayersIPCActor* GetLayersIPCActor() override { return this; }
static VRManagerChild* Get();
// Indicate that an observer wants to receive VR events.
void AddListener(dom::VREventObserver* aObserver);
// Indicate that an observer should no longer receive VR events.
void RemoveListener(dom::VREventObserver* aObserver);
int GetInputFrameID();
bool GetVRDisplays(nsTArray<RefPtr<VRDisplayClient> >& aDisplays);
bool RefreshVRDisplaysWithCallback(uint64_t aWindowId);
static void InitSameProcess();
static void InitWithGPUProcess(Endpoint<PVRManagerChild>&& aEndpoint);
static bool InitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
static bool ReinitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
static void ShutDown();
static bool IsCreated();
virtual PTextureChild* CreateTexture(const SurfaceDescriptor& aSharedData,
layers::LayersBackend aLayersBackend,
TextureFlags aFlags,
uint64_t aSerial) override;
virtual void CancelWaitForRecycle(uint64_t aTextureId) override;
PVRLayerChild* CreateVRLayer(uint32_t aDisplayID, const Rect& aLeftEyeRect, const Rect& aRightEyeRect);
static void IdentifyTextureHost(const layers::TextureFactoryIdentifier& aIdentifier);
layers::LayersBackend GetBackendType() const;
layers::SyncObject* GetSyncObject() { return mSyncObject; }
virtual MessageLoop* GetMessageLoop() const override { return mMessageLoop; }
virtual base::ProcessId GetParentPid() const override { return OtherPid(); }
nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback,
int32_t *aHandle);
void CancelFrameRequestCallback(int32_t aHandle);
void RunFrameRequestCallbacks();
void UpdateDisplayInfo(nsTArray<VRDisplayInfo>& aDisplayUpdates);
void FireDOMVRDisplayConnectEvent();
void FireDOMVRDisplayDisconnectEvent();
void FireDOMVRDisplayPresentChangeEvent();
virtual void HandleFatalError(const char* aName, const char* aMsg) const override;
protected:
explicit VRManagerChild();
~VRManagerChild();
void Destroy();
static void DeferredDestroy(RefPtr<VRManagerChild> aVRManagerChild);
virtual PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
const layers::LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial) override;
virtual bool DeallocPTextureChild(PTextureChild* actor) override;
virtual PVRLayerChild* AllocPVRLayerChild(const uint32_t& aDisplayID,
const float& aLeftEyeX,
const float& aLeftEyeY,
const float& aLeftEyeWidth,
const float& aLeftEyeHeight,
const float& aRightEyeX,
const float& aRightEyeY,
const float& aRightEyeWidth,
const float& aRightEyeHeight) override;
virtual bool DeallocPVRLayerChild(PVRLayerChild* actor) override;
virtual bool RecvUpdateDisplayInfo(nsTArray<VRDisplayInfo>&& aDisplayUpdates) override;
virtual bool RecvParentAsyncMessages(InfallibleTArray<AsyncParentMessageData>&& aMessages) override;
virtual bool RecvNotifyVSync() override;
virtual bool RecvNotifyVRVSync(const uint32_t& aDisplayID) override;
virtual bool RecvGamepadUpdate(const GamepadChangeEvent& aGamepadEvent) override;
// ShmemAllocator
virtual bool AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) override;
virtual bool AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) override;
virtual bool DeallocShmem(ipc::Shmem& aShmem) override;
virtual bool IsSameProcess() const override
{
return OtherPid() == base::GetCurrentProcId();
}
friend class layers::CompositorBridgeChild;
private:
void FireDOMVRDisplayConnectEventInternal();
void FireDOMVRDisplayDisconnectEventInternal();
void FireDOMVRDisplayPresentChangeEventInternal();
/**
* Notify id of Texture When host side end its use. Transaction id is used to
* make sure if there is no newer usage.
*/
void NotifyNotUsed(uint64_t aTextureId, uint64_t aFwdTransactionId);
nsTArray<RefPtr<VRDisplayClient> > mDisplays;
bool mDisplaysInitialized;
nsTArray<uint64_t> mNavigatorCallbacks;
int32_t mInputFrameID;
MessageLoop* mMessageLoop;
struct FrameRequest;
nsTArray<FrameRequest> mFrameRequestCallbacks;
/**
* The current frame request callback handle
*/
int32_t mFrameRequestCallbackCounter;
mozilla::TimeStamp mStartTimeStamp;
// Array of Weak pointers, instance is owned by nsGlobalWindow::mVREventObserver.
nsTArray<dom::VREventObserver*> mListeners;
/**
* Hold TextureClients refs until end of their usages on host side.
* It defer calling of TextureClient recycle callback.
*/
nsDataHashtable<nsUint64HashKey, RefPtr<layers::TextureClient> > mTexturesWaitingRecycled;
layers::LayersBackend mBackend;
RefPtr<layers::SyncObject> mSyncObject;
DISALLOW_COPY_AND_ASSIGN(VRManagerChild);
};
} // namespace mozilla
} // namespace gfx
#endif // MOZILLA_GFX_VR_VRMANAGERCHILD_H

View file

@ -0,0 +1,332 @@
/* -*- 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 "VRManagerParent.h"
#include "ipc/VRLayerParent.h"
#include "mozilla/gfx/PVRManagerParent.h"
#include "mozilla/ipc/ProtocolTypes.h"
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/Unused.h"
#include "VRManager.h"
namespace mozilla {
using namespace layers;
namespace gfx {
VRManagerParent::VRManagerParent(ProcessId aChildProcessId, bool aIsContentChild)
: HostIPCAllocator()
, mHaveEventListener(false)
, mIsContentChild(aIsContentChild)
{
MOZ_COUNT_CTOR(VRManagerParent);
MOZ_ASSERT(NS_IsMainThread());
SetOtherProcessId(aChildProcessId);
}
VRManagerParent::~VRManagerParent()
{
MOZ_ASSERT(!mVRManagerHolder);
MOZ_COUNT_DTOR(VRManagerParent);
}
PTextureParent*
VRManagerParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial)
{
return layers::TextureHost::CreateIPDLActor(this, aSharedData, aLayersBackend, aFlags, aSerial);
}
bool
VRManagerParent::DeallocPTextureParent(PTextureParent* actor)
{
return layers::TextureHost::DestroyIPDLActor(actor);
}
PVRLayerParent*
VRManagerParent::AllocPVRLayerParent(const uint32_t& aDisplayID,
const float& aLeftEyeX,
const float& aLeftEyeY,
const float& aLeftEyeWidth,
const float& aLeftEyeHeight,
const float& aRightEyeX,
const float& aRightEyeY,
const float& aRightEyeWidth,
const float& aRightEyeHeight)
{
RefPtr<VRLayerParent> layer;
layer = new VRLayerParent(aDisplayID,
Rect(aLeftEyeX, aLeftEyeY, aLeftEyeWidth, aLeftEyeHeight),
Rect(aRightEyeX, aRightEyeY, aRightEyeWidth, aRightEyeHeight));
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display) {
display->AddLayer(layer);
}
return layer.forget().take();
}
bool
VRManagerParent::DeallocPVRLayerParent(PVRLayerParent* actor)
{
gfx::VRLayerParent* layer = static_cast<gfx::VRLayerParent*>(actor);
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(layer->GetDisplayID());
if (display) {
display->RemoveLayer(layer);
}
delete actor;
return true;
}
bool
VRManagerParent::AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
return PVRManagerParent::AllocShmem(aSize, aType, aShmem);
}
bool
VRManagerParent::AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem)
{
return PVRManagerParent::AllocUnsafeShmem(aSize, aType, aShmem);
}
void
VRManagerParent::DeallocShmem(ipc::Shmem& aShmem)
{
PVRManagerParent::DeallocShmem(aShmem);
}
bool
VRManagerParent::IsSameProcess() const
{
return OtherPid() == base::GetCurrentProcId();
}
void
VRManagerParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
}
void
VRManagerParent::SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage)
{
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
}
base::ProcessId
VRManagerParent::GetChildProcessId()
{
return OtherPid();
}
void
VRManagerParent::RegisterWithManager()
{
VRManager* vm = VRManager::Get();
vm->AddVRManagerParent(this);
mVRManagerHolder = vm;
}
void
VRManagerParent::UnregisterFromManager()
{
VRManager* vm = VRManager::Get();
vm->RemoveVRManagerParent(this);
mVRManagerHolder = nullptr;
}
/* static */ bool
VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
{
MessageLoop* loop = layers::CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), true);
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
vmp, &VRManagerParent::Bind, Move(aEndpoint)));
return true;
}
void
VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint)
{
if (!aEndpoint.Bind(this)) {
return;
}
mSelfRef = this;
RegisterWithManager();
}
/*static*/ void
VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
{
aVRManager->RegisterWithManager();
}
/*static*/ VRManagerParent*
VRManagerParent::CreateSameProcess()
{
MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId(), false);
vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
vmp->mSelfRef = vmp;
loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
return vmp.get();
}
bool
VRManagerParent::CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint)
{
MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid(), false);
vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
vmp, &VRManagerParent::Bind, Move(aEndpoint)));
return true;
}
void
VRManagerParent::DeferredDestroy()
{
mCompositorThreadHolder = nullptr;
mSelfRef = nullptr;
}
void
VRManagerParent::ActorDestroy(ActorDestroyReason why)
{
UnregisterFromManager();
MessageLoop::current()->PostTask(NewRunnableMethod(this, &VRManagerParent::DeferredDestroy));
}
void
VRManagerParent::OnChannelConnected(int32_t aPid)
{
mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
}
bool
VRManagerParent::RecvRefreshDisplays()
{
// This is called to refresh the VR Displays for Navigator.GetVRDevices().
// We must pass "true" to VRManager::RefreshVRDisplays()
// to ensure that the promise returned by Navigator.GetVRDevices
// can resolve even if there are no changes to the VR Displays.
VRManager* vm = VRManager::Get();
vm->RefreshVRDisplays(true);
return true;
}
bool
VRManagerParent::RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays)
{
VRManager* vm = VRManager::Get();
vm->GetVRDisplayInfo(*aDisplays);
return true;
}
bool
VRManagerParent::RecvResetSensor(const uint32_t& aDisplayID)
{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display != nullptr) {
display->ZeroSensor();
}
return true;
}
bool
VRManagerParent::RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState)
{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display != nullptr) {
*aState = display->GetSensorState();
}
return true;
}
bool
VRManagerParent::RecvGetImmediateSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState)
{
VRManager* vm = VRManager::Get();
RefPtr<gfx::VRDisplayHost> display = vm->GetDisplay(aDisplayID);
if (display != nullptr) {
*aState = display->GetImmediateSensorState();
}
return true;
}
bool
VRManagerParent::HaveEventListener()
{
return mHaveEventListener;
}
bool
VRManagerParent::RecvSetHaveEventListener(const bool& aHaveEventListener)
{
mHaveEventListener = aHaveEventListener;
return true;
}
bool
VRManagerParent::RecvControllerListenerAdded()
{
VRManager* vm = VRManager::Get();
// Ask the connected gamepads to be added to GamepadManager
vm->ScanForDevices();
return true;
}
bool
VRManagerParent::RecvControllerListenerRemoved()
{
return true;
}
bool
VRManagerParent::RecvGetControllers(nsTArray<VRControllerInfo> *aControllers)
{
VRManager* vm = VRManager::Get();
vm->GetVRControllerInfo(*aControllers);
return true;
}
bool
VRManagerParent::SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent)
{
// GamepadManager only exists at the content process
// or the same process in non-e10s mode.
if (mIsContentChild || IsSameProcess()) {
return PVRManagerParent::SendGamepadUpdate(aGamepadEvent);
} else {
return true;
}
}
} // namespace gfx
} // namespace mozilla

View file

@ -0,0 +1,118 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_VR_VRMANAGERPARENT_H
#define MOZILLA_GFX_VR_VRMANAGERPARENT_H
#include "mozilla/layers/CompositableTransactionParent.h"
#include "mozilla/layers/CompositorThread.h" // for CompositorThreadHolder
#include "mozilla/gfx/PVRManagerParent.h" // for PVRManagerParent
#include "mozilla/gfx/PVRLayerParent.h" // for PVRLayerParent
#include "mozilla/ipc/ProtocolUtils.h" // for IToplevelProtocol
#include "mozilla/TimeStamp.h" // for TimeStamp
#include "gfxVR.h" // for VRFieldOfView
namespace mozilla {
using namespace layers;
namespace gfx {
class VRManager;
class VRManagerParent final : public PVRManagerParent
, public HostIPCAllocator
, public ShmemAllocator
{
public:
explicit VRManagerParent(ProcessId aChildProcessId, bool aIsContentChild);
static VRManagerParent* CreateSameProcess();
static bool CreateForGPUProcess(Endpoint<PVRManagerParent>&& aEndpoint);
static bool CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint);
virtual base::ProcessId GetChildProcessId() override;
// ShmemAllocator
virtual ShmemAllocator* AsShmemAllocator() override { return this; }
virtual bool AllocShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) override;
virtual bool AllocUnsafeShmem(size_t aSize,
ipc::SharedMemory::SharedMemoryType aType,
ipc::Shmem* aShmem) override;
virtual void DeallocShmem(ipc::Shmem& aShmem) override;
virtual bool IsSameProcess() const override;
bool HaveEventListener();
virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
bool SendGamepadUpdate(const GamepadChangeEvent& aGamepadEvent);
protected:
~VRManagerParent();
virtual PTextureParent* AllocPTextureParent(const SurfaceDescriptor& aSharedData,
const LayersBackend& aLayersBackend,
const TextureFlags& aFlags,
const uint64_t& aSerial) override;
virtual bool DeallocPTextureParent(PTextureParent* actor) override;
virtual PVRLayerParent* AllocPVRLayerParent(const uint32_t& aDisplayID,
const float& aLeftEyeX,
const float& aLeftEyeY,
const float& aLeftEyeWidth,
const float& aLeftEyeHeight,
const float& aRightEyeX,
const float& aRightEyeY,
const float& aRightEyeWidth,
const float& aRightEyeHeight) override;
virtual bool DeallocPVRLayerParent(PVRLayerParent* actor) override;
virtual void ActorDestroy(ActorDestroyReason why) override;
void OnChannelConnected(int32_t pid) override;
virtual bool RecvRefreshDisplays() override;
virtual bool RecvGetDisplays(nsTArray<VRDisplayInfo> *aDisplays) override;
virtual bool RecvResetSensor(const uint32_t& aDisplayID) override;
virtual bool RecvGetSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
virtual bool RecvGetImmediateSensorState(const uint32_t& aDisplayID, VRHMDSensorState* aState) override;
virtual bool RecvSetHaveEventListener(const bool& aHaveEventListener) override;
virtual bool RecvControllerListenerAdded() override;
virtual bool RecvControllerListenerRemoved() override;
virtual bool RecvGetControllers(nsTArray<VRControllerInfo> *aControllers) override;
private:
void RegisterWithManager();
void UnregisterFromManager();
void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
void DeferredDestroy();
// This keeps us alive until ActorDestroy(), at which point we do a
// deferred destruction of ourselves.
RefPtr<VRManagerParent> mSelfRef;
// Keep the compositor thread alive, until we have destroyed ourselves.
RefPtr<layers::CompositorThreadHolder> mCompositorThreadHolder;
// Keep the VRManager alive, until we have destroyed ourselves.
RefPtr<VRManager> mVRManagerHolder;
bool mHaveEventListener;
bool mIsContentChild;
};
} // namespace mozilla
} // namespace gfx
#endif // MOZILLA_GFX_VR_VRMANAGERPARENT_H

193
gfx/vr/ipc/VRMessageUtils.h Normal file
View file

@ -0,0 +1,193 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* 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 mozilla_gfx_vr_VRMessageUtils_h
#define mozilla_gfx_vr_VRMessageUtils_h
#include "ipc/IPCMessageUtils.h"
#include "mozilla/GfxMessageUtils.h"
#include "VRManager.h"
#include "gfxVR.h"
namespace IPC {
template<>
struct ParamTraits<mozilla::gfx::VRDeviceType> :
public ContiguousEnumSerializer<mozilla::gfx::VRDeviceType,
mozilla::gfx::VRDeviceType(0),
mozilla::gfx::VRDeviceType(mozilla::gfx::VRDeviceType::NumVRDeviceTypes)> {};
template<>
struct ParamTraits<mozilla::gfx::VRDisplayCapabilityFlags> :
public BitFlagsEnumSerializer<mozilla::gfx::VRDisplayCapabilityFlags,
mozilla::gfx::VRDisplayCapabilityFlags::Cap_All> {};
template <>
struct ParamTraits<mozilla::gfx::VRDisplayInfo>
{
typedef mozilla::gfx::VRDisplayInfo paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mDisplayID);
WriteParam(aMsg, aParam.mDisplayName);
WriteParam(aMsg, aParam.mCapabilityFlags);
WriteParam(aMsg, aParam.mEyeResolution);
WriteParam(aMsg, aParam.mIsConnected);
WriteParam(aMsg, aParam.mIsPresenting);
WriteParam(aMsg, aParam.mStageSize);
WriteParam(aMsg, aParam.mSittingToStandingTransform);
for (int i = 0; i < mozilla::gfx::VRDisplayInfo::NumEyes; i++) {
WriteParam(aMsg, aParam.mEyeFOV[i]);
WriteParam(aMsg, aParam.mEyeTranslation[i]);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
!ReadParam(aMsg, aIter, &(aResult->mDisplayID)) ||
!ReadParam(aMsg, aIter, &(aResult->mDisplayName)) ||
!ReadParam(aMsg, aIter, &(aResult->mCapabilityFlags)) ||
!ReadParam(aMsg, aIter, &(aResult->mEyeResolution)) ||
!ReadParam(aMsg, aIter, &(aResult->mIsConnected)) ||
!ReadParam(aMsg, aIter, &(aResult->mIsPresenting)) ||
!ReadParam(aMsg, aIter, &(aResult->mStageSize)) ||
!ReadParam(aMsg, aIter, &(aResult->mSittingToStandingTransform))) {
return false;
}
for (int i = 0; i < mozilla::gfx::VRDisplayInfo::NumEyes; i++) {
if (!ReadParam(aMsg, aIter, &(aResult->mEyeFOV[i])) ||
!ReadParam(aMsg, aIter, &(aResult->mEyeTranslation[i]))) {
return false;
}
}
return true;
}
};
template <>
struct ParamTraits<mozilla::gfx::VRHMDSensorState>
{
typedef mozilla::gfx::VRHMDSensorState paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.timestamp);
WriteParam(aMsg, aParam.inputFrameID);
WriteParam(aMsg, aParam.flags);
WriteParam(aMsg, aParam.orientation[0]);
WriteParam(aMsg, aParam.orientation[1]);
WriteParam(aMsg, aParam.orientation[2]);
WriteParam(aMsg, aParam.orientation[3]);
WriteParam(aMsg, aParam.position[0]);
WriteParam(aMsg, aParam.position[1]);
WriteParam(aMsg, aParam.position[2]);
WriteParam(aMsg, aParam.angularVelocity[0]);
WriteParam(aMsg, aParam.angularVelocity[1]);
WriteParam(aMsg, aParam.angularVelocity[2]);
WriteParam(aMsg, aParam.angularAcceleration[0]);
WriteParam(aMsg, aParam.angularAcceleration[1]);
WriteParam(aMsg, aParam.angularAcceleration[2]);
WriteParam(aMsg, aParam.linearVelocity[0]);
WriteParam(aMsg, aParam.linearVelocity[1]);
WriteParam(aMsg, aParam.linearVelocity[2]);
WriteParam(aMsg, aParam.linearAcceleration[0]);
WriteParam(aMsg, aParam.linearAcceleration[1]);
WriteParam(aMsg, aParam.linearAcceleration[2]);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->timestamp)) ||
!ReadParam(aMsg, aIter, &(aResult->inputFrameID)) ||
!ReadParam(aMsg, aIter, &(aResult->flags)) ||
!ReadParam(aMsg, aIter, &(aResult->orientation[0])) ||
!ReadParam(aMsg, aIter, &(aResult->orientation[1])) ||
!ReadParam(aMsg, aIter, &(aResult->orientation[2])) ||
!ReadParam(aMsg, aIter, &(aResult->orientation[3])) ||
!ReadParam(aMsg, aIter, &(aResult->position[0])) ||
!ReadParam(aMsg, aIter, &(aResult->position[1])) ||
!ReadParam(aMsg, aIter, &(aResult->position[2])) ||
!ReadParam(aMsg, aIter, &(aResult->angularVelocity[0])) ||
!ReadParam(aMsg, aIter, &(aResult->angularVelocity[1])) ||
!ReadParam(aMsg, aIter, &(aResult->angularVelocity[2])) ||
!ReadParam(aMsg, aIter, &(aResult->angularAcceleration[0])) ||
!ReadParam(aMsg, aIter, &(aResult->angularAcceleration[1])) ||
!ReadParam(aMsg, aIter, &(aResult->angularAcceleration[2])) ||
!ReadParam(aMsg, aIter, &(aResult->linearVelocity[0])) ||
!ReadParam(aMsg, aIter, &(aResult->linearVelocity[1])) ||
!ReadParam(aMsg, aIter, &(aResult->linearVelocity[2])) ||
!ReadParam(aMsg, aIter, &(aResult->linearAcceleration[0])) ||
!ReadParam(aMsg, aIter, &(aResult->linearAcceleration[1])) ||
!ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) {
return false;
}
return true;
}
};
template <>
struct ParamTraits<mozilla::gfx::VRFieldOfView>
{
typedef mozilla::gfx::VRFieldOfView paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.upDegrees);
WriteParam(aMsg, aParam.rightDegrees);
WriteParam(aMsg, aParam.downDegrees);
WriteParam(aMsg, aParam.leftDegrees);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->upDegrees)) ||
!ReadParam(aMsg, aIter, &(aResult->rightDegrees)) ||
!ReadParam(aMsg, aIter, &(aResult->downDegrees)) ||
!ReadParam(aMsg, aIter, &(aResult->leftDegrees))) {
return false;
}
return true;
}
};
template <>
struct ParamTraits<mozilla::gfx::VRControllerInfo>
{
typedef mozilla::gfx::VRControllerInfo paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mType);
WriteParam(aMsg, aParam.mControllerID);
WriteParam(aMsg, aParam.mControllerName);
WriteParam(aMsg, aParam.mMappingType);
WriteParam(aMsg, aParam.mNumButtons);
WriteParam(aMsg, aParam.mNumAxes);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mType)) ||
!ReadParam(aMsg, aIter, &(aResult->mControllerID)) ||
!ReadParam(aMsg, aIter, &(aResult->mControllerName)) ||
!ReadParam(aMsg, aIter, &(aResult->mMappingType)) ||
!ReadParam(aMsg, aIter, &(aResult->mNumButtons)) ||
!ReadParam(aMsg, aIter, &(aResult->mNumAxes))) {
return false;
}
return true;
}
};
} // namespace IPC
#endif // mozilla_gfx_vr_VRMessageUtils_h