Chromium Code Reviews| Index: chrome/browser/android/vr_shell/vr_shell.cc |
| diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc |
| index 90456fd60192c92960f1e2210719bb461e36cc6a..26cdca892a17059783d3d227dcc01fe88cccdc04 100644 |
| --- a/chrome/browser/android/vr_shell/vr_shell.cc |
| +++ b/chrome/browser/android/vr_shell/vr_shell.cc |
| @@ -542,6 +542,7 @@ void VrShell::SendEventsToTarget(VrInputManager* input_target, |
| } |
| void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) { |
| + webvr_pose_index_max_ = pose_num; |
| webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose; |
| } |
| @@ -559,6 +560,19 @@ uint32_t GetPixelEncodedPoseIndex() { |
| return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); |
| } |
| +bool VrShell::WebVrPoseIsValid(uint32_t pose_frame) { |
|
mthiesse
2016/12/01 15:39:11
This doesn't guarantee the pose is valid; we shoul
klausw
2016/12/01 16:10:18
Will do, in earlier versions I did have a magic nu
klausw
2016/12/01 19:50:41
Added a 16-bit magic number. Currently hardcoded s
|
| + // Ignore pose numbers that are zero or larger than any known pose |
| + // index. This helps avoid glitches from garbage data in the render |
| + // buffer that can appear during initialization or resizing. These |
| + // often appear as flashes of all-black or all-white pixels. |
| + if (pose_frame == 0 || pose_frame > webvr_pose_index_max_) { |
| + VLOG(1) << "WebVR: reject decoded pose index " << pose_frame << |
| + ", highest seen is " << webvr_pose_index_max_; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| TRACE_EVENT0("gpu", "VrShell::DrawFrame"); |
| // Reset the viewport list to just the pair of viewports for the |
| @@ -623,15 +637,18 @@ void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| // doing this once we have working no-compositor rendering for WebVR. |
| if (gvr_api_->GetAsyncReprojectionEnabled()) { |
| uint32_t webvr_pose_frame = GetPixelEncodedPoseIndex(); |
| - // If we don't get a valid frame ID back we shouldn't attempt to reproject |
| - // by an invalid matrix, so turn of reprojection instead. |
| - if (webvr_pose_frame == 0) { |
| - webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| - webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| - } else { |
| + if (WebVrPoseIsValid(webvr_pose_frame)) { |
| + // We have a valid pose, use it for reprojection. |
| webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_FULL); |
| webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_FULL); |
| head_pose = webvr_head_pose_[webvr_pose_frame % kPoseRingBufferSize]; |
|
mthiesse
2016/12/01 15:39:11
You should make webvr_head_pose_ a vector of uniqu
klausw
2016/12/01 16:10:18
Poses do get reused unfortunately. The compositor
klausw
2016/12/01 19:50:41
Done, I've added a "valid" vector that's set to fa
|
| + } else { |
| + // If we don't get a valid frame ID back we shouldn't attempt |
| + // to reproject by an invalid matrix, so turn off reprojection |
| + // instead. Invalid poses can permanently break reprojection |
| + // for this GVR instance: http://crbug.com/667327 |
| + webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| + webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| } |
| } |
| } |