diff options
Diffstat (limited to 'gfx/vr/gfxVR.h')
-rw-r--r-- | gfx/vr/gfxVR.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/gfx/vr/gfxVR.h b/gfx/vr/gfxVR.h new file mode 100644 index 0000000000..d4d772b6a2 --- /dev/null +++ b/gfx/vr/gfxVR.h @@ -0,0 +1,162 @@ +/* -*- 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/. */ + +#ifndef GFX_VR_H +#define GFX_VR_H + +#include "moz_external_vr.h" +#include "nsTArray.h" +#include "nsString.h" +#include "nsCOMPtr.h" +#include "mozilla/RefPtr.h" +#include "mozilla/gfx/2D.h" +#include "mozilla/Atomics.h" +#include "mozilla/EnumeratedArray.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/TypedEnumBits.h" +#include <type_traits> + +namespace mozilla { +namespace layers { +class PTextureParent; +} +namespace dom { +enum class GamepadMappingType : uint8_t; +enum class GamepadHand : uint8_t; +} // namespace dom +namespace gfx { +enum class VRAPIMode : uint8_t { WebXR, WebVR, NumVRAPIModes }; + +class VRLayerParent; +class VRDisplayHost; +class VRManagerPromise; + +// The maximum number of frames of latency that we would expect before we +// should give up applying pose prediction. +// If latency is greater than one second, then the experience is not likely +// to be corrected by pose prediction. Setting this value too +// high may result in unnecessary memory allocation. +// As the current fastest refresh rate is 90hz, 100 is selected as a +// conservative value. +static const int kVRMaxLatencyFrames = 100; + +struct VRDisplayInfo { + uint32_t mDisplayID; + uint32_t mPresentingGroups; + uint32_t mGroupMask; + uint64_t mFrameId; + VRDisplayState mDisplayState; + VRControllerState mControllerState[kVRControllerMaxCount]; + + VRHMDSensorState mLastSensorState[kVRMaxLatencyFrames]; + void Clear() { memset(this, 0, sizeof(VRDisplayInfo)); } + const VRHMDSensorState& GetSensorState() const { + return mLastSensorState[mFrameId % kVRMaxLatencyFrames]; + } + + uint32_t GetDisplayID() const { return mDisplayID; } + const char* GetDisplayName() const { return mDisplayState.displayName; } + VRDisplayCapabilityFlags GetCapabilities() const { + return mDisplayState.capabilityFlags; + } + + const IntSize SuggestedEyeResolution() const; + const Point3D GetEyeTranslation(uint32_t whichEye) const; + const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const { + return mDisplayState.eyeFOV[whichEye]; + } + bool GetIsConnected() const { return mDisplayState.isConnected; } + bool GetIsMounted() const { return mDisplayState.isMounted; } + uint32_t GetPresentingGroups() const { return mPresentingGroups; } + uint32_t GetGroupMask() const { return mGroupMask; } + const Size GetStageSize() const; + const Matrix4x4 GetSittingToStandingTransform() const; + uint64_t GetFrameId() const { return mFrameId; } + + bool operator==(const VRDisplayInfo& other) const { + for (size_t i = 0; i < kVRMaxLatencyFrames; i++) { + if (mLastSensorState[i] != other.mLastSensorState[i]) { + return false; + } + } + // Note that mDisplayState and mControllerState are asserted to be POD + // types, so memcmp is safe + return mDisplayID == other.mDisplayID && + memcmp(&mDisplayState, &other.mDisplayState, + sizeof(VRDisplayState)) == 0 && + memcmp(mControllerState, other.mControllerState, + sizeof(VRControllerState) * kVRControllerMaxCount) == 0 && + mPresentingGroups == other.mPresentingGroups && + mGroupMask == other.mGroupMask && mFrameId == other.mFrameId; + } + + bool operator!=(const VRDisplayInfo& other) const { + return !(*this == other); + } +}; + +static_assert(std::is_pod<VRDisplayInfo>::value, + "VRDisplayInfo must be a POD type."); + +struct VRSubmitFrameResultInfo { + VRSubmitFrameResultInfo() + : mFormat(SurfaceFormat::UNKNOWN), mFrameNum(0), mWidth(0), mHeight(0) {} + + nsCString mBase64Image; + SurfaceFormat mFormat; + uint64_t mFrameNum; + uint32_t mWidth; + uint32_t mHeight; +}; + +struct VRControllerInfo { + uint32_t GetControllerID() const { return mControllerID; } + const char* GetControllerName() const { + return mControllerState.controllerName; + } + dom::GamepadMappingType GetMappingType() const { return mMappingType; } + uint32_t GetDisplayID() const { return mDisplayID; } + dom::GamepadHand GetHand() const { return mControllerState.hand; } + uint32_t GetNumButtons() const { return mControllerState.numButtons; } + uint32_t GetNumAxes() const { return mControllerState.numAxes; } + uint32_t GetNumHaptics() const { return mControllerState.numHaptics; } + + uint32_t mControllerID; + dom::GamepadMappingType mMappingType; + uint32_t mDisplayID; + VRControllerState mControllerState; + bool operator==(const VRControllerInfo& other) const { + // Note that mControllerState is asserted to be a POD type, so memcmp is + // safe + return mControllerID == other.mControllerID && + memcmp(&mControllerState, &other.mControllerState, + sizeof(VRControllerState)) == 0 && + mMappingType == other.mMappingType && mDisplayID == other.mDisplayID; + } + + bool operator!=(const VRControllerInfo& other) const { + return !(*this == other); + } +}; + +struct VRTelemetry { + VRTelemetry() : mLastDroppedFrameCount(-1) {} + + void Clear() { + mPresentationStart = TimeStamp(); + mLastDroppedFrameCount = -1; + } + + bool IsLastDroppedFrameValid() { return (mLastDroppedFrameCount != -1); } + + TimeStamp mPresentationStart; + int32_t mLastDroppedFrameCount; +}; + +} // namespace gfx +} // namespace mozilla + +#endif /* GFX_VR_H */ |