Improve readability of vsync and settings update code

This commit is contained in:
Kung-vr
2019-01-28 23:11:20 +09:00
parent d529b21f3e
commit a39196af01
10 changed files with 324 additions and 215 deletions
+225 -215
View File
@@ -390,7 +390,7 @@ void OverlayController::SetWidget( QQuickItem* quickItem,
this, this,
SLOT( OnTimeoutPumpEvents() ) ); SLOT( OnTimeoutPumpEvents() ) );
// was m_pPumpEventsTimer->setInterval( 20 ); // Every 1ms we check if the current frame has advanced (for vysnc)
m_pPumpEventsTimer->setInterval( 1 ); m_pPumpEventsTimer->setInterval( 1 );
m_pPumpEventsTimer->start(); m_pPumpEventsTimer->start();
@@ -523,240 +523,250 @@ void OverlayController::processInputBindings()
m_actions.optionalOverrideRightHandPlayspaceRotate() ); m_actions.optionalOverrideRightHandPlayspaceRotate() );
} }
// vsync implementation:
// (this function triggers every 1ms)
void OverlayController::OnTimeoutPumpEvents() void OverlayController::OnTimeoutPumpEvents()
{ {
// get the current frame number from the VRSystem frame counter
vr::VRSystem()->GetTimeSinceLastVsync( nullptr, &m_currentFrame ); vr::VRSystem()->GetTimeSinceLastVsync( nullptr, &m_currentFrame );
// Check if we are in the next frame yet
if ( m_currentFrame > m_lastFrame ) if ( m_currentFrame > m_lastFrame )
{ {
if ( !vr::VRSystem() ) // If the frame has advanced since last check, it's time for our main
// event loop. (this function should trigger about every 11ms assuming
// 90fps compositor)
mainEventLoop();
// wait for the next frame after executing our main event loop once.
m_lastFrame = m_currentFrame;
}
}
void OverlayController::mainEventLoop()
{
if ( !vr::VRSystem() )
return;
m_actions.UpdateStates();
processInputBindings();
vr::VREvent_t vrEvent;
bool chaperoneDataAlreadyUpdated = false;
while ( pollNextEvent( m_ulOverlayHandle, &vrEvent ) )
{
switch ( vrEvent.eventType )
{
case vr::VREvent_MouseMove:
{
QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
if ( ptNewMouse != m_ptLastMouse )
{
QMouseEvent mouseEvent( QEvent::MouseMove,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
Qt::NoButton,
m_lastMouseButtons,
0 );
m_ptLastMouse = ptNewMouse;
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
OnRenderRequest();
}
}
break;
case vr::VREvent_MouseButtonDown:
{
QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
Qt::MouseButton button
= vrEvent.data.mouse.button == vr::VRMouseButton_Right
? Qt::RightButton
: Qt::LeftButton;
m_lastMouseButtons |= button;
QMouseEvent mouseEvent( QEvent::MouseButtonPress,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
button,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
}
break;
case vr::VREvent_MouseButtonUp:
{
QPoint ptNewMouse = getMousePositionForEvent( vrEvent.data.mouse );
Qt::MouseButton button
= vrEvent.data.mouse.button == vr::VRMouseButton_Right
? Qt::RightButton
: Qt::LeftButton;
m_lastMouseButtons &= ~button;
QMouseEvent mouseEvent( QEvent::MouseButtonRelease,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
button,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
}
break;
case vr::VREvent_Scroll:
{
// Wheel speed is defined as 1/8 of a degree
QWheelEvent wheelEvent(
m_ptLastMouse,
m_pWindow->mapToGlobal( m_ptLastMouse ),
QPoint(),
QPoint( vrEvent.data.scroll.xdelta * 360.0f * 8.0f,
vrEvent.data.scroll.ydelta * 360.0f * 8.0f ),
0,
Qt::Vertical,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &wheelEvent );
}
break;
case vr::VREvent_OverlayShown:
{
m_pWindow->update();
}
break;
case vr::VREvent_Quit:
{
LOG( INFO ) << "Received quit request.";
vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some
// time just in case
m_moveCenterTabController.reset();
m_chaperoneTabController.shutdown();
Shutdown();
QApplication::exit();
return; return;
}
break;
m_actions.UpdateStates(); case vr::VREvent_DashboardActivated:
{
LOG( DEBUG ) << "Dashboard activated";
m_dashboardVisible = true;
}
break;
processInputBindings(); case vr::VREvent_DashboardDeactivated:
{
LOG( DEBUG ) << "Dashboard deactivated";
m_dashboardVisible = false;
}
break;
vr::VREvent_t vrEvent; case vr::VREvent_KeyboardDone:
bool chaperoneDataAlreadyUpdated = false; {
while ( pollNextEvent( m_ulOverlayHandle, &vrEvent ) ) char keyboardBuffer[1024];
vr::VROverlay()->GetKeyboardText( keyboardBuffer, 1024 );
emit keyBoardInputSignal( QString( keyboardBuffer ),
vrEvent.data.keyboard.uUserValue );
}
break;
// Multiple ChaperoneUniverseHasChanged are often emitted at the
// same time (some with a little bit of delay) There is no sure way
// to recognize redundant events, we can only exclude redundant
// events during the same call of OnTimeoutPumpEvents() INFO Removed
// logging on play space mover for possible crashing issues.
case vr::VREvent_ChaperoneUniverseHasChanged:
case vr::VREvent_ChaperoneDataHasChanged:
{
if ( !chaperoneDataAlreadyUpdated )
{
// LOG(INFO) << "Re-loading chaperone data ...";
m_chaperoneUtils.loadChaperoneData();
// LOG(INFO) << "Found " << m_chaperoneUtils.quadsCount() <<
// " chaperone quads."; if
// (m_chaperoneUtils.isChaperoneWellFormed()) { LOG(INFO) <<
// "Chaperone data seems to be well-formed.";
//} else {
// LOG(INFO) << "Chaperone data is NOT well-formed.";
//}
chaperoneDataAlreadyUpdated = true;
}
}
break;
}
}
vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount];
vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(
vr::TrackingUniverseStanding,
0.0f,
devicePoses,
vr::k_unMaxTrackedDeviceCount );
// HMD/Controller Velocities
auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_LeftHand );
float leftSpeed = 0.0f;
if ( leftId != vr::k_unTrackedDeviceIndexInvalid
&& devicePoses[leftId].bPoseIsValid
&& devicePoses[leftId].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[leftId].vVelocity.v;
leftSpeed
= std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
}
auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_RightHand );
auto rightSpeed = 0.0f;
if ( rightId != vr::k_unTrackedDeviceIndexInvalid
&& devicePoses[rightId].bPoseIsValid
&& devicePoses[rightId].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[rightId].vVelocity.v;
rightSpeed
= std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
}
auto hmdSpeed = 0.0f;
if ( devicePoses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid
&& devicePoses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[vr::k_unTrackedDeviceIndex_Hmd].vVelocity.v;
hmdSpeed
= std::sqrt( vel[0] * vel[0] + vel[1] * vel[1] + vel[2] * vel[2] );
}
m_moveCenterTabController.eventLoopTick(
vr::VRCompositor()->GetTrackingSpace(), devicePoses );
m_utilitiesTabController.eventLoopTick();
m_fixFloorTabController.eventLoopTick( devicePoses );
m_statisticsTabController.eventLoopTick(
devicePoses, leftSpeed, rightSpeed );
m_steamVRTabController.eventLoopTick();
m_chaperoneTabController.eventLoopTick(
devicePoses, leftSpeed, rightSpeed, hmdSpeed );
m_settingsTabController.eventLoopTick();
m_reviveTabController.eventLoopTick();
m_audioTabController.eventLoopTick();
m_accessibilityTabController.eventLoopTick(
vr::VRCompositor()->GetTrackingSpace() );
if ( m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid )
{
while ( vr::VROverlay()->PollNextOverlayEvent(
m_ulOverlayThumbnailHandle, &vrEvent, sizeof( vrEvent ) ) )
{ {
switch ( vrEvent.eventType ) switch ( vrEvent.eventType )
{ {
case vr::VREvent_MouseMove:
{
QPoint ptNewMouse
= getMousePositionForEvent( vrEvent.data.mouse );
if ( ptNewMouse != m_ptLastMouse )
{
QMouseEvent mouseEvent(
QEvent::MouseMove,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
Qt::NoButton,
m_lastMouseButtons,
0 );
m_ptLastMouse = ptNewMouse;
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
OnRenderRequest();
}
}
break;
case vr::VREvent_MouseButtonDown:
{
QPoint ptNewMouse
= getMousePositionForEvent( vrEvent.data.mouse );
Qt::MouseButton button
= vrEvent.data.mouse.button == vr::VRMouseButton_Right
? Qt::RightButton
: Qt::LeftButton;
m_lastMouseButtons |= button;
QMouseEvent mouseEvent( QEvent::MouseButtonPress,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
button,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
}
break;
case vr::VREvent_MouseButtonUp:
{
QPoint ptNewMouse
= getMousePositionForEvent( vrEvent.data.mouse );
Qt::MouseButton button
= vrEvent.data.mouse.button == vr::VRMouseButton_Right
? Qt::RightButton
: Qt::LeftButton;
m_lastMouseButtons &= ~button;
QMouseEvent mouseEvent( QEvent::MouseButtonRelease,
ptNewMouse,
m_pWindow->mapToGlobal( ptNewMouse ),
button,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &mouseEvent );
}
break;
case vr::VREvent_Scroll:
{
// Wheel speed is defined as 1/8 of a degree
QWheelEvent wheelEvent(
m_ptLastMouse,
m_pWindow->mapToGlobal( m_ptLastMouse ),
QPoint(),
QPoint( vrEvent.data.scroll.xdelta * 360.0f * 8.0f,
vrEvent.data.scroll.ydelta * 360.0f * 8.0f ),
0,
Qt::Vertical,
m_lastMouseButtons,
0 );
QCoreApplication::sendEvent( m_pWindow.get(), &wheelEvent );
}
break;
case vr::VREvent_OverlayShown: case vr::VREvent_OverlayShown:
{ {
m_pWindow->update(); m_pWindow->update();
} }
break; break;
case vr::VREvent_Quit:
{
LOG( INFO ) << "Received quit request.";
vr::VRSystem()->AcknowledgeQuit_Exiting(); // Let us buy some
// time just in case
m_moveCenterTabController.reset();
m_chaperoneTabController.shutdown();
Shutdown();
QApplication::exit();
return;
}
break;
case vr::VREvent_DashboardActivated:
{
LOG( DEBUG ) << "Dashboard activated";
m_dashboardVisible = true;
}
break;
case vr::VREvent_DashboardDeactivated:
{
LOG( DEBUG ) << "Dashboard deactivated";
m_dashboardVisible = false;
}
break;
case vr::VREvent_KeyboardDone:
{
char keyboardBuffer[1024];
vr::VROverlay()->GetKeyboardText( keyboardBuffer, 1024 );
emit keyBoardInputSignal( QString( keyboardBuffer ),
vrEvent.data.keyboard.uUserValue );
}
break;
// Multiple ChaperoneUniverseHasChanged are often emitted at the
// same time (some with a little bit of delay) There is no sure way
// to recognize redundant events, we can only exclude redundant
// events during the same call of OnTimeoutPumpEvents() INFO Removed
// logging on play space mover for possible crashing issues.
case vr::VREvent_ChaperoneUniverseHasChanged:
case vr::VREvent_ChaperoneDataHasChanged:
{
if ( !chaperoneDataAlreadyUpdated )
{
// LOG(INFO) << "Re-loading chaperone data ...";
m_chaperoneUtils.loadChaperoneData();
// LOG(INFO) << "Found " << m_chaperoneUtils.quadsCount() <<
// " chaperone quads."; if
// (m_chaperoneUtils.isChaperoneWellFormed()) { LOG(INFO) <<
// "Chaperone data seems to be well-formed.";
//} else {
// LOG(INFO) << "Chaperone data is NOT well-formed.";
//}
chaperoneDataAlreadyUpdated = true;
}
}
break;
} }
} }
vr::TrackedDevicePose_t devicePoses[vr::k_unMaxTrackedDeviceCount];
vr::VRSystem()->GetDeviceToAbsoluteTrackingPose(
vr::TrackingUniverseStanding,
0.0f,
devicePoses,
vr::k_unMaxTrackedDeviceCount );
// HMD/Controller Velocities
auto leftId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_LeftHand );
float leftSpeed = 0.0f;
if ( leftId != vr::k_unTrackedDeviceIndexInvalid
&& devicePoses[leftId].bPoseIsValid
&& devicePoses[leftId].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[leftId].vVelocity.v;
leftSpeed = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1]
+ vel[2] * vel[2] );
}
auto rightId = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(
vr::TrackedControllerRole_RightHand );
auto rightSpeed = 0.0f;
if ( rightId != vr::k_unTrackedDeviceIndexInvalid
&& devicePoses[rightId].bPoseIsValid
&& devicePoses[rightId].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[rightId].vVelocity.v;
rightSpeed = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1]
+ vel[2] * vel[2] );
}
auto hmdSpeed = 0.0f;
if ( devicePoses[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid
&& devicePoses[vr::k_unTrackedDeviceIndex_Hmd].eTrackingResult
== vr::TrackingResult_Running_OK )
{
auto& vel = devicePoses[vr::k_unTrackedDeviceIndex_Hmd].vVelocity.v;
hmdSpeed = std::sqrt( vel[0] * vel[0] + vel[1] * vel[1]
+ vel[2] * vel[2] );
}
m_moveCenterTabController.eventLoopTick(
vr::VRCompositor()->GetTrackingSpace(), devicePoses );
m_utilitiesTabController.eventLoopTick();
m_fixFloorTabController.eventLoopTick( devicePoses );
m_statisticsTabController.eventLoopTick(
devicePoses, leftSpeed, rightSpeed );
m_steamVRTabController.eventLoopTick();
m_chaperoneTabController.eventLoopTick(
devicePoses, leftSpeed, rightSpeed, hmdSpeed );
m_settingsTabController.eventLoopTick();
m_reviveTabController.eventLoopTick();
m_audioTabController.eventLoopTick();
m_accessibilityTabController.eventLoopTick(
vr::VRCompositor()->GetTrackingSpace() );
if ( m_ulOverlayThumbnailHandle != vr::k_ulOverlayHandleInvalid )
{
while ( vr::VROverlay()->PollNextOverlayEvent(
m_ulOverlayThumbnailHandle, &vrEvent, sizeof( vrEvent ) ) )
{
switch ( vrEvent.eventType )
{
case vr::VREvent_OverlayShown:
{
m_pWindow->update();
}
break;
}
}
}
m_lastFrame = m_currentFrame;
} }
} }
+1
View File
@@ -167,6 +167,7 @@ public:
bool pollNextEvent( vr::VROverlayHandle_t ulOverlayHandle, bool pollNextEvent( vr::VROverlayHandle_t ulOverlayHandle,
vr::VREvent_t* pEvent ); vr::VREvent_t* pEvent );
void mainEventLoop();
public slots: public slots:
void renderOverlay(); void renderOverlay();
@@ -116,6 +116,19 @@ void AccessibilityTabController::eventLoopTick(
{ {
return; return;
} }
// 151 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 151 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AudioTabController: 89
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// ReviveTabController: 139
// SettingsTabController: 157
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 151 ) if ( settingsUpdateCounter >= 151 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
+13
View File
@@ -168,6 +168,19 @@ void AudioTabController::eventLoopTick()
{ {
return; return;
} }
// 89 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 89 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// ReviveTabController: 139
// SettingsTabController: 157
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 89 ) if ( settingsUpdateCounter >= 89 )
{ {
if ( m_micProximitySensorCanMute ) if ( m_micProximitySensorCanMute )
@@ -649,6 +649,18 @@ void ChaperoneTabController::eventLoopTick(
} }
} }
// 101 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 101 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// MoveCenterTabController: 149
// ReviveTabController: 139
// SettingsTabController: 157
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 101 ) if ( settingsUpdateCounter >= 101 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
@@ -976,6 +976,18 @@ void MoveCenterTabController::eventLoopTick(
vr::ETrackingUniverseOrigin universe, vr::ETrackingUniverseOrigin universe,
vr::TrackedDevicePose_t* devicePoses ) vr::TrackedDevicePose_t* devicePoses )
{ {
// 149 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 149 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// ChaperoneTabController: 101
// ReviveTabController: 139
// SettingsTabController: 157
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 149 ) if ( settingsUpdateCounter >= 149 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
@@ -309,6 +309,18 @@ void ReviveTabController::eventLoopTick()
if ( m_isOverlayInstalled if ( m_isOverlayInstalled
|| parent->m_settingsTabController.forceRevivePage() ) || parent->m_settingsTabController.forceRevivePage() )
{ {
// 139 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 139 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// SettingsTabController: 157
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 139 ) if ( settingsUpdateCounter >= 139 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
@@ -28,6 +28,18 @@ void SettingsTabController::initStage2( OverlayController* var_parent,
void SettingsTabController::eventLoopTick() void SettingsTabController::eventLoopTick()
{ {
// 157 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 157 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// ReviveTabController: 139
// SteamVRTabController: 97
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 157 ) if ( settingsUpdateCounter >= 157 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
@@ -22,6 +22,18 @@ void SteamVRTabController::initStage2( OverlayController* var_parent,
void SteamVRTabController::eventLoopTick() void SteamVRTabController::eventLoopTick()
{ {
// 97 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 97 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// ReviveTabController: 139
// SettingsTabController: 157
// UtilitiesTabController: 19
if ( settingsUpdateCounter >= 97 ) if ( settingsUpdateCounter >= 97 )
{ {
if ( parent->isDashboardVisible() ) if ( parent->isDashboardVisible() )
@@ -321,6 +321,18 @@ vr::VROverlayHandle_t createBatteryOverlay( vr::TrackedDeviceIndex_t index )
void UtilitiesTabController::eventLoopTick() void UtilitiesTabController::eventLoopTick()
{ {
// 19 was chosen because it's a prime number (to reduce overlap of
// simultaneous settings updates).
// Actual rate of updates is 19 * vsync (~11ms)
// Values chosen based on update speed priority
// Values in other tabs are as follows (avoid using same values):
// AccessibiltyTabController: 151
// AudioTabController: 89
// ChaperoneTabController: 101
// MoveCenterTabController: 149
// ReviveTabController: 139
// SettingsTabController: 157
// SteamVRTabController: 97
if ( settingsUpdateCounter >= 19 ) if ( settingsUpdateCounter >= 19 )
{ {
vr::VROverlayHandle_t pOverlayHandle; vr::VROverlayHandle_t pOverlayHandle;