зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1617023 - Part 1: Integrating Gamepad with XRInputSource. r=kip
Differential Revision: https://phabricator.services.mozilla.com/D67431 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
e2003e251b
Коммит
91ad9bdf58
|
@ -50,6 +50,27 @@ const uint32_t VR_GAMEPAD_IDX_OFFSET = 0x01 << 16;
|
|||
|
||||
NS_IMPL_ISUPPORTS(GamepadManager, nsIObserver)
|
||||
|
||||
/*static*/
|
||||
uint32_t GamepadManager::GetGamepadIndexWithServiceType(
|
||||
uint32_t aIndex, GamepadServiceType aServiceType) {
|
||||
uint32_t newIndex = 0;
|
||||
|
||||
switch (aServiceType) {
|
||||
case GamepadServiceType::Standard:
|
||||
MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
|
||||
newIndex = aIndex;
|
||||
break;
|
||||
case GamepadServiceType::VR:
|
||||
newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
GamepadManager::GamepadManager()
|
||||
: mEnabled(false),
|
||||
mNonstandardEventsEnabled(false),
|
||||
|
@ -195,26 +216,6 @@ already_AddRefed<Gamepad> GamepadManager::GetGamepad(
|
|||
return GetGamepad(GetGamepadIndexWithServiceType(aGamepadId, aServiceType));
|
||||
}
|
||||
|
||||
uint32_t GamepadManager::GetGamepadIndexWithServiceType(
|
||||
uint32_t aIndex, GamepadServiceType aServiceType) const {
|
||||
uint32_t newIndex = 0;
|
||||
|
||||
switch (aServiceType) {
|
||||
case GamepadServiceType::Standard:
|
||||
MOZ_ASSERT(aIndex <= VR_GAMEPAD_IDX_OFFSET);
|
||||
newIndex = aIndex;
|
||||
break;
|
||||
case GamepadServiceType::VR:
|
||||
newIndex = aIndex + VR_GAMEPAD_IDX_OFFSET;
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return newIndex;
|
||||
}
|
||||
|
||||
void GamepadManager::AddGamepad(uint32_t aIndex, const nsAString& aId,
|
||||
GamepadMappingType aMapping, GamepadHand aHand,
|
||||
GamepadServiceType aServiceType,
|
||||
|
|
|
@ -35,6 +35,11 @@ class GamepadManager final : public nsIObserver {
|
|||
// Get the singleton service
|
||||
static already_AddRefed<GamepadManager> GetService();
|
||||
|
||||
// Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
|
||||
// is from VRManager.
|
||||
static uint32_t GetGamepadIndexWithServiceType(
|
||||
uint32_t aIndex, GamepadServiceType aServiceType);
|
||||
|
||||
void BeginShutdown();
|
||||
void StopMonitoring();
|
||||
|
||||
|
@ -139,10 +144,6 @@ class GamepadManager final : public nsIObserver {
|
|||
// Indicate that a window has received data from a gamepad.
|
||||
void SetWindowHasSeenGamepad(nsGlobalWindowInner* aWindow, uint32_t aIndex,
|
||||
bool aHasSeen = true);
|
||||
// Our gamepad index has VR_GAMEPAD_IDX_OFFSET while GamepadChannelType
|
||||
// is from VRManager.
|
||||
uint32_t GetGamepadIndexWithServiceType(
|
||||
uint32_t aIndex, GamepadServiceType aServiceType) const;
|
||||
|
||||
// Gamepads connected to the system. Copies of these are handed out
|
||||
// to each window.
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
#include "XRNativeOriginViewer.h"
|
||||
#include "XRNativeOriginTracker.h"
|
||||
|
||||
#include "mozilla/dom/Gamepad.h"
|
||||
#include "mozilla/dom/GamepadManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
@ -102,7 +105,17 @@ nsTArray<nsString> GetInputSourceProfile(VRControllerType aType) {
|
|||
return profile;
|
||||
}
|
||||
|
||||
XRInputSource::XRInputSource(nsISupports* aParent) : mParent(aParent) {}
|
||||
XRInputSource::XRInputSource(nsISupports* aParent)
|
||||
: mParent(aParent),
|
||||
mGamepad(nullptr),
|
||||
mIndex(-1) {}
|
||||
|
||||
XRInputSource::~XRInputSource() {
|
||||
mTargetRaySpace = nullptr;
|
||||
mGripSpace = nullptr;
|
||||
mGamepad = nullptr;
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
JSObject* XRInputSource::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) {
|
||||
|
@ -130,8 +143,7 @@ void XRInputSource::GetProfiles(nsTArray<nsString>& aResult) {
|
|||
}
|
||||
|
||||
Gamepad* XRInputSource::GetGamepad() {
|
||||
// TODO (Bug 1617023): Implement Gamepad for XRInputSource.
|
||||
return nullptr;
|
||||
return mGamepad;
|
||||
}
|
||||
|
||||
void XRInputSource::Setup(XRSession* aSession, uint32_t aIndex) {
|
||||
|
@ -186,13 +198,51 @@ void XRInputSource::Setup(XRSession* aSession, uint32_t aIndex) {
|
|||
}
|
||||
mTargetRaySpace = new XRSpace(aSession->GetParentObject(), aSession, nativeOriginTargetRay);
|
||||
mGripSpace = new XRSpace(aSession->GetParentObject(), aSession, nativeOriginGrip);
|
||||
const uint32_t gamepadId = displayInfo.mDisplayID * kVRControllerMaxCount + aIndex;
|
||||
const uint32_t hashKey = GamepadManager::GetGamepadIndexWithServiceType(gamepadId, GamepadServiceType::VR);
|
||||
mGamepad = new Gamepad(mParent, NS_ConvertASCIItoUTF16(""), -1, hashKey, GamepadMappingType::Xr_standard,
|
||||
controllerState.hand, displayInfo.mDisplayID, controllerState.numButtons, controllerState.numAxes,
|
||||
controllerState.numHaptics, 0, 0);
|
||||
mIndex = aIndex;
|
||||
}
|
||||
|
||||
void XRInputSource::SetGamepadIsConnected(bool aConnected) {
|
||||
mGamepad->SetConnected(aConnected);
|
||||
}
|
||||
|
||||
void XRInputSource::Update(XRSession* aSession) {
|
||||
MOZ_ASSERT(aSession && mIndex >= 0 && mGamepad);
|
||||
|
||||
gfx::VRDisplayClient* displayClient = aSession->GetDisplayClient();
|
||||
if (!displayClient) {
|
||||
MOZ_ASSERT(displayClient);
|
||||
return;
|
||||
}
|
||||
const gfx::VRDisplayInfo& displayInfo = displayClient->GetDisplayInfo();
|
||||
const gfx::VRControllerState& controllerState = displayInfo.mControllerState[mIndex];
|
||||
MOZ_ASSERT(controllerState.controllerName[0] != '\0');
|
||||
|
||||
// Update button values.
|
||||
nsTArray<RefPtr<GamepadButton>> buttons;
|
||||
mGamepad->GetButtons(buttons);
|
||||
for (uint32_t i = 0; i < controllerState.numButtons; ++i) {
|
||||
const bool pressed = controllerState.buttonPressed & (1ULL << i);
|
||||
const bool touched = controllerState.buttonTouched & (1ULL << i);
|
||||
|
||||
if (buttons[i]->Pressed() != pressed || buttons[i]->Touched() != touched ||
|
||||
buttons[i]->Value() != controllerState.triggerValue[i]) {
|
||||
mGamepad->SetButton(i, pressed, touched, controllerState.triggerValue[i]);
|
||||
}
|
||||
}
|
||||
// Update axis values.
|
||||
nsTArray<double> axes;
|
||||
mGamepad->GetAxes(axes);
|
||||
for (uint32_t i = 0; i < controllerState.numAxes; ++i) {
|
||||
if (axes[i] != controllerState.axisValue[i]) {
|
||||
mGamepad->SetAxis(i, controllerState.axisValue[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t XRInputSource::GetIndex() {
|
||||
|
|
|
@ -49,7 +49,7 @@ class XRInputSource final : public nsWrapperCache {
|
|||
int32_t GetIndex();
|
||||
|
||||
protected:
|
||||
virtual ~XRInputSource() = default;
|
||||
virtual ~XRInputSource();
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
|
@ -60,6 +60,7 @@ class XRInputSource final : public nsWrapperCache {
|
|||
|
||||
RefPtr<XRSpace> mTargetRaySpace;
|
||||
RefPtr<XRSpace> mGripSpace;
|
||||
RefPtr<Gamepad> mGamepad;
|
||||
int32_t mIndex;
|
||||
};
|
||||
|
||||
|
|
|
@ -50,16 +50,26 @@ void XRInputSourceArray::Update(XRSession* aSession) {
|
|||
}
|
||||
}
|
||||
// Checking if it is added before.
|
||||
if (!found) {
|
||||
if (!found &&
|
||||
(controllerState.numButtons > 0 || controllerState.numAxes > 0)) {
|
||||
inputSource = new XRInputSource(mParent);
|
||||
inputSource->Setup(aSession, i);
|
||||
mInputSources.AppendElement(inputSource);
|
||||
}
|
||||
// If added, updating the current controller states.
|
||||
inputSource->Update(aSession);
|
||||
if (inputSource) {
|
||||
inputSource->Update(aSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XRInputSourceArray::Clear() {
|
||||
for (auto& input: mInputSources) {
|
||||
input->SetGamepadIsConnected(false);
|
||||
}
|
||||
mInputSources.Clear();
|
||||
}
|
||||
|
||||
uint32_t XRInputSourceArray::Length() { return mInputSources.Length(); }
|
||||
|
||||
XRInputSource* XRInputSourceArray::IndexedGetter(uint32_t aIndex,
|
||||
|
|
|
@ -396,6 +396,9 @@ void XRSession::Shutdown() {
|
|||
}
|
||||
|
||||
void XRSession::ExitPresentInternal() {
|
||||
if (mInputSources) {
|
||||
mInputSources->Clear();
|
||||
}
|
||||
if (mDisplayClient) {
|
||||
mDisplayClient->SessionEnded(this);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/dom/GamepadManager.h"
|
||||
#include "mozilla/dom/Gamepad.h"
|
||||
#include "mozilla/dom/XRSession.h"
|
||||
#include "mozilla/dom/XRInputSourceArray.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/WebXRBinding.h"
|
||||
|
@ -140,8 +141,19 @@ void VRDisplayClient::FireEvents() {
|
|||
StartFrame();
|
||||
}
|
||||
|
||||
// We only call FireGamepadEvents() in WebVR instead of WebXR
|
||||
FireGamepadEvents();
|
||||
// In WebXR spec, Gamepad instances returned by an XRInputSource's gamepad attribute
|
||||
// MUST NOT be included in the array returned by navigator.getGamepads().
|
||||
if (!StaticPrefs::dom_vr_webxr_enabled()) { // Checking mWebVR?
|
||||
FireGamepadEvents();
|
||||
} else {
|
||||
// Update controller states into XRInputSourceArray.
|
||||
for (auto& session : mSessions) {
|
||||
dom::XRInputSourceArray* inputs = session->InputSources();
|
||||
if (inputs) {
|
||||
inputs->Update(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VRDisplayClient::GamepadMappingForWebVR(
|
||||
|
|
Загрузка…
Ссылка в новой задаче