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

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: Address comments 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 // TODO(mthiesse): The page is no longer visible here. We should unfocus
292 // or otherwise let it know it's hidden.
293 }
294 }
295 #endif
296 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
297 return;
298 }
275 // TODO(asimjour) for now, scroll is sent to the main content. 299 // TODO(asimjour) for now, scroll is sent to the main content.
276 if (gesture->type == WebInputEvent::GestureScrollBegin || 300 if (gesture->type == WebInputEvent::GestureScrollBegin ||
277 gesture->type == WebInputEvent::GestureScrollUpdate || 301 gesture->type == WebInputEvent::GestureScrollUpdate ||
278 gesture->type == WebInputEvent::GestureScrollEnd) { 302 gesture->type == WebInputEvent::GestureScrollEnd) {
279 content_input_manager_->ProcessUpdatedGesture(*gesture.get()); 303 content_input_manager_->ProcessUpdatedGesture(*gesture.get());
280 } 304 }
281 305
282 WebInputEvent::Type original_type = gesture->type; 306 WebInputEvent::Type original_type = gesture->type;
283 gvr::Vec3f ergo_neutral_pose; 307 gvr::Vec3f ergo_neutral_pose;
284 if (!controller_->IsConnected()) { 308 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) { 428 void VrShell::SetGvrPoseForWebVr(const gvr::Mat4f& pose, uint32_t pose_num) {
405 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose; 429 webvr_head_pose_[pose_num % kPoseRingBufferSize] = pose;
406 } 430 }
407 431
408 uint32_t GetPixelEncodedPoseIndex() { 432 uint32_t GetPixelEncodedPoseIndex() {
409 // Read the pose index encoded in a bottom left pixel as color values. 433 // 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 434 // See also third_party/WebKit/Source/modules/vr/VRDisplay.cpp which
411 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc 435 // encodes the pose index, and device/vr/android/gvr/gvr_device.cc
412 // which tracks poses. 436 // which tracks poses.
413 uint8_t pixels[4]; 437 uint8_t pixels[4];
414 // Assume we're reading from the frambebuffer we just wrote to. 438 // Assume we're reading from the framebuffer we just wrote to.
415 // That's true currently, we may need to use glReadBuffer(GL_BACK) 439 // That's true currently, we may need to use glReadBuffer(GL_BACK)
416 // or equivalent if the rendering setup changes in the future. 440 // or equivalent if the rendering setup changes in the future.
417 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 441 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
418 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); 442 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16);
419 } 443 }
420 444
421 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { 445 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) {
422 buffer_viewport_list_->SetToRecommendedBufferViewports(); 446 buffer_viewport_list_->SetToRecommendedBufferViewports();
423 447
424 gvr::Frame frame = swap_chain_->AcquireFrame(); 448 gvr::Frame frame = swap_chain_->AcquireFrame();
(...skipping 17 matching lines...) Expand all
442 frame.BindBuffer(kFramePrimaryBuffer); 466 frame.BindBuffer(kFramePrimaryBuffer);
443 467
444 HandleQueuedTasks(); 468 HandleQueuedTasks();
445 469
446 // Update the render position of all UI elements (including desktop). 470 // Update the render position of all UI elements (including desktop).
447 const float screen_tilt = kDesktopScreenTiltDefault * M_PI / 180.0f; 471 const float screen_tilt = kDesktopScreenTiltDefault * M_PI / 180.0f;
448 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds()); 472 scene_->UpdateTransforms(screen_tilt, UiScene::TimeInMicroseconds());
449 473
450 UpdateController(GetForwardVector(head_pose)); 474 UpdateController(GetForwardVector(head_pose));
451 475
452 if (webvr_mode_) { 476 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) {
453 DrawWebVr(); 477 DrawWebVr();
454 478
455 // When using async reprojection, we need to know which pose was used in 479 // 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 480 // the WebVR app for drawing this frame. Due to unknown amounts of
457 // buffering in the compositor and SurfaceTexture, we read the pose number 481 // 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 482 // 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 483 // 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 484 // pixels is an expensive operation. TODO(klausw): stop doing this once we
461 // have working no-compositor rendering for WebVR. 485 // have working no-compositor rendering for WebVR.
462 if (gvr_api_->GetAsyncReprojectionEnabled()) { 486 if (gvr_api_->GetAsyncReprojectionEnabled()) {
(...skipping 16 matching lines...) Expand all
479 if (!rect->visible) { 503 if (!rect->visible) {
480 continue; 504 continue;
481 } 505 }
482 if (rect->lock_to_fov) { 506 if (rect->lock_to_fov) {
483 head_locked_elements.push_back(rect.get()); 507 head_locked_elements.push_back(rect.get());
484 } else { 508 } else {
485 world_elements.push_back(rect.get()); 509 world_elements.push_back(rect.get());
486 } 510 }
487 } 511 }
488 512
489 if (!webvr_mode_) { 513 bool not_web_vr = html_interface_->GetMode() != UiInterface::Mode::WEB_VR;
514
515 if (not_web_vr) {
490 glEnable(GL_CULL_FACE); 516 glEnable(GL_CULL_FACE);
491 glEnable(GL_DEPTH_TEST); 517 glEnable(GL_DEPTH_TEST);
492 glEnable(GL_SCISSOR_TEST); 518 glEnable(GL_SCISSOR_TEST);
493 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); 519 glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
494 } 520 }
495 521
496 if (!world_elements.empty()) { 522 DrawUiView(&head_pose, world_elements, not_web_vr);
497 DrawUiView(&head_pose, world_elements);
498 }
499 523
500 if (!head_locked_elements.empty()) { 524 if (!head_locked_elements.empty()) {
501 // Switch to head-locked viewports. 525 // Switch to head-locked viewports.
502 size_t last_viewport = buffer_viewport_list_->GetSize(); 526 size_t last_viewport = buffer_viewport_list_->GetSize();
503 buffer_viewport_list_->SetBufferViewport(last_viewport++, 527 buffer_viewport_list_->SetBufferViewport(last_viewport++,
504 *headlocked_left_viewport_); 528 *headlocked_left_viewport_);
505 buffer_viewport_list_->SetBufferViewport(last_viewport++, 529 buffer_viewport_list_->SetBufferViewport(last_viewport++,
506 *headlocked_right_viewport_); 530 *headlocked_right_viewport_);
507 531
508 // Bind the headlocked framebuffer. 532 // Bind the headlocked framebuffer.
509 frame.BindBuffer(kFrameHeadlockedBuffer); 533 frame.BindBuffer(kFrameHeadlockedBuffer);
510 glClear(GL_COLOR_BUFFER_BIT); 534 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
511 535 DrawUiView(nullptr, head_locked_elements, true);
512 DrawUiView(nullptr, head_locked_elements);
513 } 536 }
514 } 537 }
515 538
516 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, 539 void VrShell::DrawUiView(const gvr::Mat4f* head_pose,
517 const std::vector<const ContentRectangle*>& elements) { 540 const std::vector<const ContentRectangle*>& elements,
541 bool clear) {
518 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { 542 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) {
519 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get()); 543 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get());
520 544
521 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); 545 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye);
522 if (head_pose != nullptr) { 546 if (head_pose != nullptr) {
523 view_matrix = MatrixMul(view_matrix, *head_pose); 547 view_matrix = MatrixMul(view_matrix, *head_pose);
524 } 548 }
525 549
526 gvr::Recti pixel_rect = 550 gvr::Recti pixel_rect =
527 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv()); 551 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv());
528 glViewport(pixel_rect.left, pixel_rect.bottom, 552 glViewport(pixel_rect.left, pixel_rect.bottom,
529 pixel_rect.right - pixel_rect.left, 553 pixel_rect.right - pixel_rect.left,
530 pixel_rect.top - pixel_rect.bottom); 554 pixel_rect.top - pixel_rect.bottom);
531 glScissor(pixel_rect.left, pixel_rect.bottom, 555 glScissor(pixel_rect.left, pixel_rect.bottom,
532 pixel_rect.right - pixel_rect.left, 556 pixel_rect.right - pixel_rect.left,
533 pixel_rect.top - pixel_rect.bottom); 557 pixel_rect.top - pixel_rect.bottom);
534 558
535 if (!webvr_mode_) { 559 if (clear) {
536 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 560 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
537 } 561 }
538 562
539 const gvr::Mat4f render_matrix = MatrixMul( 563 const gvr::Mat4f render_matrix = MatrixMul(
540 PerspectiveMatrixFromView( 564 PerspectiveMatrixFromView(
541 buffer_viewport_->GetSourceFov(), kZNear, kZFar), 565 buffer_viewport_->GetSourceFov(), kZNear, kZFar),
542 view_matrix); 566 view_matrix);
543 567
544 DrawElements(render_matrix, elements); 568 DrawElements(render_matrix, elements);
545 if (head_pose != nullptr) { 569 if (head_pose != nullptr) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 672
649 void VrShell::DrawWebVr() { 673 void VrShell::DrawWebVr() {
650 // Don't need face culling, depth testing, blending, etc. Turn it all off. 674 // Don't need face culling, depth testing, blending, etc. Turn it all off.
651 glDisable(GL_CULL_FACE); 675 glDisable(GL_CULL_FACE);
652 glDepthMask(GL_FALSE); 676 glDepthMask(GL_FALSE);
653 glDisable(GL_DEPTH_TEST); 677 glDisable(GL_DEPTH_TEST);
654 glDisable(GL_SCISSOR_TEST); 678 glDisable(GL_SCISSOR_TEST);
655 glDisable(GL_BLEND); 679 glDisable(GL_BLEND);
656 glDisable(GL_POLYGON_OFFSET_FILL); 680 glDisable(GL_POLYGON_OFFSET_FILL);
657 681
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); 682 glViewport(0, 0, render_size_.width, render_size_.height);
662 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); 683 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_);
663 } 684 }
664 685
665 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { 686 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) {
666 // Set a flag to handle this on the render thread at the next frame. 687 // Set a flag to handle this on the render thread at the next frame.
667 touch_pending_ = true; 688 touch_pending_ = true;
668 } 689 }
669 690
670 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { 691 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, 849 const JavaParamRef<jobject>& ui_web_contents,
829 jlong ui_window_android) { 850 jlong ui_window_android) {
830 return reinterpret_cast<intptr_t>(new VrShell( 851 return reinterpret_cast<intptr_t>(new VrShell(
831 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), 852 env, obj, content::WebContents::FromJavaWebContents(content_web_contents),
832 reinterpret_cast<ui::WindowAndroid*>(content_window_android), 853 reinterpret_cast<ui::WindowAndroid*>(content_window_android),
833 content::WebContents::FromJavaWebContents(ui_web_contents), 854 content::WebContents::FromJavaWebContents(ui_web_contents),
834 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); 855 reinterpret_cast<ui::WindowAndroid*>(ui_window_android)));
835 } 856 }
836 857
837 } // namespace vr_shell 858 } // namespace vr_shell
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698