Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(723)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2541023003: WebVR: Add sanity checks for decoded pose index values (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/android/vr_shell/vr_shell.h" 5 #include "chrome/browser/android/vr_shell/vr_shell.h"
6 6
7 #include "base/metrics/histogram_macros.h" 7 #include "base/metrics/histogram_macros.h"
8 #include "chrome/browser/android/vr_shell/ui_elements.h" 8 #include "chrome/browser/android/vr_shell/ui_elements.h"
9 #include "chrome/browser/android/vr_shell/ui_interface.h" 9 #include "chrome/browser/android/vr_shell/ui_interface.h"
10 #include "chrome/browser/android/vr_shell/ui_scene.h" 10 #include "chrome/browser/android/vr_shell/ui_scene.h"
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF(); 535 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF();
536 } 536 }
537 gesture->type = WebInputEvent::GestureTapDown; 537 gesture->type = WebInputEvent::GestureTapDown;
538 gesture->data.tapDown.width = pixel_x; 538 gesture->data.tapDown.width = pixel_x;
539 gesture->data.tapDown.height = pixel_y; 539 gesture->data.tapDown.height = pixel_y;
540 current_input_target_->ProcessUpdatedGesture(*gesture.get()); 540 current_input_target_->ProcessUpdatedGesture(*gesture.get());
541 } 541 }
542 } 542 }
543 543
544 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) { 544 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
545 webvr_pose_index_max_ = pose_num;
545 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose; 546 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose;
546 } 547 }
547 548
548 uint32_t GetPixelEncodedPoseIndex() { 549 uint32_t GetPixelEncodedPoseIndex() {
549 TRACE_EVENT0("gpu", "VrShell::GetPixelEncodedPoseIndex"); 550 TRACE_EVENT0("gpu", "VrShell::GetPixelEncodedPoseIndex");
550 // Read the pose index encoded in a bottom left pixel as color values. 551 // Read the pose index encoded in a bottom left pixel as color values.
551 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which 552 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which
552 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc 553 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc
553 // which tracks poses. 554 // which tracks poses.
554 uint8_t pixels[4]; 555 uint8_t pixels[4];
555 // Assume we're reading from the framebuffer we just wrote to. 556 // Assume we're reading from the framebuffer we just wrote to.
556 // That's true currently, we may need to use glReadBuffer(GL_BACK) 557 // That's true currently, we may need to use glReadBuffer(GL_BACK)
557 // or equivalent if the rendering setup changes in the future. 558 // or equivalent if the rendering setup changes in the future.
558 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 559 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
559 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); 560 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16);
560 } 561 }
561 562
563 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
564 // Ignore pose numbers that are zero or larger than any known pose
565 // index. This helps avoid glitches from garbage data in the render
566 // buffer that can appear during initialization or resizing. These
567 // often appear as flashes of all-black or all-white pixels.
568 if (pose_frame == 0 || pose_frame > webvr_pose_index_max_) {
569 VLOG(1) << "WebVR: reject decoded pose index " << pose_frame <<
570 ", highest seen is " << webvr_pose_index_max_;
571 return false;
572 }
573 return true;
574 }
575
562 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { 576 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) {
563 TRACE_EVENT0("gpu", "VrShell::DrawFrame"); 577 TRACE_EVENT0("gpu", "VrShell::DrawFrame");
564 // Reset the viewport list to just the pair of viewports for the 578 // Reset the viewport list to just the pair of viewports for the
565 // primary buffer each frame. Head-locked viewports get added by 579 // primary buffer each frame. Head-locked viewports get added by
566 // DrawVrShell if needed. 580 // DrawVrShell if needed.
567 buffer_viewport_list_->SetToRecommendedBufferViewports(); 581 buffer_viewport_list_->SetToRecommendedBufferViewports();
568 582
569 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { 583 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
570 // If needed, resize the primary buffer for use with WebVR. 584 // If needed, resize the primary buffer for use with WebVR.
571 if (render_size_primary_ != render_size_primary_webvr_) { 585 if (render_size_primary_ != render_size_primary_webvr_) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 630
617 // When using async reprojection, we need to know which pose was used in 631 // When using async reprojection, we need to know which pose was used in
618 // the WebVR app for drawing this frame. Due to unknown amounts of 632 // the WebVR app for drawing this frame. Due to unknown amounts of
619 // buffering in the compositor and SurfaceTexture, we read the pose number 633 // buffering in the compositor and SurfaceTexture, we read the pose number
620 // from a corner pixel. There's no point in doing this for legacy 634 // from a corner pixel. There's no point in doing this for legacy
621 // distortion rendering since that doesn't need a pose, and reading back 635 // distortion rendering since that doesn't need a pose, and reading back
622 // pixels is an expensive operation. TODO(klausw,crbug.com/655722): stop 636 // pixels is an expensive operation. TODO(klausw,crbug.com/655722): stop
623 // doing this once we have working no-compositor rendering for WebVR. 637 // doing this once we have working no-compositor rendering for WebVR.
624 if (gvr_api_->GetAsyncReprojectionEnabled()) { 638 if (gvr_api_->GetAsyncReprojectionEnabled()) {
625 uint32_t webvr_pose_frame = GetPixelEncodedPoseIndex(); 639 uint32_t webvr_pose_frame = GetPixelEncodedPoseIndex();
626 // If we don't get a valid frame ID back we shouldn't attempt to reproject 640 if (WebVrPoseIsValid(webvr_pose_frame)) {
627 // by an invalid matrix, so turn of reprojection instead. 641 // We have a valid pose, use it for reprojection.
628 if (webvr_pose_frame == 0) {
629 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
630 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
631 } else {
632 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_FULL); 642 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_FULL);
633 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_FULL); 643 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_FULL);
634 head_pose = webvr_head_pose_[webvr_pose_frame % kPoseRingBufferSize]; 644 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
645 } else {
646 // If we don't get a valid frame ID back we shouldn't attempt
647 // to reproject by an invalid matrix, so turn off reprojection
648 // instead. Invalid poses can permanently break reprojection
649 // for this GVR instance: http://crbug.com/667327
650 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
651 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
635 } 652 }
636 } 653 }
637 } 654 }
638 655
639 DrawVrShell(head_pose, frame); 656 DrawVrShell(head_pose, frame);
640 657
641 frame.Unbind(); 658 frame.Unbind();
642 frame.Submit(*buffer_viewport_list_, head_pose); 659 frame.Submit(*buffer_viewport_list_, head_pose);
643 } 660 }
644 661
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 const JavaParamRef<jobject>& ui_web_contents, 1070 const JavaParamRef<jobject>& ui_web_contents,
1054 jlong ui_window_android) { 1071 jlong ui_window_android) {
1055 return reinterpret_cast<intptr_t>(new VrShell( 1072 return reinterpret_cast<intptr_t>(new VrShell(
1056 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), 1073 env, obj, content::WebContents::FromJavaWebContents(content_web_contents),
1057 reinterpret_cast<ui::WindowAndroid*>(content_window_android), 1074 reinterpret_cast<ui::WindowAndroid*>(content_window_android),
1058 content::WebContents::FromJavaWebContents(ui_web_contents), 1075 content::WebContents::FromJavaWebContents(ui_web_contents),
1059 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 1076 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
1060 } 1077 }
1061 1078
1062 } // namespace vr_shell 1079 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698