зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1476797 - Indicate VR session activity indepenently of layer presence r=daoshengmu
MozReview-Commit-ID: 4F0vclSj5gB Differential Revision: https://phabricator.services.mozilla.com/D2451 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6da4b51b7b
Коммит
17fa5240f0
|
@ -2063,6 +2063,7 @@ nsGlobalWindowInner::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
|||
// forwards, navigating backwards, and on page reload.
|
||||
for (const auto& display : mVRDisplays) {
|
||||
if (display->IsPresenting()) {
|
||||
display->StartVRNavigation();
|
||||
// Save this VR display ID to trigger vrdisplayactivate event
|
||||
// after the next load event.
|
||||
nsGlobalWindowOuter* outer = GetOuterWindowInternal();
|
||||
|
|
|
@ -498,11 +498,24 @@ VRDisplay::ResetPose()
|
|||
mClient->ZeroSensor();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::StartVRNavigation()
|
||||
{
|
||||
mClient->StartVRNavigation();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplay::StartHandlingVRNavigationEvent()
|
||||
{
|
||||
mHandlingVRNavigationEventStart = TimeStamp::Now();
|
||||
++mVRNavigationEventDepth;
|
||||
TimeDuration timeout = TimeDuration::FromMilliseconds(gfxPrefs::VRNavigationTimeout());
|
||||
// A 0 or negative TimeDuration indicates that content may take
|
||||
// as long as it wishes to respond to the event, as long as
|
||||
// it happens before the event exits.
|
||||
if (timeout.ToMilliseconds() > 0) {
|
||||
mClient->StopVRNavigation(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -510,6 +523,9 @@ VRDisplay::StopHandlingVRNavigationEvent()
|
|||
{
|
||||
MOZ_ASSERT(mVRNavigationEventDepth > 0);
|
||||
--mVRNavigationEventDepth;
|
||||
if (mVRNavigationEventDepth == 0) {
|
||||
mClient->StopVRNavigation(TimeDuration::FromMilliseconds(0));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -522,7 +538,7 @@ VRDisplay::IsHandlingVRNavigationEvent()
|
|||
return false;
|
||||
}
|
||||
TimeDuration timeout = TimeDuration::FromMilliseconds(gfxPrefs::VRNavigationTimeout());
|
||||
return timeout <= TimeDuration(0) ||
|
||||
return timeout.ToMilliseconds() <= 0 ||
|
||||
(TimeStamp::Now() - mHandlingVRNavigationEventStart) <= timeout;
|
||||
}
|
||||
|
||||
|
|
|
@ -363,6 +363,7 @@ public:
|
|||
int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback,
|
||||
mozilla::ErrorResult& aError);
|
||||
void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError);
|
||||
void StartVRNavigation();
|
||||
void StartHandlingVRNavigationEvent();
|
||||
void StopHandlingVRNavigationEvent();
|
||||
bool IsHandlingVRNavigationEvent();
|
||||
|
|
|
@ -297,3 +297,31 @@ 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);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
bool IsPresentationGenerationCurrent() const;
|
||||
void MakePresentationGenerationCurrent();
|
||||
|
||||
void StartVRNavigation();
|
||||
void StopVRNavigation(const TimeDuration& aTimeout);
|
||||
|
||||
protected:
|
||||
virtual ~VRDisplayClient();
|
||||
|
||||
|
|
|
@ -345,6 +345,18 @@ VRDisplayHost::CheckClearDisplayInfoDirty()
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayHost::StartVRNavigation()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayHost::StopVRNavigation(const TimeDuration& aTimeout)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VRControllerHost::VRControllerHost(VRDeviceType aType, dom::GamepadHand aHand,
|
||||
uint32_t aDisplayID)
|
||||
: mControllerInfo{}
|
||||
|
@ -422,3 +434,4 @@ VRControllerHost::GetVibrateIndex()
|
|||
{
|
||||
return mVibrateIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
virtual void ZeroSensor() = 0;
|
||||
virtual void StartPresentation() = 0;
|
||||
virtual void StopPresentation() = 0;
|
||||
virtual void StartVRNavigation();
|
||||
virtual void StopVRNavigation(const TimeDuration& aTimeout);
|
||||
void NotifyVSync();
|
||||
|
||||
void StartFrame();
|
||||
|
|
|
@ -599,5 +599,23 @@ VRManager::DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameRes
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::StartVRNavigation(const uint32_t& aDisplayID)
|
||||
{
|
||||
RefPtr<VRDisplayHost> display = GetDisplay(aDisplayID);
|
||||
if (display) {
|
||||
display->StartVRNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRManager::StopVRNavigation(const uint32_t& aDisplayID, const TimeDuration& aTimeout)
|
||||
{
|
||||
RefPtr<VRDisplayHost> display = GetDisplay(aDisplayID);
|
||||
if (display) {
|
||||
display->StopVRNavigation(aTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
void StopVibrateHaptic(uint32_t aControllerIdx);
|
||||
void NotifyVibrateHapticCompleted(const VRManagerPromise& aPromise);
|
||||
void DispatchSubmitFrameResult(uint32_t aDisplayID, const VRSubmitFrameResultInfo& aResult);
|
||||
void StartVRNavigation(const uint32_t& aDisplayID);
|
||||
void StopVRNavigation(const uint32_t& aDisplayID, const TimeDuration& aTimeout);
|
||||
|
||||
protected:
|
||||
VRManager();
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace dom {
|
|||
#endif // MOZILLA_INTERNAL_API
|
||||
namespace gfx {
|
||||
|
||||
static const int32_t kVRExternalVersion = 1;
|
||||
static const int32_t kVRExternalVersion = 2;
|
||||
|
||||
// We assign VR presentations to groups with a bitmask.
|
||||
// Currently, we will only display either content or chrome.
|
||||
|
@ -359,6 +359,8 @@ struct VRBrowserState
|
|||
#if defined(__ANDROID__)
|
||||
bool shutdown;
|
||||
#endif // defined(__ANDROID__)
|
||||
bool presentationActive;
|
||||
bool navigationTransitionActive;
|
||||
VRLayerState layerState[kVRLayerMaxCount];
|
||||
};
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ int VRDisplayExternal::sPushIndex = 0;
|
|||
|
||||
VRDisplayExternal::VRDisplayExternal(const VRDisplayState& aDisplayState)
|
||||
: VRDisplayHost(VRDeviceType::External)
|
||||
, mIsPresenting(false)
|
||||
, mBrowserState{}
|
||||
, mLastSensorState{}
|
||||
{
|
||||
MOZ_COUNT_CTOR_INHERITED(VRDisplayExternal, VRDisplayHost);
|
||||
|
@ -86,10 +86,14 @@ VRDisplayExternal::ZeroSensor()
|
|||
void
|
||||
VRDisplayExternal::Refresh()
|
||||
{
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
|
||||
manager->PullState(&mDisplayInfo.mDisplayState, &mLastSensorState, mDisplayInfo.mControllerState);
|
||||
if (!mVRNavigationTransitionEnd.IsNull() &&
|
||||
TimeStamp::Now() > mVRNavigationTransitionEnd) {
|
||||
mBrowserState.navigationTransitionActive = false;
|
||||
}
|
||||
|
||||
PullState();
|
||||
PushState();
|
||||
}
|
||||
|
||||
VRHMDSensorState
|
||||
|
@ -101,21 +105,17 @@ VRDisplayExternal::GetSensorState()
|
|||
void
|
||||
VRDisplayExternal::StartPresentation()
|
||||
{
|
||||
if (mIsPresenting) {
|
||||
if (mBrowserState.presentationActive) {
|
||||
return;
|
||||
}
|
||||
sPushIndex = 0;
|
||||
mIsPresenting = true;
|
||||
mTelemetry.Clear();
|
||||
mTelemetry.mPresentationStart = TimeStamp::Now();
|
||||
|
||||
// Indicate that we are ready to start immersive mode
|
||||
VRBrowserState state;
|
||||
memset(&state, 0, sizeof(VRBrowserState));
|
||||
state.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
manager->PushState(&state);
|
||||
mBrowserState.presentationActive = true;
|
||||
mBrowserState.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
|
||||
PushState();
|
||||
|
||||
// TODO - Implement telemetry:
|
||||
|
||||
|
@ -125,18 +125,16 @@ VRDisplayExternal::StartPresentation()
|
|||
void
|
||||
VRDisplayExternal::StopPresentation()
|
||||
{
|
||||
if (!mIsPresenting) {
|
||||
if (!mBrowserState.presentationActive) {
|
||||
return;
|
||||
}
|
||||
mIsPresenting = false;
|
||||
sPushIndex = 0;
|
||||
|
||||
// Indicate that we have stopped immersive mode
|
||||
VRBrowserState state;
|
||||
memset(&state, 0, sizeof(VRBrowserState));
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
manager->PushState(&state, true);
|
||||
mBrowserState.presentationActive = false;
|
||||
memset(mBrowserState.layerState, 0, sizeof(VRLayerState) * mozilla::ArrayLength(mBrowserState.layerState));
|
||||
|
||||
PushState(true);
|
||||
|
||||
// TODO - Implement telemetry:
|
||||
|
||||
|
@ -154,6 +152,25 @@ VRDisplayExternal::StopPresentation()
|
|||
*/
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayExternal::StartVRNavigation()
|
||||
{
|
||||
mBrowserState.navigationTransitionActive = true;
|
||||
mVRNavigationTransitionEnd = TimeStamp();
|
||||
PushState();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayExternal::StopVRNavigation(const TimeDuration& aTimeout)
|
||||
{
|
||||
if (aTimeout.ToMilliseconds() <= 0) {
|
||||
mBrowserState.navigationTransitionActive = false;
|
||||
mVRNavigationTransitionEnd = TimeStamp();
|
||||
PushState();
|
||||
}
|
||||
mVRNavigationTransitionEnd = TimeStamp::Now() + aTimeout;
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplayExternal::PopulateLayerTexture(const layers::SurfaceDescriptor& aTexture,
|
||||
VRLayerTextureType* aTextureType,
|
||||
|
@ -207,10 +224,8 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
|
|||
const gfx::Rect& aLeftEyeRect,
|
||||
const gfx::Rect& aRightEyeRect)
|
||||
{
|
||||
VRBrowserState state;
|
||||
memset(&state, 0, sizeof(VRBrowserState));
|
||||
state.layerState[0].type = VRLayerType::LayerType_Stereo_Immersive;
|
||||
VRLayer_Stereo_Immersive& layer = state.layerState[0].layer_stereo_immersive;
|
||||
MOZ_ASSERT(mBrowserState.layerState[0].type == VRLayerType::LayerType_Stereo_Immersive);
|
||||
VRLayer_Stereo_Immersive& layer = mBrowserState.layerState[0].layer_stereo_immersive;
|
||||
if (!PopulateLayerTexture(aTexture, &layer.mTextureType, &layer.mTextureHandle)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -226,26 +241,24 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
|
|||
layer.mRightEyeRect.width = aRightEyeRect.width;
|
||||
layer.mRightEyeRect.height = aRightEyeRect.height;
|
||||
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
manager->PushState(&state, true);
|
||||
PushState(true);
|
||||
sPushIndex++;
|
||||
|
||||
VRDisplayState displayState;
|
||||
memset(&displayState, 0, sizeof(VRDisplayState));
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
manager->PullState(&displayState, &mLastSensorState, mDisplayInfo.mControllerState, [&]() {
|
||||
return (displayState.mLastSubmittedFrameId >= aFrameId) || displayState.mSuppressFrames || !displayState.mIsConnected;
|
||||
PullState([&]() {
|
||||
return (mDisplayInfo.mDisplayState.mLastSubmittedFrameId >= aFrameId) ||
|
||||
mDisplayInfo.mDisplayState.mSuppressFrames ||
|
||||
!mDisplayInfo.mDisplayState.mIsConnected;
|
||||
});
|
||||
|
||||
if (displayState.mSuppressFrames || !displayState.mIsConnected) {
|
||||
if (mDisplayInfo.mDisplayState.mSuppressFrames || !mDisplayInfo.mDisplayState.mIsConnected) {
|
||||
// External implementation wants to supress frames, service has shut down or hardware has been disconnected.
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
while (displayState.mLastSubmittedFrameId < aFrameId) {
|
||||
if (manager->PullState(&displayState, &mLastSensorState, mDisplayInfo.mControllerState)) {
|
||||
if (displayState.mSuppressFrames || !displayState.mIsConnected) {
|
||||
while (mDisplayInfo.mDisplayState.mLastSubmittedFrameId < aFrameId) {
|
||||
if (PullState()) {
|
||||
if (mDisplayInfo.mDisplayState.mSuppressFrames || !mDisplayInfo.mDisplayState.mIsConnected) {
|
||||
// External implementation wants to supress frames, service has shut down or hardware has been disconnected.
|
||||
return false;
|
||||
}
|
||||
|
@ -258,9 +271,40 @@ VRDisplayExternal::SubmitFrame(const layers::SurfaceDescriptor& aTexture,
|
|||
}
|
||||
#endif // defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
return displayState.mLastSubmittedFrameSuccessful;
|
||||
return mDisplayInfo.mDisplayState.mLastSubmittedFrameSuccessful;
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayExternal::PushState(bool aNotifyCond)
|
||||
{
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
manager->PushState(&mBrowserState, aNotifyCond);
|
||||
}
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
bool
|
||||
VRDisplayExternal::PullState(const std::function<bool()>& aWaitCondition)
|
||||
{
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
return manager->PullState(&mDisplayInfo.mDisplayState,
|
||||
&mLastSensorState,
|
||||
mDisplayInfo.mControllerState,
|
||||
aWaitCondition);
|
||||
}
|
||||
#else
|
||||
bool
|
||||
VRDisplayExternal::PullState()
|
||||
{
|
||||
VRManager *vm = VRManager::Get();
|
||||
VRSystemManagerExternal* manager = vm->GetExternalManager();
|
||||
return manager->PullState(&mDisplayInfo.mDisplayState,
|
||||
&mLastSensorState,
|
||||
mDisplayInfo.mControllerState);
|
||||
}
|
||||
#endif
|
||||
|
||||
VRSystemManagerExternal::VRSystemManagerExternal(VRExternalShmem* aAPIShmem /* = nullptr*/)
|
||||
: mExternalShmem(aAPIShmem)
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
|
|
|
@ -37,6 +37,8 @@ protected:
|
|||
VRHMDSensorState GetSensorState() override;
|
||||
void StartPresentation() override;
|
||||
void StopPresentation() override;
|
||||
void StartVRNavigation() override;
|
||||
void StopVRNavigation(const TimeDuration& aTimeout) override;
|
||||
|
||||
bool SubmitFrame(const layers::SurfaceDescriptor& aTexture,
|
||||
uint64_t aFrameId,
|
||||
|
@ -55,9 +57,16 @@ private:
|
|||
bool PopulateLayerTexture(const layers::SurfaceDescriptor& aTexture,
|
||||
VRLayerTextureType* aTextureType,
|
||||
VRLayerTextureHandle* aTextureHandle);
|
||||
void PushState(bool aNotifyCond = false);
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
bool PullState(const std::function<bool()>& aWaitCondition = nullptr);
|
||||
#else
|
||||
bool PullState();
|
||||
#endif
|
||||
|
||||
VRTelemetry mTelemetry;
|
||||
bool mIsPresenting;
|
||||
TimeStamp mVRNavigationTransitionEnd;
|
||||
VRBrowserState mBrowserState;
|
||||
VRHMDSensorState mLastSensorState;
|
||||
};
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ parent:
|
|||
async NewAxisMoveEventToMockController(uint32_t aDeviceID, long aAxis,
|
||||
double aValue);
|
||||
async NewPoseMoveToMockController(uint32_t aDeviceID, GamepadPoseState aPose);
|
||||
async StartVRNavigation(uint32_t aDeviceID);
|
||||
async StopVRNavigation(uint32_t aDeviceID, TimeDuration aDuration);
|
||||
|
||||
child:
|
||||
// Notify children of updated VR display enumeration and details. This will
|
||||
|
|
|
@ -434,5 +434,21 @@ VRManagerParent::SendReplyGamepadVibrateHaptic(const uint32_t& aPromiseID)
|
|||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
VRManagerParent::RecvStartVRNavigation(const uint32_t& aDeviceID)
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->StartVRNavigation(aDeviceID);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
VRManagerParent::RecvStopVRNavigation(const uint32_t& aDeviceID, const TimeDuration& aTimeout)
|
||||
{
|
||||
VRManager* vm = VRManager::Get();
|
||||
vm->StopVRNavigation(aDeviceID, aTimeout);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -73,7 +73,8 @@ protected:
|
|||
virtual mozilla::ipc::IPCResult RecvNewAxisMoveEventToMockController(const uint32_t& aDeviceID, const long& aAxis,
|
||||
const double& aValue) override;
|
||||
virtual mozilla::ipc::IPCResult RecvNewPoseMoveToMockController(const uint32_t& aDeviceID, const GamepadPoseState& pose) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvStartVRNavigation(const uint32_t& aDeviceID) override;
|
||||
virtual mozilla::ipc::IPCResult RecvStopVRNavigation(const uint32_t& aDeviceID, const TimeDuration& aTimeout) override;
|
||||
private:
|
||||
void RegisterWithManager();
|
||||
void UnregisterFromManager();
|
||||
|
|
Загрузка…
Ссылка в новой задаче