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

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

Issue 2508703002: WebVR: Use content CVC size for compositor rendering (Closed)
Patch Set: Undo VrShellImpl changes, use native-side values. 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"
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698