mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 17:55:50 +00:00
69790bc62e
The inclusions were removed with the following very crude script and the resulting breakage was fixed up by hand. The manual fixups did either revert the changes done by the script, replace a generic header with a more specific one or replace a header with a forward declaration. find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2) if [ -n "$interfaces" ]; then if [[ "$interfaces" == *$'\n'* ]]; then regexp="\(" for i in $interfaces; do regexp="$regexp$i\|"; done regexp="${regexp%%\\\|}\)" else regexp="$interfaces" fi interface=$(basename "$path") rg -l "#include.*${interface%%.idl}.h" . | while read path2; do hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" ) if [ $hits -eq 0 ]; then echo "Removing ${interface} from ${path2}" grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp mv -f "$path2".tmp "$path2" fi done fi done Differential Revision: https://phabricator.services.mozilla.com/D55443 --HG-- extra : moz-landing-system : lando
311 lines
12 KiB
C++
311 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 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/. */
|
|
|
|
#include <math.h>
|
|
|
|
#include "prlink.h"
|
|
#include "prenv.h"
|
|
|
|
#include "nsIGlobalObject.h"
|
|
#include "nsRefPtrHashtable.h"
|
|
#include "nsString.h"
|
|
#include "mozilla/dom/GamepadManager.h"
|
|
#include "mozilla/dom/Gamepad.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/Unused.h"
|
|
#include "nsServiceManagerUtils.h"
|
|
|
|
#ifdef XP_WIN
|
|
# include "../layers/d3d11/CompositorD3D11.h"
|
|
#endif
|
|
|
|
#include "VRDisplayClient.h"
|
|
#include "VRDisplayPresentation.h"
|
|
#include "VRManagerChild.h"
|
|
#include "VRLayerChild.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::gfx;
|
|
|
|
VRDisplayClient::VRDisplayClient(const VRDisplayInfo& aDisplayInfo)
|
|
: mDisplayInfo(aDisplayInfo),
|
|
bLastEventWasMounted(false),
|
|
bLastEventWasPresenting(false),
|
|
mPresentationCount(0),
|
|
mLastEventFrameId(0),
|
|
mLastPresentingGeneration(0),
|
|
mLastEventControllerState{} {
|
|
MOZ_COUNT_CTOR(VRDisplayClient);
|
|
}
|
|
|
|
VRDisplayClient::~VRDisplayClient() { MOZ_COUNT_DTOR(VRDisplayClient); }
|
|
|
|
void VRDisplayClient::UpdateDisplayInfo(const VRDisplayInfo& aDisplayInfo) {
|
|
mDisplayInfo = aDisplayInfo;
|
|
FireEvents();
|
|
}
|
|
|
|
already_AddRefed<VRDisplayPresentation> VRDisplayClient::BeginPresentation(
|
|
const nsTArray<mozilla::dom::VRLayer>& aLayers, uint32_t aGroup) {
|
|
++mPresentationCount;
|
|
RefPtr<VRDisplayPresentation> presentation =
|
|
new VRDisplayPresentation(this, aLayers, aGroup);
|
|
return presentation.forget();
|
|
}
|
|
|
|
void VRDisplayClient::PresentationDestroyed() { --mPresentationCount; }
|
|
|
|
void VRDisplayClient::SetGroupMask(uint32_t aGroupMask) {
|
|
VRManagerChild* vm = VRManagerChild::Get();
|
|
vm->SendSetGroupMask(mDisplayInfo.mDisplayID, aGroupMask);
|
|
}
|
|
|
|
bool VRDisplayClient::IsPresentationGenerationCurrent() const {
|
|
if (mLastPresentingGeneration !=
|
|
mDisplayInfo.mDisplayState.presentingGeneration) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void VRDisplayClient::MakePresentationGenerationCurrent() {
|
|
mLastPresentingGeneration = mDisplayInfo.mDisplayState.presentingGeneration;
|
|
}
|
|
|
|
void VRDisplayClient::FireEvents() {
|
|
RefPtr<VRManagerChild> vm = VRManagerChild::Get();
|
|
// Only fire these events for non-chrome VR sessions
|
|
bool isPresenting = (mDisplayInfo.mPresentingGroups & kVRGroupContent) != 0;
|
|
|
|
// Check if we need to trigger onVRDisplayPresentChange event
|
|
if (bLastEventWasPresenting != isPresenting) {
|
|
bLastEventWasPresenting = isPresenting;
|
|
vm->FireDOMVRDisplayPresentChangeEvent(mDisplayInfo.mDisplayID);
|
|
}
|
|
|
|
// Check if we need to trigger onvrdisplayactivate event
|
|
if (!bLastEventWasMounted && mDisplayInfo.mDisplayState.isMounted) {
|
|
bLastEventWasMounted = true;
|
|
if (StaticPrefs::dom_vr_autoactivate_enabled()) {
|
|
vm->FireDOMVRDisplayMountedEvent(mDisplayInfo.mDisplayID);
|
|
}
|
|
}
|
|
|
|
// Check if we need to trigger onvrdisplaydeactivate event
|
|
if (bLastEventWasMounted && !mDisplayInfo.mDisplayState.isMounted) {
|
|
bLastEventWasMounted = false;
|
|
if (StaticPrefs::dom_vr_autoactivate_enabled()) {
|
|
vm->FireDOMVRDisplayUnmountedEvent(mDisplayInfo.mDisplayID);
|
|
}
|
|
}
|
|
|
|
if (mLastPresentingGeneration !=
|
|
mDisplayInfo.mDisplayState.presentingGeneration) {
|
|
mLastPresentingGeneration = mDisplayInfo.mDisplayState.presentingGeneration;
|
|
vm->NotifyPresentationGenerationChanged(mDisplayInfo.mDisplayID);
|
|
}
|
|
|
|
// Check if we need to trigger VRDisplay.requestAnimationFrame
|
|
if (mLastEventFrameId != mDisplayInfo.mFrameId) {
|
|
mLastEventFrameId = mDisplayInfo.mFrameId;
|
|
vm->RunFrameRequestCallbacks();
|
|
}
|
|
|
|
FireGamepadEvents();
|
|
}
|
|
|
|
void VRDisplayClient::FireGamepadEvents() {
|
|
RefPtr<dom::GamepadManager> gamepadManager(dom::GamepadManager::GetService());
|
|
if (!gamepadManager) {
|
|
return;
|
|
}
|
|
for (int stateIndex = 0; stateIndex < kVRControllerMaxCount; stateIndex++) {
|
|
const VRControllerState& state = mDisplayInfo.mControllerState[stateIndex];
|
|
const VRControllerState& lastState = mLastEventControllerState[stateIndex];
|
|
uint32_t gamepadId =
|
|
mDisplayInfo.mDisplayID * kVRControllerMaxCount + stateIndex;
|
|
bool bIsNew = false;
|
|
|
|
// Send events to notify that controllers are removed
|
|
if (state.controllerName[0] == '\0') {
|
|
// Controller is not present
|
|
if (lastState.controllerName[0] != '\0') {
|
|
// Controller has been removed
|
|
dom::GamepadRemoved info;
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
}
|
|
// Do not process any further events for removed controllers
|
|
continue;
|
|
}
|
|
|
|
// Send events to notify that new controllers are added
|
|
RefPtr<dom::Gamepad> existing =
|
|
gamepadManager->GetGamepad(gamepadId, dom::GamepadServiceType::VR);
|
|
// ControllerState in OpenVR action-based API gets delay to query btn and
|
|
// axis count. So, we need to check if they are more than zero.
|
|
if ((lastState.controllerName[0] == '\0' || !existing) &&
|
|
(state.numButtons > 0 || state.numAxes > 0)) {
|
|
dom::GamepadAdded info(NS_ConvertUTF8toUTF16(state.controllerName),
|
|
dom::GamepadMappingType::_empty, state.hand,
|
|
mDisplayInfo.mDisplayID, state.numButtons,
|
|
state.numAxes, state.numHaptics, 0, 0);
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
bIsNew = true;
|
|
}
|
|
|
|
// Send events for handedness changes
|
|
if (state.hand != lastState.hand) {
|
|
dom::GamepadHandInformation info(state.hand);
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
}
|
|
|
|
// Send events for axis value changes
|
|
for (uint32_t axisIndex = 0; axisIndex < state.numAxes; axisIndex++) {
|
|
if (state.axisValue[axisIndex] != lastState.axisValue[axisIndex]) {
|
|
dom::GamepadAxisInformation info(axisIndex, state.axisValue[axisIndex]);
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
}
|
|
}
|
|
|
|
// Send events for trigger, touch, and button value changes
|
|
if (!bIsNew) {
|
|
// When a new controller is added, we do not emit button events for
|
|
// the initial state of the inputs.
|
|
for (uint32_t buttonIndex = 0; buttonIndex < state.numButtons;
|
|
buttonIndex++) {
|
|
bool bPressed = (state.buttonPressed & (1ULL << buttonIndex)) != 0;
|
|
bool bTouched = (state.buttonTouched & (1ULL << buttonIndex)) != 0;
|
|
bool bLastPressed =
|
|
(lastState.buttonPressed & (1ULL << buttonIndex)) != 0;
|
|
bool bLastTouched =
|
|
(lastState.buttonTouched & (1ULL << buttonIndex)) != 0;
|
|
|
|
if (state.triggerValue[buttonIndex] !=
|
|
lastState.triggerValue[buttonIndex] ||
|
|
bPressed != bLastPressed || bTouched != bLastTouched) {
|
|
dom::GamepadButtonInformation info(
|
|
buttonIndex, state.triggerValue[buttonIndex], bPressed, bTouched);
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send events for pose changes
|
|
// Note that VRPose is asserted to be a POD type so memcmp is safe
|
|
if (state.flags != lastState.flags ||
|
|
state.isPositionValid != lastState.isPositionValid ||
|
|
state.isOrientationValid != lastState.isOrientationValid ||
|
|
memcmp(&state.pose, &lastState.pose, sizeof(VRPose)) != 0) {
|
|
// Convert pose to GamepadPoseState
|
|
dom::GamepadPoseState poseState;
|
|
poseState.Clear();
|
|
poseState.flags = state.flags;
|
|
|
|
// Orientation values
|
|
poseState.isOrientationValid = state.isOrientationValid;
|
|
poseState.orientation[0] = state.pose.orientation[0];
|
|
poseState.orientation[1] = state.pose.orientation[1];
|
|
poseState.orientation[2] = state.pose.orientation[2];
|
|
poseState.orientation[3] = state.pose.orientation[3];
|
|
poseState.angularVelocity[0] = state.pose.angularVelocity[0];
|
|
poseState.angularVelocity[1] = state.pose.angularVelocity[1];
|
|
poseState.angularVelocity[2] = state.pose.angularVelocity[2];
|
|
poseState.angularAcceleration[0] = state.pose.angularAcceleration[0];
|
|
poseState.angularAcceleration[1] = state.pose.angularAcceleration[1];
|
|
poseState.angularAcceleration[2] = state.pose.angularAcceleration[2];
|
|
|
|
// Position values
|
|
poseState.isPositionValid = state.isPositionValid;
|
|
poseState.position[0] = state.pose.position[0];
|
|
poseState.position[1] = state.pose.position[1];
|
|
poseState.position[2] = state.pose.position[2];
|
|
poseState.linearVelocity[0] = state.pose.linearVelocity[0];
|
|
poseState.linearVelocity[1] = state.pose.linearVelocity[1];
|
|
poseState.linearVelocity[2] = state.pose.linearVelocity[2];
|
|
poseState.linearAcceleration[0] = state.pose.linearAcceleration[0];
|
|
poseState.linearAcceleration[1] = state.pose.linearAcceleration[1];
|
|
poseState.linearAcceleration[2] = state.pose.linearAcceleration[2];
|
|
|
|
// Send the event
|
|
dom::GamepadPoseInformation info(poseState);
|
|
dom::GamepadChangeEventBody body(info);
|
|
dom::GamepadChangeEvent event(gamepadId, dom::GamepadServiceType::VR,
|
|
body);
|
|
gamepadManager->Update(event);
|
|
}
|
|
}
|
|
|
|
// Note that VRControllerState is asserted to be a POD type and memcpy is
|
|
// safe.
|
|
memcpy(mLastEventControllerState, mDisplayInfo.mControllerState,
|
|
sizeof(VRControllerState) * kVRControllerMaxCount);
|
|
}
|
|
|
|
const VRHMDSensorState& VRDisplayClient::GetSensorState() const {
|
|
return mDisplayInfo.GetSensorState();
|
|
}
|
|
|
|
bool VRDisplayClient::GetIsConnected() const {
|
|
return mDisplayInfo.GetIsConnected();
|
|
}
|
|
|
|
bool VRDisplayClient::IsPresenting() {
|
|
return mDisplayInfo.mPresentingGroups != 0;
|
|
}
|
|
|
|
void VRDisplayClient::NotifyDisconnected() {
|
|
mDisplayInfo.mDisplayState.isConnected = false;
|
|
}
|
|
|
|
void VRDisplayClient::UpdateSubmitFrameResult(
|
|
const VRSubmitFrameResultInfo& aResult) {
|
|
mSubmitFrameResult = aResult;
|
|
}
|
|
|
|
void VRDisplayClient::GetSubmitFrameResult(VRSubmitFrameResultInfo& aResult) {
|
|
aResult = mSubmitFrameResult;
|
|
}
|
|
|
|
void VRDisplayClient::StartVRNavigation() {
|
|
/**
|
|
* A VR-to-VR site navigation has started, notify VRManager
|
|
* so we don't drop out of VR during the transition
|
|
*/
|
|
VRManagerChild* vm = VRManagerChild::Get();
|
|
vm->SendStartVRNavigation(mDisplayInfo.mDisplayID);
|
|
}
|
|
|
|
void VRDisplayClient::StopVRNavigation(const TimeDuration& aTimeout) {
|
|
/**
|
|
* A VR-to-VR site navigation has ended and the new site
|
|
* has received a vrdisplayactivate event.
|
|
* Don't actually consider the navigation transition over
|
|
* until aTimeout has elapsed.
|
|
* This may be called multiple times, in which case the timeout
|
|
* should be reset to aTimeout.
|
|
* When aTimeout is TimeDuration(0), we should consider the
|
|
* transition immediately ended.
|
|
*/
|
|
VRManagerChild* vm = VRManagerChild::Get();
|
|
vm->SendStopVRNavigation(mDisplayInfo.mDisplayID, aTimeout);
|
|
}
|