Before this fix, a script could call into HMD.getHUDLookAtPosition2D() while the app was shutting down, which in turn would call getHeadPose() on the currently active display plugin. This call could cause a crash within the openvr plugin, because the SDK was either shutdown, or in the process of shutting down on the main thread. This fixes this by spliting the previous DisplayPlugin::getHeadPose(int) into two parts: * updateHeadPose(int) which is only called once a frame and only by the main thread. * getHeadPose() which is thread-safe and will return a cached copy of the hmd pose sampled by the last updateHeadPose.
Showing the changes to interface/src/Application.cpp (1 of 9 files). Show all
Unified · Split
| @@ -1603,7 +1603,7 @@ void Application::paintGL() { · 1602 unmodified lines | |||
| 1603 | // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it | 1603 | // unmodified head pose because the only plugin that cares (the Oculus plugin) uses it |
| 1604 | // for rotational timewarp. If we move to support positonal timewarp, we need to | 1604 | // for rotational timewarp. If we move to support positonal timewarp, we need to |
| 1605 | // ensure this contains the full pose composed with the eye offsets. | 1605 | // ensure this contains the full pose composed with the eye offsets. |
| 1606 | mat4 headPose = displayPlugin->getHeadPose(_frameCount); | 1606 | mat4 headPose = displayPlugin->updateHeadPose(_frameCount); |
| 1607 | 1607 | ||
| 1608 | // FIXME we probably don't need to set the projection matrix every frame, | 1608 | // FIXME we probably don't need to set the projection matrix every frame, |
| 1609 | // only when the display plugin changes (or in non-HMD modes when the user | 1609 | // only when the display plugin changes (or in non-HMD modes when the user |
| @@ -2975,7 +2975,7 @@ void Application::updateMyAvatarLookAtPosition() { · 1365 unmodified lines | |||
| 2975 | lookAtPosition.x = -lookAtPosition.x; | 2975 | lookAtPosition.x = -lookAtPosition.x; |
| 2976 | } | 2976 | } |
| 2977 | if (isHMD) { | 2977 | if (isHMD) { |
| 2978 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(_frameCount); | 2978 | glm::mat4 headPose = getActiveDisplayPlugin()->getHeadPose(); |
| 2979 | glm::quat hmdRotation = glm::quat_cast(headPose); | 2979 | glm::quat hmdRotation = glm::quat_cast(headPose); |
| 2980 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); | 2980 | lookAtSpot = _myCamera.getPosition() + myAvatar->getOrientation() * (hmdRotation * lookAtPosition); |
| 2981 | } else { | 2981 | } else { |
| @@ -4927,7 +4927,7 @@ mat4 Application::getEyeOffset(int eye) const { · 1945 unmodified lines | |||
| 4927 | 4927 | ||
| 4928 | mat4 Application::getHMDSensorPose() const { | 4928 | mat4 Application::getHMDSensorPose() const { |
| 4929 | if (isHMDMode()) { | 4929 | if (isHMDMode()) { |
| 4930 | return getActiveDisplayPlugin()->getHeadPose(_frameCount); | 4930 | return getActiveDisplayPlugin()->getHeadPose(); |
| 4931 | } | 4931 | } |
| 4932 | return mat4(); | 4932 | return mat4(); |
| 4933 | } | 4933 | } |