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

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

Issue 2430543002: Draw WebVR security overlay with a non-reprojected viewport (Closed)
Patch Set: Rebase, Overlay->Headlocked Created 4 years, 2 months 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 // Positions and sizes of statically placed UI elements in the UI texture. 76 // Positions and sizes of statically placed UI elements in the UI texture.
77 // TODO(klausw): replace the hardcoded positions with JS position/offset 77 // TODO(klausw): replace the hardcoded positions with JS position/offset
78 // retrieval once the infrastructure for that is hooked up. 78 // retrieval once the infrastructure for that is hooked up.
79 // 79 //
80 // UI is designed with 1 pixel = 1mm at 1m distance. It's rescaled to 80 // UI is designed with 1 pixel = 1mm at 1m distance. It's rescaled to
81 // maintain the same angular resolution if placed closer or further. 81 // maintain the same angular resolution if placed closer or further.
82 // The warning overlays should be fairly close since they cut holes 82 // The warning overlays should be fairly close since they cut holes
83 // into geometry (they ignore the Z buffer), leading to odd effects 83 // into geometry (they ignore the Z buffer), leading to odd effects
84 // if they are far away. 84 // if they are far away.
85 static constexpr vr_shell::Recti kWebVrWarningTransientRect = { 85 static constexpr vr_shell::Recti kWebVrWarningTransientRect = {
86 0, 128, 512, 256}; 86 0, 128, 512, 250};
87 static constexpr vr_shell::Recti kWebVrWarningPermanentRect = {0, 0, 512, 128}; 87 static constexpr vr_shell::Recti kWebVrWarningPermanentRect = {0, 0, 512, 128};
88 static constexpr float kWebVrWarningDistance = 0.7f; // meters 88 static constexpr float kWebVrWarningDistance = 0.7f; // meters
89 static constexpr float kWebVrWarningPermanentAngle = 16.3f; // degrees up 89 static constexpr float kWebVrWarningPermanentAngle = 16.3f; // degrees up
90 // How long the transient warning needs to be displayed. 90 // How long the transient warning needs to be displayed.
91 static constexpr int64_t kWebVrWarningSeconds = 30; 91 static constexpr int64_t kWebVrWarningSeconds = 30;
92 92
93 static constexpr int kFramePrimaryBuffer = 0;
94 static constexpr int kFrameHeadlockedBuffer = 1;
95
93 vr_shell::VrShell* g_instance; 96 vr_shell::VrShell* g_instance;
94 97
95 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; 98 static const char kVrShellUIURL[] = "chrome://vr-shell-ui";
96 99
97 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { 100 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) {
98 float xdiff = (vec1.x - vec2.x); 101 float xdiff = (vec1.x - vec2.x);
99 float ydiff = (vec1.y - vec2.y); 102 float ydiff = (vec1.y - vec2.y);
100 float zdiff = (vec1.z - vec2.z); 103 float zdiff = (vec1.z - vec2.z);
101 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; 104 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
102 return std::sqrt(scale); 105 return std::sqrt(scale);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || 243 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone ||
241 gl::init::InitializeGLOneOff()); 244 gl::init::InitializeGLOneOff());
242 245
243 content_texture_id_ = content_texture_handle; 246 content_texture_id_ = content_texture_handle;
244 ui_texture_id_ = ui_texture_handle; 247 ui_texture_id_ = ui_texture_handle;
245 248
246 gvr_api_->InitializeGl(); 249 gvr_api_->InitializeGl();
247 std::vector<gvr::BufferSpec> specs; 250 std::vector<gvr::BufferSpec> specs;
248 specs.push_back(gvr_api_->CreateBufferSpec()); 251 specs.push_back(gvr_api_->CreateBufferSpec());
249 render_size_ = specs[0].GetSize(); 252 render_size_ = specs[0].GetSize();
253
254 // For WebVR content
255 specs.push_back(gvr_api_->CreateBufferSpec());
256
250 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); 257 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs)));
251 258
252 vr_shell_renderer_.reset(new VrShellRenderer()); 259 vr_shell_renderer_.reset(new VrShellRenderer());
253 buffer_viewport_list_.reset( 260 buffer_viewport_list_.reset(
254 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); 261 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList()));
262 buffer_viewport_list_->SetToRecommendedBufferViewports();
263
255 buffer_viewport_.reset( 264 buffer_viewport_.reset(
256 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 265 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
266
267 headlocked_left_viewport_.reset(
268 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
269 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE,
270 headlocked_left_viewport_.get());
271 headlocked_left_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer);
272 headlocked_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
273
274 headlocked_right_viewport_.reset(
275 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
276 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
277 headlocked_right_viewport_.get());
278 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer);
279 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
257 } 280 }
258 281
259 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) { 282 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
260 controller_->UpdateState(); 283 controller_->UpdateState();
261 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture(); 284 std::unique_ptr<VrGesture> gesture = controller_->DetectGesture();
262 285
263 // TODO(asimjour) for now, scroll is sent to the main content. 286 // TODO(asimjour) for now, scroll is sent to the main content.
264 if (gesture->type == WebInputEvent::GestureScrollBegin || 287 if (gesture->type == WebInputEvent::GestureScrollBegin ||
265 gesture->type == WebInputEvent::GestureScrollUpdate || 288 gesture->type == WebInputEvent::GestureScrollUpdate ||
266 gesture->type == WebInputEvent::GestureScrollEnd) { 289 gesture->type == WebInputEvent::GestureScrollEnd) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 gvr::Vec3f position = GetTranslation(head_pose); 434 gvr::Vec3f position = GetTranslation(head_pose);
412 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { 435 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) {
413 // This appears to be a 3DOF pose without a neck model. Add one. 436 // This appears to be a 3DOF pose without a neck model. Add one.
414 // The head pose has redundant data. Assume we're only using the 437 // The head pose has redundant data. Assume we're only using the
415 // object_from_reference_matrix, we're not updating position_external. 438 // object_from_reference_matrix, we're not updating position_external.
416 // TODO: Not sure what object_from_reference_matrix is. The new api removed 439 // TODO: Not sure what object_from_reference_matrix is. The new api removed
417 // it. For now, removing it seems working fine. 440 // it. For now, removing it seems working fine.
418 gvr_api_->ApplyNeckModel(head_pose, 1.0f); 441 gvr_api_->ApplyNeckModel(head_pose, 1.0f);
419 } 442 }
420 443
421 // Bind back to the default framebuffer. 444 // Bind the primary framebuffer.
422 frame.BindBuffer(0); 445 frame.BindBuffer(kFramePrimaryBuffer);
423 446
424 if (webvr_mode_) { 447 if (webvr_mode_) {
425 DrawWebVr(); 448 DrawWebVr();
426 if (!webvr_secure_origin_) { 449 // Wait for the DOM contents to be loaded before rendering to avoid drawing
450 // white rectangles with no content.
451 if (!webvr_secure_origin_ && IsUiTextureReady()) {
452 size_t last_viewport = buffer_viewport_list_->GetSize();
453 buffer_viewport_list_->SetBufferViewport(last_viewport++,
454 *headlocked_left_viewport_);
455 buffer_viewport_list_->SetBufferViewport(last_viewport++,
456 *headlocked_right_viewport_);
457
458 // Bind the headlocked framebuffer.
459 frame.BindBuffer(kFrameHeadlockedBuffer);
427 DrawWebVrOverlay(target_time.monotonic_system_time_nanos); 460 DrawWebVrOverlay(target_time.monotonic_system_time_nanos);
428 } 461 }
429 462
430 // When using async reprojection, we need to know which pose was used in 463 // When using async reprojection, we need to know which pose was used in
431 // the WebVR app for drawing this frame. Due to unknown amounts of 464 // the WebVR app for drawing this frame. Due to unknown amounts of
432 // buffering in the compositor and SurfaceTexture, we read the pose number 465 // buffering in the compositor and SurfaceTexture, we read the pose number
433 // from a corner pixel. There's no point in doing this for legacy 466 // from a corner pixel. There's no point in doing this for legacy
434 // distortion rendering since that doesn't need a pose, and reading back 467 // distortion rendering since that doesn't need a pose, and reading back
435 // pixels is an expensive operation. TODO(klausw): stop doing this once we 468 // pixels is an expensive operation. TODO(klausw): stop doing this once we
436 // have working no-compositor rendering for WebVR. 469 // have working no-compositor rendering for WebVR.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 view_matrix); 529 view_matrix);
497 530
498 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 531 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
499 532
500 // TODO(mthiesse): Draw order for transparency. 533 // TODO(mthiesse): Draw order for transparency.
501 DrawUI(world_render_matrix, fov_render_matrix); 534 DrawUI(world_render_matrix, fov_render_matrix);
502 DrawCursor(world_render_matrix); 535 DrawCursor(world_render_matrix);
503 } 536 }
504 537
505 bool VrShell::IsUiTextureReady() { 538 bool VrShell::IsUiTextureReady() {
506 return ui_tex_width_ > 0 && ui_tex_height_ > 0; 539 return ui_tex_width_ > 0 && ui_tex_height_ > 0 && dom_contents_loaded_;
507 } 540 }
508 541
509 Rectf VrShell::MakeUiGlCopyRect(Recti pixel_rect) { 542 Rectf VrShell::MakeUiGlCopyRect(Recti pixel_rect) {
510 CHECK(IsUiTextureReady()); 543 CHECK(IsUiTextureReady());
511 return Rectf({ 544 return Rectf({
512 static_cast<float>(pixel_rect.x) / ui_tex_width_, 545 static_cast<float>(pixel_rect.x) / ui_tex_width_,
513 static_cast<float>(pixel_rect.y) / ui_tex_height_, 546 static_cast<float>(pixel_rect.y) / ui_tex_height_,
514 static_cast<float>(pixel_rect.width) / ui_tex_width_, 547 static_cast<float>(pixel_rect.width) / ui_tex_width_,
515 static_cast<float>(pixel_rect.height) / ui_tex_height_}); 548 static_cast<float>(pixel_rect.height) / ui_tex_height_});
516 } 549 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 void VrShell::DrawWebVrOverlay(int64_t present_time_nanos) { 671 void VrShell::DrawWebVrOverlay(int64_t present_time_nanos) {
639 // Draw WebVR security warning overlays for each eye. This uses the 672 // Draw WebVR security warning overlays for each eye. This uses the
640 // eye-from-head matrices but not the pose, goal is to place the icons in an 673 // eye-from-head matrices but not the pose, goal is to place the icons in an
641 // eye-relative position so that they follow along with head rotations. 674 // eye-relative position so that they follow along with head rotations.
642 675
643 gvr::Mat4f left_eye_view_matrix = 676 gvr::Mat4f left_eye_view_matrix =
644 gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE); 677 gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE);
645 gvr::Mat4f right_eye_view_matrix = 678 gvr::Mat4f right_eye_view_matrix =
646 gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE); 679 gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE);
647 680
681 glClear(GL_COLOR_BUFFER_BIT);
682
648 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, 683 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE,
649 buffer_viewport_.get()); 684 buffer_viewport_.get());
650 DrawWebVrEye(left_eye_view_matrix, *buffer_viewport_, present_time_nanos); 685 DrawWebVrEye(left_eye_view_matrix, *buffer_viewport_, present_time_nanos);
651 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, 686 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
652 buffer_viewport_.get()); 687 buffer_viewport_.get());
653 DrawWebVrEye(right_eye_view_matrix, *buffer_viewport_, present_time_nanos); 688 DrawWebVrEye(right_eye_view_matrix, *buffer_viewport_, present_time_nanos);
654 } 689 }
655 690
656 void VrShell::DrawWebVrEye(const gvr::Mat4f& view_matrix, 691 void VrShell::DrawWebVrEye(const gvr::Mat4f& view_matrix,
657 const gvr::BufferViewport& params, 692 const gvr::BufferViewport& params,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // TODO(mthiesse): Setting the background to transparent after the DOM content 784 // TODO(mthiesse): Setting the background to transparent after the DOM content
750 // has loaded is a hack to work around the background not updating when we set 785 // has loaded is a hack to work around the background not updating when we set
751 // it to transparent unless we perform a very specific sequence of events. 786 // it to transparent unless we perform a very specific sequence of events.
752 // First the page background must load as not transparent, then we set the 787 // First the page background must load as not transparent, then we set the
753 // background of the renderer to transparent, then we update the page 788 // background of the renderer to transparent, then we update the page
754 // background to be transparent. This is probably a bug in blink that we 789 // background to be transparent. This is probably a bug in blink that we
755 // should fix. 790 // should fix.
756 ui_contents_->GetRenderWidgetHostView()->SetBackgroundColor( 791 ui_contents_->GetRenderWidgetHostView()->SetBackgroundColor(
757 SK_ColorTRANSPARENT); 792 SK_ColorTRANSPARENT);
758 html_interface_->OnDomContentsLoaded(); 793 html_interface_->OnDomContentsLoaded();
794 dom_contents_loaded_ = true;
759 } 795 }
760 796
761 void VrShell::SetWebVrMode(JNIEnv* env, 797 void VrShell::SetWebVrMode(JNIEnv* env,
762 const base::android::JavaParamRef<jobject>& obj, 798 const base::android::JavaParamRef<jobject>& obj,
763 bool enabled) { 799 bool enabled) {
764 webvr_mode_ = enabled; 800 webvr_mode_ = enabled;
765 if (enabled) { 801 if (enabled) {
766 int64_t now = gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; 802 int64_t now = gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos;
767 constexpr int64_t seconds_to_nanos = 1000 * 1000 * 1000; 803 constexpr int64_t seconds_to_nanos = 1000 * 1000 * 1000;
768 webvr_warning_end_nanos_ = now + kWebVrWarningSeconds * seconds_to_nanos; 804 webvr_warning_end_nanos_ = now + kWebVrWarningSeconds * seconds_to_nanos;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 const JavaParamRef<jobject>& ui_web_contents, 916 const JavaParamRef<jobject>& ui_web_contents,
881 jlong ui_window_android) { 917 jlong ui_window_android) {
882 return reinterpret_cast<intptr_t>(new VrShell( 918 return reinterpret_cast<intptr_t>(new VrShell(
883 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), 919 env, obj, content::WebContents::FromJavaWebContents(content_web_contents),
884 reinterpret_cast<ui::WindowAndroid*>(content_window_android), 920 reinterpret_cast<ui::WindowAndroid*>(content_window_android),
885 content::WebContents::FromJavaWebContents(ui_web_contents), 921 content::WebContents::FromJavaWebContents(ui_web_contents),
886 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 922 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
887 } 923 }
888 924
889 } // namespace vr_shell 925 } // 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