OLD | NEW |
---|---|
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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 void VrShell::InitializeGl(JNIEnv* env, | 244 void VrShell::InitializeGl(JNIEnv* env, |
245 const JavaParamRef<jobject>& obj, | 245 const JavaParamRef<jobject>& obj, |
246 jint content_texture_handle, | 246 jint content_texture_handle, |
247 jint ui_texture_handle) { | 247 jint ui_texture_handle) { |
248 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 248 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
249 gl::init::InitializeGLOneOff()); | 249 gl::init::InitializeGLOneOff()); |
250 | 250 |
251 content_texture_id_ = content_texture_handle; | 251 content_texture_id_ = content_texture_handle; |
252 ui_texture_id_ = ui_texture_handle; | 252 ui_texture_id_ = ui_texture_handle; |
253 | 253 |
254 // While WebVR is going through the compositor path, it shares | |
255 // the same texture ID. This will change once it gets its own | |
256 // surface, but store it separately to avoid future confusion. | |
257 webvr_texture_id_ = content_texture_id_; | |
258 | |
254 gvr_api_->InitializeGl(); | 259 gvr_api_->InitializeGl(); |
255 std::vector<gvr::BufferSpec> specs; | 260 std::vector<gvr::BufferSpec> specs; |
261 // For kFramePrimaryBuffer (primary VrShell and WebVR content) | |
256 specs.push_back(gvr_api_->CreateBufferSpec()); | 262 specs.push_back(gvr_api_->CreateBufferSpec()); |
257 render_size_ = specs[0].GetSize(); | 263 render_size_primary_ = specs[kFramePrimaryBuffer].GetSize(); |
258 | 264 |
259 // For WebVR content | 265 // For kFrameHeadlockedBuffer (for WebVR insecure content warning). |
266 // Set this up at fixed resolution, the (smaller) FOV gets set below. | |
260 specs.push_back(gvr_api_->CreateBufferSpec()); | 267 specs.push_back(gvr_api_->CreateBufferSpec()); |
268 specs[specs.size() - 1].SetSize(1024, 1024); | |
mthiesse
2016/11/16 21:30:41
magic numbers to constants with comment
mthiesse
2016/11/16 21:30:41
nit: specs.back()
klausw
2016/11/16 23:37:39
Done.
klausw
2016/11/16 23:37:39
Done:
// Pixel dimensions and field of view for t
| |
269 render_size_headlocked_ = specs[kFrameHeadlockedBuffer].GetSize(); | |
261 | 270 |
262 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); | 271 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); |
263 | 272 |
264 vr_shell_renderer_.reset(new VrShellRenderer()); | 273 vr_shell_renderer_.reset(new VrShellRenderer()); |
274 | |
275 // Allocate a buffer viewport for use in UI drawing. This isn't | |
276 // initialized at this point, it'll be set from other viewport list | |
277 // entries as needed. | |
278 buffer_viewport_.reset( | |
279 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | |
280 | |
281 // Set up main content viewports. The list has two elements, 0=left | |
282 // eye and 1=right eye. | |
265 buffer_viewport_list_.reset( | 283 buffer_viewport_list_.reset( |
266 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); | 284 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
267 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 285 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
268 | 286 |
269 buffer_viewport_.reset( | 287 // Set up head-locked UI viewports, these will be elements 2=left eye |
270 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 288 // and 3=right eye. For now, use a hardcoded 20-degree-from-center FOV |
271 | 289 // frustum to reduce rendering cost for this overlay. This fits the |
290 // current content, but will need to be adjusted once there's more dynamic | |
291 // head-locked content that could be larger. | |
272 headlocked_left_viewport_.reset( | 292 headlocked_left_viewport_.reset( |
273 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 293 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
274 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 294 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
275 headlocked_left_viewport_.get()); | 295 headlocked_left_viewport_.get()); |
276 headlocked_left_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); | 296 headlocked_left_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); |
277 headlocked_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 297 headlocked_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
298 headlocked_left_viewport_->SetSourceFov({20.f, 20.f, 20.f, 20.f}); | |
278 | 299 |
279 headlocked_right_viewport_.reset( | 300 headlocked_right_viewport_.reset( |
280 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 301 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
281 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 302 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
282 headlocked_right_viewport_.get()); | 303 headlocked_right_viewport_.get()); |
283 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); | 304 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); |
284 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 305 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
306 headlocked_right_viewport_->SetSourceFov({20.f, 20.f, 20.f, 20.f}); | |
285 | 307 |
308 // Save copies of the first two viewport items for use by WebVR, it | |
309 // sets its own UV bounds. | |
286 webvr_left_viewport_.reset( | 310 webvr_left_viewport_.reset( |
287 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 311 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
288 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 312 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
289 webvr_left_viewport_.get()); | 313 webvr_left_viewport_.get()); |
290 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); | 314 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); |
291 | 315 |
292 webvr_right_viewport_.reset( | 316 webvr_right_viewport_.reset( |
293 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 317 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
294 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 318 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
295 webvr_right_viewport_.get()); | 319 webvr_right_viewport_.get()); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 // Assume we're reading from the framebuffer we just wrote to. | 515 // Assume we're reading from the framebuffer we just wrote to. |
492 // That's true currently, we may need to use glReadBuffer(GL_BACK) | 516 // That's true currently, we may need to use glReadBuffer(GL_BACK) |
493 // or equivalent if the rendering setup changes in the future. | 517 // or equivalent if the rendering setup changes in the future. |
494 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 518 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
495 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); | 519 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); |
496 } | 520 } |
497 | 521 |
498 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 522 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
499 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 523 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
500 | 524 |
525 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { | |
mthiesse
2016/11/16 21:30:41
Do you need to undo this when not in webVR?
klausw
2016/11/16 23:37:38
I don't think so, I added this comment:
// If
klausw
2016/11/16 23:50:04
On second thought this isn't hard to fix to make i
klausw
2016/11/17 00:07:42
Done, though it doesn't currently seem to work rig
| |
526 if (render_size_primary_.width != webvr_width_ || | |
527 render_size_primary_.height != webvr_height_) { | |
528 render_size_primary_.width = webvr_width_; | |
529 render_size_primary_.height = webvr_height_; | |
530 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_); | |
531 } | |
532 } | |
533 | |
501 gvr::Frame frame = swap_chain_->AcquireFrame(); | 534 gvr::Frame frame = swap_chain_->AcquireFrame(); |
502 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 535 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
503 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 536 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
504 | 537 |
505 gvr::Mat4f head_pose = | 538 gvr::Mat4f head_pose = |
506 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); | 539 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); |
507 | 540 |
508 gvr::Vec3f position = GetTranslation(head_pose); | 541 gvr::Vec3f position = GetTranslation(head_pose); |
509 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { | 542 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { |
510 // This appears to be a 3DOF pose without a neck model. Add one. | 543 // This appears to be a 3DOF pose without a neck model. Add one. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 | 600 |
568 glEnable(GL_CULL_FACE); | 601 glEnable(GL_CULL_FACE); |
569 glEnable(GL_DEPTH_TEST); | 602 glEnable(GL_DEPTH_TEST); |
570 glDepthMask(GL_TRUE); | 603 glDepthMask(GL_TRUE); |
571 | 604 |
572 if (not_web_vr) { | 605 if (not_web_vr) { |
573 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); | 606 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); |
574 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 607 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
575 } | 608 } |
576 | 609 |
577 DrawUiView(&head_pose, world_elements); | 610 DrawUiView(&head_pose, world_elements, render_size_primary_, 0); |
bajones
2016/11/16 21:23:52
Would prefer that this used something like kPrimar
klausw
2016/11/16 23:37:39
Done, using kViewportListPrimaryOffset.
| |
578 | 611 |
579 if (!head_locked_elements.empty()) { | 612 if (!head_locked_elements.empty()) { |
580 // Switch to head-locked viewports. | 613 // Switch to head-locked viewports. |
581 size_t last_viewport = buffer_viewport_list_->GetSize(); | 614 size_t last_viewport = buffer_viewport_list_->GetSize(); |
582 buffer_viewport_list_->SetBufferViewport(last_viewport++, | 615 if (last_viewport <= 2) { |
bajones
2016/11/16 21:23:52
Not an issue with this patch, but I'm curious: Did
klausw
2016/11/16 23:37:39
I don't think it was a problem, SetToRecommendedBu
| |
583 *headlocked_left_viewport_); | 616 buffer_viewport_list_->SetBufferViewport(last_viewport++, |
584 buffer_viewport_list_->SetBufferViewport(last_viewport++, | 617 *headlocked_left_viewport_); |
585 *headlocked_right_viewport_); | 618 buffer_viewport_list_->SetBufferViewport(last_viewport++, |
619 *headlocked_right_viewport_); | |
620 } | |
586 | 621 |
587 // Bind the headlocked framebuffer. | 622 // Bind the headlocked framebuffer. |
588 frame.BindBuffer(kFrameHeadlockedBuffer); | 623 frame.BindBuffer(kFrameHeadlockedBuffer); |
589 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 624 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
590 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 625 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
591 DrawUiView(nullptr, head_locked_elements); | 626 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_, 2); |
bajones
2016/11/16 21:23:52
Same magic number concern here: kHeadlockedViewpor
klausw
2016/11/16 23:37:38
Done, using kViewportListHeadlockedOffset
| |
592 } | 627 } |
593 } | 628 } |
594 | 629 |
630 void VrShell::SetWebVRRenderSurfaceSize(int width, int height) { | |
631 webvr_width_ = width; | |
632 webvr_height_ = height; | |
633 // TODO(klausw): set the WebVR render surface size here once we have that. | |
634 } | |
635 | |
636 gvr::Sizei VrShell::GetWebVRCompositorSurfaceSize() { | |
637 return render_size_primary_; | |
638 } | |
639 | |
640 | |
595 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, | 641 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, |
596 const std::vector<const ContentRectangle*>& elements) { | 642 const std::vector<const ContentRectangle*>& elements, |
643 const gvr::Sizei& render_size, int viewport_offset) { | |
597 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { | 644 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { |
598 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get()); | 645 buffer_viewport_list_->GetBufferViewport( |
646 eye + viewport_offset, buffer_viewport_.get()); | |
599 | 647 |
600 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); | 648 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); |
601 if (head_pose != nullptr) { | 649 if (head_pose != nullptr) { |
602 view_matrix = MatrixMul(view_matrix, *head_pose); | 650 view_matrix = MatrixMul(view_matrix, *head_pose); |
603 } | 651 } |
604 | 652 |
605 gvr::Recti pixel_rect = | 653 gvr::Recti pixel_rect = |
606 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv()); | 654 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv()); |
607 glViewport(pixel_rect.left, pixel_rect.bottom, | 655 glViewport(pixel_rect.left, pixel_rect.bottom, |
608 pixel_rect.right - pixel_rect.left, | 656 pixel_rect.right - pixel_rect.left, |
609 pixel_rect.top - pixel_rect.bottom); | 657 pixel_rect.top - pixel_rect.bottom); |
610 | 658 |
611 const gvr::Mat4f render_matrix = MatrixMul( | 659 const gvr::Mat4f render_matrix = MatrixMul( |
612 PerspectiveMatrixFromView( | 660 PerspectiveMatrixFromView( |
613 buffer_viewport_->GetSourceFov(), kZNear, kZFar), | 661 buffer_viewport_->GetSourceFov(), kZNear, kZFar), |
614 view_matrix); | 662 view_matrix); |
615 | 663 |
616 DrawElements(render_matrix, elements); | 664 DrawElements(render_matrix, elements); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 | 769 |
722 void VrShell::DrawWebVr() { | 770 void VrShell::DrawWebVr() { |
723 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 771 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
724 glDisable(GL_CULL_FACE); | 772 glDisable(GL_CULL_FACE); |
725 glDepthMask(GL_FALSE); | 773 glDepthMask(GL_FALSE); |
726 glDisable(GL_DEPTH_TEST); | 774 glDisable(GL_DEPTH_TEST); |
727 glDisable(GL_SCISSOR_TEST); | 775 glDisable(GL_SCISSOR_TEST); |
728 glDisable(GL_BLEND); | 776 glDisable(GL_BLEND); |
729 glDisable(GL_POLYGON_OFFSET_FILL); | 777 glDisable(GL_POLYGON_OFFSET_FILL); |
730 | 778 |
731 glViewport(0, 0, render_size_.width, render_size_.height); | 779 glViewport(0, 0, render_size_primary_.width, render_size_primary_.height); |
732 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 780 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_); |
733 | 781 |
734 buffer_viewport_list_->SetBufferViewport(0, *webvr_left_viewport_); | 782 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE, |
735 buffer_viewport_list_->SetBufferViewport(1, *webvr_right_viewport_); | 783 *webvr_left_viewport_); |
784 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE, | |
785 *webvr_right_viewport_); | |
736 } | 786 } |
737 | 787 |
738 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 788 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
739 // Set a flag to handle this on the render thread at the next frame. | 789 // Set a flag to handle this on the render thread at the next frame. |
740 touch_pending_ = true; | 790 touch_pending_ = true; |
741 } | 791 } |
742 | 792 |
743 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 793 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
744 if (gvr_api_ == nullptr) | 794 if (gvr_api_ == nullptr) |
745 return; | 795 return; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
777 webvr_mode_ = enabled; | 827 webvr_mode_ = enabled; |
778 if (enabled) { | 828 if (enabled) { |
779 html_interface_->SetMode(UiInterface::Mode::WEB_VR); | 829 html_interface_->SetMode(UiInterface::Mode::WEB_VR); |
780 } else { | 830 } else { |
781 html_interface_->SetMode(UiInterface::Mode::STANDARD); | 831 html_interface_->SetMode(UiInterface::Mode::STANDARD); |
782 } | 832 } |
783 } | 833 } |
784 | 834 |
785 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { | 835 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { |
786 html_interface_->SetSecureOrigin(secure_origin); | 836 html_interface_->SetSecureOrigin(secure_origin); |
837 webvr_needs_ui_ = !secure_origin; | |
bajones
2016/11/16 21:23:52
Doesn't look like this is actually used anywhere?
klausw
2016/11/16 23:37:38
Correct, removed here and in the .h file.
This us
| |
787 } | 838 } |
788 | 839 |
789 void VrShell::SubmitWebVRFrame() { | 840 void VrShell::SubmitWebVRFrame() { |
790 } | 841 } |
791 | 842 |
792 void VrShell::UpdateWebVRTextureBounds(const gvr::Rectf& left_bounds, | 843 void VrShell::UpdateWebVRTextureBounds(const gvr::Rectf& left_bounds, |
793 const gvr::Rectf& right_bounds) { | 844 const gvr::Rectf& right_bounds) { |
794 webvr_left_viewport_->SetSourceUv(left_bounds); | 845 webvr_left_viewport_->SetSourceUv(left_bounds); |
795 webvr_right_viewport_->SetSourceUv(right_bounds); | 846 webvr_right_viewport_->SetSourceUv(right_bounds); |
796 } | 847 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
899 const JavaParamRef<jobject>& ui_web_contents, | 950 const JavaParamRef<jobject>& ui_web_contents, |
900 jlong ui_window_android) { | 951 jlong ui_window_android) { |
901 return reinterpret_cast<intptr_t>(new VrShell( | 952 return reinterpret_cast<intptr_t>(new VrShell( |
902 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), | 953 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), |
903 reinterpret_cast<ui::WindowAndroid*>(content_window_android), | 954 reinterpret_cast<ui::WindowAndroid*>(content_window_android), |
904 content::WebContents::FromJavaWebContents(ui_web_contents), | 955 content::WebContents::FromJavaWebContents(ui_web_contents), |
905 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 956 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
906 } | 957 } |
907 | 958 |
908 } // namespace vr_shell | 959 } // namespace vr_shell |
OLD | NEW |