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

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

Issue 2471433002: Implement WebVR presentation pausing for VR Shell Menu Mode (Closed)
Patch Set: Implement Blur/Focus in MockVRServiceClient Created 4 years, 1 month 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
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"
11 #include "chrome/browser/android/vr_shell/vr_compositor.h" 11 #include "chrome/browser/android/vr_shell/vr_compositor.h"
12 #include "chrome/browser/android/vr_shell/vr_controller.h" 12 #include "chrome/browser/android/vr_shell/vr_controller.h"
13 #include "chrome/browser/android/vr_shell/vr_gl_util.h" 13 #include "chrome/browser/android/vr_shell/vr_gl_util.h"
14 #include "chrome/browser/android/vr_shell/vr_input_manager.h" 14 #include "chrome/browser/android/vr_shell/vr_input_manager.h"
15 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" 15 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
16 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" 16 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h"
17 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h" 17 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h"
18 #include "content/public/browser/navigation_controller.h" 18 #include "content/public/browser/navigation_controller.h"
19 #include "content/public/browser/render_view_host.h" 19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/render_widget_host.h" 20 #include "content/public/browser/render_widget_host.h"
21 #include "content/public/browser/render_widget_host_view.h" 21 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
23 #include "content/public/common/referrer.h" 23 #include "content/public/common/referrer.h"
24 #include "content/public/common/screen_info.h" 24 #include "content/public/common/screen_info.h"
25 #include "device/vr/android/gvr/gvr_device_provider.h"
25 #include "jni/VrShellImpl_jni.h" 26 #include "jni/VrShellImpl_jni.h"
26 #include "ui/android/view_android.h" 27 #include "ui/android/view_android.h"
27 #include "ui/android/window_android.h" 28 #include "ui/android/window_android.h"
28 #include "ui/base/page_transition_types.h" 29 #include "ui/base/page_transition_types.h"
29 #include "ui/gl/gl_bindings.h" 30 #include "ui/gl/gl_bindings.h"
30 #include "ui/gl/init/gl_factory.h" 31 #include "ui/gl/init/gl_factory.h"
31 32
32 using base::android::JavaParamRef; 33 using base::android::JavaParamRef;
33 34
34 namespace { 35 namespace {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 g_instance = nullptr; 180 g_instance = nullptr;
180 gl::init::ClearGLBindings(); 181 gl::init::ClearGLBindings();
181 } 182 }
182 183
183 void VrShell::SetDelegate(JNIEnv* env, 184 void VrShell::SetDelegate(JNIEnv* env,
184 const base::android::JavaParamRef<jobject>& obj, 185 const base::android::JavaParamRef<jobject>& obj,
185 const base::android::JavaParamRef<jobject>& delegate) { 186 const base::android::JavaParamRef<jobject>& delegate) {
186 delegate_ = VrShellDelegate::getNativeDelegate(env, delegate); 187 delegate_ = VrShellDelegate::getNativeDelegate(env, delegate);
187 } 188 }
188 189
189 enum class ViewerType 190 enum class ViewerType {
190 {
191 UNKNOWN_TYPE = 0, 191 UNKNOWN_TYPE = 0,
192 CARDBOARD = 1, 192 CARDBOARD = 1,
193 DAYDREAM = 2, 193 DAYDREAM = 2,
194 VIEWER_TYPE_MAX, 194 VIEWER_TYPE_MAX,
195 }; 195 };
196 196
197 void VrShell::GvrInit(JNIEnv* env, 197 void VrShell::GvrInit(JNIEnv* env,
198 const JavaParamRef<jobject>& obj, 198 const JavaParamRef<jobject>& obj,
199 jlong native_gvr_api) { 199 jlong native_gvr_api) {
200 gvr_api_ = 200 gvr_api_ =
201 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); 201 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api));
202 202
203 if (delegate_) 203 if (delegate_)
204 delegate_->OnVrShellReady(this); 204 delegate_->OnVrShellReady(this);
205 controller_.reset( 205 controller_.reset(
206 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api))); 206 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api)));
207 content_input_manager_ = new VrInputManager(main_contents_); 207 content_input_manager_ = new VrInputManager(main_contents_);
208 ui_input_manager_ = new VrInputManager(ui_contents_); 208 ui_input_manager_ = new VrInputManager(ui_contents_);
209 209
210 ViewerType viewerType; 210 ViewerType viewerType;
211 switch (gvr_api_->GetViewerType()) 211 switch (gvr_api_->GetViewerType()) {
212 {
213 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM: 212 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM:
214 viewerType = ViewerType::DAYDREAM; 213 viewerType = ViewerType::DAYDREAM;
215 break; 214 break;
216 case gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD: 215 case gvr::ViewerType::GVR_VIEWER_TYPE_CARDBOARD:
217 viewerType = ViewerType::CARDBOARD; 216 viewerType = ViewerType::CARDBOARD;
218 break; 217 break;
219 default: 218 default:
220 NOTREACHED(); 219 NOTREACHED();
221 viewerType = ViewerType::UNKNOWN_TYPE; 220 viewerType = ViewerType::UNKNOWN_TYPE;
222 break; 221 break;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); 263 new gvr::BufferViewport(gvr_api_->CreateBufferViewport()));
265 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, 264 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE,
266 headlocked_right_viewport_.get()); 265 headlocked_right_viewport_.get());
267 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); 266 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer);
268 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); 267 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE);
269 } 268 }
270 269
271 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) { 270 void VrShell::UpdateController(const gvr::Vec3f& forward_vector) {
272 controller_->UpdateState(); 271 controller_->UpdateState();
273 std::unique_ptr<WebGestureEvent> gesture = controller_->DetectGesture(); 272 std::unique_ptr<WebGestureEvent> gesture = controller_->DetectGesture();
274 273 #if defined(ENABLE_VR_SHELL)
274 // Note that button up/down state is transient, so IsButtonUp only returns
275 // true for a single frame (and we're guaranteed not to miss it).
276 if (controller_->IsButtonUp(
277 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) {
278 if (html_interface_->GetMode() == UiInterface::Mode::MENU) {
279 // Temporary: Hit app button a second time to exit menu mode.
280 if (webvr_mode_) {
281 html_interface_->SetMode(UiInterface::Mode::WEB_VR);
282 delegate_->GetDeviceProvider()->OnDisplayFocus();
283 } else {
284 html_interface_->SetMode(UiInterface::Mode::STANDARD);
285 }
286 } else {
287 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
288 delegate_->GetDeviceProvider()->OnDisplayBlur();
289 }
290 html_interface_->SetMode(UiInterface::Mode::MENU);
291 }
292 }
293 #endif
294 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
295 return;
296 }
275 // TODO(asimjour) for now, scroll is sent to the main content. 297 // TODO(asimjour) for now, scroll is sent to the main content.
276 if (gesture->type == WebInputEvent::GestureScrollBegin || 298 if (gesture->type == WebInputEvent::GestureScrollBegin ||
277 gesture->type == WebInputEvent::GestureScrollUpdate || 299 gesture->type == WebInputEvent::GestureScrollUpdate ||
278 gesture->type == WebInputEvent::GestureScrollEnd) { 300 gesture->type == WebInputEvent::GestureScrollEnd) {
279 content_input_manager_->ProcessUpdatedGesture(*gesture.get()); 301 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
280 } 302 }
281 303
282 WebInputEvent::Type original_type = gesture->type; 304 WebInputEvent::Type original_type = gesture->type;
283 gvr::Vec3f ergo_neutral_pose; 305 gvr::Vec3f ergo_neutral_pose;
284 if (!controller_->IsConnected()) { 306 if (!controller_->IsConnected()) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) { 426 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
405 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose; 427 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose;
406 } 428 }
407 429
408 uint32_t GetPixelEncodedPoseIndex() { 430 uint32_t GetPixelEncodedPoseIndex() {
409 // Read the pose index encoded in a bottom left pixel as color values. 431 // Read the pose index encoded in a bottom left pixel as color values.
410 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which 432 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which
411 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc 433 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc
412 // which tracks poses. 434 // which tracks poses.
413 uint8_t pixels[4]; 435 uint8_t pixels[4];
414 // Assume we're reading from the frambebuffer we just wrote to. 436 // Assume we're reading from the framebuffer we just wrote to.
415 // That's true currently, we may need to use glReadBuffer(GL_BACK) 437 // That's true currently, we may need to use glReadBuffer(GL_BACK)
416 // or equivalent if the rendering setup changes in the future. 438 // or equivalent if the rendering setup changes in the future.
417 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 439 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
418 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); 440 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16);
419 } 441 }
420 442
421 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { 443 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) {
422 buffer_viewport_list_->SetToRecommendedBufferViewports(); 444 buffer_viewport_list_->SetToRecommendedBufferViewports();
423 445
424 gvr::Frame frame = swap_chain_->AcquireFrame(); 446 gvr::Frame frame = swap_chain_->AcquireFrame();
(...skipping 17 matching lines...) Expand all
442 frame.BindBuffer(kFramePrimaryBuffer); 464 frame.BindBuffer(kFramePrimaryBuffer);
443 465
444 HandleQueuedTasks(); 466 HandleQueuedTasks();
445 467
446 // Update the render position of all UI elements (including desktop). 468 // Update the render position of all UI elements (including desktop).
447 const float screen_tilt = kDesktopScreenTiltDefault * M_PI / 180.0f; 469 const float screen_tilt = kDesktopScreenTiltDefault * M_PI / 180.0f;
448 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds()); 470 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds());
449 471
450 UpdateController(GetForwardVector(head_pose)); 472 UpdateController(GetForwardVector(head_pose));
451 473
452 if (webvr_mode_) { 474 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
453 DrawWebVr(); 475 DrawWebVr();
454 476
455 // When using async reprojection, we need to know which pose was used in 477 // When using async reprojection, we need to know which pose was used in
456 // the WebVR app for drawing this frame. Due to unknown amounts of 478 // the WebVR app for drawing this frame. Due to unknown amounts of
457 // buffering in the compositor and SurfaceTexture, we read the pose number 479 // buffering in the compositor and SurfaceTexture, we read the pose number
458 // from a corner pixel. There's no point in doing this for legacy 480 // from a corner pixel. There's no point in doing this for legacy
459 // distortion rendering since that doesn't need a pose, and reading back 481 // distortion rendering since that doesn't need a pose, and reading back
460 // pixels is an expensive operation. TODO(klausw): stop doing this once we 482 // pixels is an expensive operation. TODO(klausw): stop doing this once we
461 // have working no-compositor rendering for WebVR. 483 // have working no-compositor rendering for WebVR.
462 if (gvr_api_->GetAsyncReprojectionEnabled()) { 484 if (gvr_api_->GetAsyncReprojectionEnabled()) {
(...skipping 16 matching lines...) Expand all
479 if (!rect->visible) { 501 if (!rect->visible) {
480 continue; 502 continue;
481 } 503 }
482 if (rect->lock_to_fov) { 504 if (rect->lock_to_fov) {
483 head_locked_elements.push_back(rect.get()); 505 head_locked_elements.push_back(rect.get());
484 } else { 506 } else {
485 world_elements.push_back(rect.get()); 507 world_elements.push_back(rect.get());
486 } 508 }
487 } 509 }
488 510
489 if (!webvr_mode_) { 511 bool not_web_vr = html_interface_->GetMode() != UiInterface::Mode::WEB_VR;
dcheng 2016/11/04 05:24:46 Should we get rid of |webvr_mode_|?
mthiesse 2016/11/04 17:20:36 Right now it's used to know which mode to return t
512
513 if (not_web_vr) {
490 glEnable(GL_CULL_FACE); 514 glEnable(GL_CULL_FACE);
491 glEnable(GL_DEPTH_TEST); 515 glEnable(GL_DEPTH_TEST);
492 glEnable(GL_SCISSOR_TEST); 516 glEnable(GL_SCISSOR_TEST);
493 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 517 glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
494 } 518 }
495 519
496 if (!world_elements.empty()) { 520 DrawUiView(&head_pose, world_elements, not_web_vr);
497 DrawUiView(&head_pose, world_elements);
498 }
499 521
500 if (!head_locked_elements.empty()) { 522 if (!head_locked_elements.empty()) {
501 // Switch to head-locked viewports. 523 // Switch to head-locked viewports.
502 size_t last_viewport = buffer_viewport_list_->GetSize(); 524 size_t last_viewport = buffer_viewport_list_->GetSize();
503 buffer_viewport_list_->SetBufferViewport(last_viewport++, 525 buffer_viewport_list_->SetBufferViewport(last_viewport++,
504 *headlocked_left_viewport_); 526 *headlocked_left_viewport_);
505 buffer_viewport_list_->SetBufferViewport(last_viewport++, 527 buffer_viewport_list_->SetBufferViewport(last_viewport++,
506 *headlocked_right_viewport_); 528 *headlocked_right_viewport_);
507 529
508 // Bind the headlocked framebuffer. 530 // Bind the headlocked framebuffer.
509 frame.BindBuffer(kFrameHeadlockedBuffer); 531 frame.BindBuffer(kFrameHeadlockedBuffer);
510 glClear(GL_COLOR_BUFFER_BIT); 532 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
511 533 DrawUiView(nullptr, head_locked_elements, true);
512 DrawUiView(nullptr, head_locked_elements);
513 } 534 }
514 } 535 }
515 536
516 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, 537 void VrShell::DrawUiView(const gvr::Mat4f* head_pose,
517 const std::vector<const ContentRectangle*>& elements) { 538 const std::vector<const ContentRectangle*>& elements,
539 bool clear) {
518 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { 540 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) {
519 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get()); 541 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get());
520 542
521 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); 543 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye);
522 if (head_pose != nullptr) { 544 if (head_pose != nullptr) {
523 view_matrix = MatrixMul(view_matrix, *head_pose); 545 view_matrix = MatrixMul(view_matrix, *head_pose);
524 } 546 }
525 547
526 gvr::Recti pixel_rect = 548 gvr::Recti pixel_rect =
527 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv()); 549 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv());
528 glViewport(pixel_rect.left, pixel_rect.bottom, 550 glViewport(pixel_rect.left, pixel_rect.bottom,
529 pixel_rect.right - pixel_rect.left, 551 pixel_rect.right - pixel_rect.left,
530 pixel_rect.top - pixel_rect.bottom); 552 pixel_rect.top - pixel_rect.bottom);
531 glScissor(pixel_rect.left, pixel_rect.bottom, 553 glScissor(pixel_rect.left, pixel_rect.bottom,
532 pixel_rect.right - pixel_rect.left, 554 pixel_rect.right - pixel_rect.left,
533 pixel_rect.top - pixel_rect.bottom); 555 pixel_rect.top - pixel_rect.bottom);
534 556
535 if (!webvr_mode_) { 557 if (clear) {
536 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 558 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
537 } 559 }
538 560
539 const gvr::Mat4f render_matrix = MatrixMul( 561 const gvr::Mat4f render_matrix = MatrixMul(
540 PerspectiveMatrixFromView( 562 PerspectiveMatrixFromView(
541 buffer_viewport_->GetSourceFov(), kZNear, kZFar), 563 buffer_viewport_->GetSourceFov(), kZNear, kZFar),
542 view_matrix); 564 view_matrix);
543 565
544 DrawElements(render_matrix, elements); 566 DrawElements(render_matrix, elements);
545 if (head_pose != nullptr) { 567 if (head_pose != nullptr) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 670
649 void VrShell::DrawWebVr() { 671 void VrShell::DrawWebVr() {
650 // Don't need face culling, depth testing, blending, etc. Turn it all off. 672 // Don't need face culling, depth testing, blending, etc. Turn it all off.
651 glDisable(GL_CULL_FACE); 673 glDisable(GL_CULL_FACE);
652 glDepthMask(GL_FALSE); 674 glDepthMask(GL_FALSE);
653 glDisable(GL_DEPTH_TEST); 675 glDisable(GL_DEPTH_TEST);
654 glDisable(GL_SCISSOR_TEST); 676 glDisable(GL_SCISSOR_TEST);
655 glDisable(GL_BLEND); 677 glDisable(GL_BLEND);
656 glDisable(GL_POLYGON_OFFSET_FILL); 678 glDisable(GL_POLYGON_OFFSET_FILL);
657 679
658 // Don't need to clear, since we're drawing over the entire render target.
659 glClear(GL_COLOR_BUFFER_BIT);
660
661 glViewport(0, 0, render_size_.width, render_size_.height); 680 glViewport(0, 0, render_size_.width, render_size_.height);
662 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); 681 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_);
663 } 682 }
664 683
665 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { 684 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) {
666 // Set a flag to handle this on the render thread at the next frame. 685 // Set a flag to handle this on the render thread at the next frame.
667 touch_pending_ = true; 686 touch_pending_ = true;
668 } 687 }
669 688
670 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { 689 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 const JavaParamRef<jobject>& ui_web_contents, 847 const JavaParamRef<jobject>& ui_web_contents,
829 jlong ui_window_android) { 848 jlong ui_window_android) {
830 return reinterpret_cast<intptr_t>(new VrShell( 849 return reinterpret_cast<intptr_t>(new VrShell(
831 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), 850 env, obj, content::WebContents::FromJavaWebContents(content_web_contents),
832 reinterpret_cast<ui::WindowAndroid*>(content_window_android), 851 reinterpret_cast<ui::WindowAndroid*>(content_window_android),
833 content::WebContents::FromJavaWebContents(ui_web_contents), 852 content::WebContents::FromJavaWebContents(ui_web_contents),
834 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 853 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
835 } 854 }
836 855
837 } // namespace vr_shell 856 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698