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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 66 |
67 // Fraction of the distance to the object the cursor is drawn at to avoid | 67 // Fraction of the distance to the object the cursor is drawn at to avoid |
68 // rounding errors drawing the cursor behind the object. | 68 // rounding errors drawing the cursor behind the object. |
69 static constexpr float kReticleOffset = 0.99f; | 69 static constexpr float kReticleOffset = 0.99f; |
70 | 70 |
71 // Limit the rendering distance of the reticle to the distance to a corner of | 71 // Limit the rendering distance of the reticle to the distance to a corner of |
72 // the content quad, times this value. This lets the rendering distance | 72 // the content quad, times this value. This lets the rendering distance |
73 // adjust according to content quad placement. | 73 // adjust according to content quad placement. |
74 static constexpr float kReticleDistanceMultiplier = 1.5f; | 74 static constexpr float kReticleDistanceMultiplier = 1.5f; |
75 | 75 |
| 76 // GVR buffer indices for use with viewport->SetSourceBufferIndex |
| 77 // or frame.BindBuffer. We use one for world content (with reprojection) |
| 78 // including main VrShell and WebVR content plus world-space UI. |
| 79 // The headlocked buffer is for UI that should not use reprojection. |
76 static constexpr int kFramePrimaryBuffer = 0; | 80 static constexpr int kFramePrimaryBuffer = 0; |
77 static constexpr int kFrameHeadlockedBuffer = 1; | 81 static constexpr int kFrameHeadlockedBuffer = 1; |
78 | 82 |
| 83 // Pixel dimensions and field of view for the head-locked content. This |
| 84 // is currently sized to fit the WebVR "insecure transport" warnings, |
| 85 // adjust it as needed if there is additional content. |
| 86 static constexpr gvr::Sizei kHeadlockedBufferDimensions = {1024, 1024}; |
| 87 static constexpr gvr::Rectf kHeadlockedBufferFov = {20.f, 20.f, 20.f, 20.f}; |
| 88 |
| 89 // The GVR viewport list has two entries (left eye and right eye) for each |
| 90 // GVR buffer. |
| 91 static constexpr int kViewportListPrimaryOffset = 0; |
| 92 static constexpr int kViewportListHeadlockedOffset = 2; |
| 93 |
79 vr_shell::VrShell* g_instance; | 94 vr_shell::VrShell* g_instance; |
80 | 95 |
81 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; | 96 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; |
82 | 97 |
83 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { | 98 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { |
84 float xdiff = (vec1.x - vec2.x); | 99 float xdiff = (vec1.x - vec2.x); |
85 float ydiff = (vec1.y - vec2.y); | 100 float ydiff = (vec1.y - vec2.y); |
86 float zdiff = (vec1.z - vec2.z); | 101 float zdiff = (vec1.z - vec2.z); |
87 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; | 102 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; |
88 return std::sqrt(scale); | 103 return std::sqrt(scale); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 const JavaParamRef<jobject>& obj, | 230 const JavaParamRef<jobject>& obj, |
216 jlong native_gvr_api) { | 231 jlong native_gvr_api) { |
217 base::AutoLock lock(gvr_init_lock_); | 232 base::AutoLock lock(gvr_init_lock_); |
218 | 233 |
219 // set the initial webvr state | 234 // set the initial webvr state |
220 metrics_helper_->SetWebVREnabled(webvr_mode_); | 235 metrics_helper_->SetWebVREnabled(webvr_mode_); |
221 metrics_helper_->SetVRActive(true); | 236 metrics_helper_->SetVRActive(true); |
222 | 237 |
223 gvr_api_ = | 238 gvr_api_ = |
224 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); | 239 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); |
225 | 240 // TODO(klausw,crbug.com/655722): should report OnGvrDelegateReady here once |
226 if (delegate_) { | 241 // we switch to using a WebVR render surface. We currently need to wait for |
227 main_thread_task_runner_->PostTask( | 242 // the compositor window's size to be known first. See also |
228 FROM_HERE, base::Bind(&device::GvrDeviceProvider::OnGvrDelegateReady, | 243 // ContentSurfaceChanged. |
229 delegate_->GetDeviceProvider(), | |
230 weak_ptr_factory_.GetWeakPtr())); | |
231 } | |
232 controller_.reset( | 244 controller_.reset( |
233 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api))); | 245 new VrController(reinterpret_cast<gvr_context*>(native_gvr_api))); |
234 content_input_manager_ = new VrInputManager(main_contents_); | 246 content_input_manager_ = new VrInputManager(main_contents_); |
235 ui_input_manager_ = new VrInputManager(ui_contents_); | 247 ui_input_manager_ = new VrInputManager(ui_contents_); |
236 | 248 |
237 ViewerType viewerType; | 249 ViewerType viewerType; |
238 switch (gvr_api_->GetViewerType()) { | 250 switch (gvr_api_->GetViewerType()) { |
239 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM: | 251 case gvr::ViewerType::GVR_VIEWER_TYPE_DAYDREAM: |
240 viewerType = ViewerType::DAYDREAM; | 252 viewerType = ViewerType::DAYDREAM; |
241 break; | 253 break; |
(...skipping 12 matching lines...) Expand all Loading... |
254 void VrShell::InitializeGl(JNIEnv* env, | 266 void VrShell::InitializeGl(JNIEnv* env, |
255 const JavaParamRef<jobject>& obj, | 267 const JavaParamRef<jobject>& obj, |
256 jint content_texture_handle, | 268 jint content_texture_handle, |
257 jint ui_texture_handle) { | 269 jint ui_texture_handle) { |
258 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 270 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
259 gl::init::InitializeGLOneOff()); | 271 gl::init::InitializeGLOneOff()); |
260 | 272 |
261 content_texture_id_ = content_texture_handle; | 273 content_texture_id_ = content_texture_handle; |
262 ui_texture_id_ = ui_texture_handle; | 274 ui_texture_id_ = ui_texture_handle; |
263 | 275 |
| 276 // While WebVR is going through the compositor path, it shares |
| 277 // the same texture ID. This will change once it gets its own |
| 278 // surface, but store it separately to avoid future confusion. |
| 279 // TODO(klausw,crbug.com/655722): remove this. |
| 280 webvr_texture_id_ = content_texture_id_; |
| 281 |
264 gvr_api_->InitializeGl(); | 282 gvr_api_->InitializeGl(); |
265 std::vector<gvr::BufferSpec> specs; | 283 std::vector<gvr::BufferSpec> specs; |
| 284 // For kFramePrimaryBuffer (primary VrShell and WebVR content) |
266 specs.push_back(gvr_api_->CreateBufferSpec()); | 285 specs.push_back(gvr_api_->CreateBufferSpec()); |
267 render_size_ = specs[0].GetSize(); | 286 render_size_primary_ = specs[kFramePrimaryBuffer].GetSize(); |
| 287 render_size_primary_vrshell_ = render_size_primary_; |
268 | 288 |
269 // For WebVR content | 289 // For kFrameHeadlockedBuffer (for WebVR insecure content warning). |
| 290 // Set this up at fixed resolution, the (smaller) FOV gets set below. |
270 specs.push_back(gvr_api_->CreateBufferSpec()); | 291 specs.push_back(gvr_api_->CreateBufferSpec()); |
| 292 specs.back().SetSize(kHeadlockedBufferDimensions); |
| 293 render_size_headlocked_ = specs[kFrameHeadlockedBuffer].GetSize(); |
271 | 294 |
272 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); | 295 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); |
273 | 296 |
274 vr_shell_renderer_.reset(new VrShellRenderer()); | 297 vr_shell_renderer_.reset(new VrShellRenderer()); |
| 298 |
| 299 // Allocate a buffer viewport for use in UI drawing. This isn't |
| 300 // initialized at this point, it'll be set from other viewport list |
| 301 // entries as needed. |
| 302 buffer_viewport_.reset( |
| 303 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
| 304 |
| 305 // Set up main content viewports. The list has two elements, 0=left |
| 306 // eye and 1=right eye. |
275 buffer_viewport_list_.reset( | 307 buffer_viewport_list_.reset( |
276 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); | 308 new gvr::BufferViewportList(gvr_api_->CreateEmptyBufferViewportList())); |
277 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 309 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
278 | 310 |
279 buffer_viewport_.reset( | 311 // Set up head-locked UI viewports, these will be elements 2=left eye |
280 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 312 // and 3=right eye. For now, use a hardcoded 20-degree-from-center FOV |
281 | 313 // frustum to reduce rendering cost for this overlay. This fits the |
| 314 // current content, but will need to be adjusted once there's more dynamic |
| 315 // head-locked content that could be larger. |
282 headlocked_left_viewport_.reset( | 316 headlocked_left_viewport_.reset( |
283 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 317 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
284 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 318 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
285 headlocked_left_viewport_.get()); | 319 headlocked_left_viewport_.get()); |
286 headlocked_left_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); | 320 headlocked_left_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); |
287 headlocked_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 321 headlocked_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| 322 headlocked_left_viewport_->SetSourceFov(kHeadlockedBufferFov); |
288 | 323 |
289 headlocked_right_viewport_.reset( | 324 headlocked_right_viewport_.reset( |
290 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 325 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
291 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 326 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
292 headlocked_right_viewport_.get()); | 327 headlocked_right_viewport_.get()); |
293 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); | 328 headlocked_right_viewport_->SetSourceBufferIndex(kFrameHeadlockedBuffer); |
294 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 329 headlocked_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
| 330 headlocked_right_viewport_->SetSourceFov(kHeadlockedBufferFov); |
295 | 331 |
| 332 // Save copies of the first two viewport items for use by WebVR, it |
| 333 // sets its own UV bounds. |
296 webvr_left_viewport_.reset( | 334 webvr_left_viewport_.reset( |
297 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 335 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
298 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 336 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
299 webvr_left_viewport_.get()); | 337 webvr_left_viewport_.get()); |
300 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); | 338 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); |
301 | 339 |
302 webvr_right_viewport_.reset( | 340 webvr_right_viewport_.reset( |
303 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 341 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
304 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 342 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
305 webvr_right_viewport_.get()); | 343 webvr_right_viewport_.get()); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 // which tracks poses. | 537 // which tracks poses. |
500 uint8_t pixels[4]; | 538 uint8_t pixels[4]; |
501 // Assume we're reading from the framebuffer we just wrote to. | 539 // Assume we're reading from the framebuffer we just wrote to. |
502 // That's true currently, we may need to use glReadBuffer(GL_BACK) | 540 // That's true currently, we may need to use glReadBuffer(GL_BACK) |
503 // or equivalent if the rendering setup changes in the future. | 541 // or equivalent if the rendering setup changes in the future. |
504 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 542 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels); |
505 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); | 543 return pixels[0] | (pixels[1] << 8) | (pixels[2] << 16); |
506 } | 544 } |
507 | 545 |
508 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 546 void VrShell::DrawFrame(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 547 // Reset the viewport list to just the pair of viewports for the |
| 548 // primary buffer each frame. Head-locked viewports get added by |
| 549 // DrawVrShell if needed. |
509 buffer_viewport_list_->SetToRecommendedBufferViewports(); | 550 buffer_viewport_list_->SetToRecommendedBufferViewports(); |
510 | 551 |
| 552 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { |
| 553 // If needed, resize the primary buffer for use with WebVR. |
| 554 if (render_size_primary_ != render_size_primary_webvr_) { |
| 555 render_size_primary_ = render_size_primary_webvr_; |
| 556 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_); |
| 557 } |
| 558 } else { |
| 559 if (render_size_primary_ != render_size_primary_vrshell_) { |
| 560 render_size_primary_ = render_size_primary_vrshell_; |
| 561 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_); |
| 562 } |
| 563 } |
| 564 |
511 gvr::Frame frame = swap_chain_->AcquireFrame(); | 565 gvr::Frame frame = swap_chain_->AcquireFrame(); |
512 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 566 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
513 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 567 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
514 | 568 |
515 gvr::Mat4f head_pose = | 569 gvr::Mat4f head_pose = |
516 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); | 570 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); |
517 | 571 |
518 gvr::Vec3f position = GetTranslation(head_pose); | 572 gvr::Vec3f position = GetTranslation(head_pose); |
519 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { | 573 if (position.x == 0.0f && position.y == 0.0f && position.z == 0.0f) { |
520 // This appears to be a 3DOF pose without a neck model. Add one. | 574 // This appears to be a 3DOF pose without a neck model. Add one. |
(...skipping 16 matching lines...) Expand all Loading... |
537 UpdateController(GetForwardVector(head_pose)); | 591 UpdateController(GetForwardVector(head_pose)); |
538 | 592 |
539 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { | 593 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { |
540 DrawWebVr(); | 594 DrawWebVr(); |
541 | 595 |
542 // When using async reprojection, we need to know which pose was used in | 596 // When using async reprojection, we need to know which pose was used in |
543 // the WebVR app for drawing this frame. Due to unknown amounts of | 597 // the WebVR app for drawing this frame. Due to unknown amounts of |
544 // buffering in the compositor and SurfaceTexture, we read the pose number | 598 // buffering in the compositor and SurfaceTexture, we read the pose number |
545 // from a corner pixel. There's no point in doing this for legacy | 599 // from a corner pixel. There's no point in doing this for legacy |
546 // distortion rendering since that doesn't need a pose, and reading back | 600 // distortion rendering since that doesn't need a pose, and reading back |
547 // pixels is an expensive operation. TODO(klausw): stop doing this once we | 601 // pixels is an expensive operation. TODO(klausw,crbug.com/655722): stop |
548 // have working no-compositor rendering for WebVR. | 602 // doing this once we have working no-compositor rendering for WebVR. |
549 if (gvr_api_->GetAsyncReprojectionEnabled()) { | 603 if (gvr_api_->GetAsyncReprojectionEnabled()) { |
550 uint32_t webvr_pose_frame = GetPixelEncodedPoseIndex(); | 604 uint32_t webvr_pose_frame = GetPixelEncodedPoseIndex(); |
551 // If we don't get a valid frame ID back we shouldn't attempt to reproject | 605 // If we don't get a valid frame ID back we shouldn't attempt to reproject |
552 // by an invalid matrix, so turn of reprojection instead. | 606 // by an invalid matrix, so turn of reprojection instead. |
553 if (webvr_pose_frame == 0) { | 607 if (webvr_pose_frame == 0) { |
554 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 608 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
555 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); | 609 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_NONE); |
556 } else { | 610 } else { |
557 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_FULL); | 611 webvr_left_viewport_->SetReprojection(GVR_REPROJECTION_FULL); |
558 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_FULL); | 612 webvr_right_viewport_->SetReprojection(GVR_REPROJECTION_FULL); |
(...skipping 16 matching lines...) Expand all Loading... |
575 if (!rect->visible) { | 629 if (!rect->visible) { |
576 continue; | 630 continue; |
577 } | 631 } |
578 if (rect->lock_to_fov) { | 632 if (rect->lock_to_fov) { |
579 head_locked_elements.push_back(rect.get()); | 633 head_locked_elements.push_back(rect.get()); |
580 } else { | 634 } else { |
581 world_elements.push_back(rect.get()); | 635 world_elements.push_back(rect.get()); |
582 } | 636 } |
583 } | 637 } |
584 | 638 |
585 bool not_web_vr = html_interface_->GetMode() != UiInterface::Mode::WEB_VR; | 639 if (html_interface_->GetMode() == UiInterface::Mode::WEB_VR) { |
| 640 // WebVR is incompatible with 3D world compositing since the |
| 641 // depth buffer was already populated with unknown scaling - the |
| 642 // WebVR app has full control over zNear/zFar. Just leave the |
| 643 // existing content in place in the primary buffer without |
| 644 // clearing. Currently, there aren't any world elements in WebVR |
| 645 // mode, this will need further testing if those get added |
| 646 // later. |
| 647 } else { |
| 648 // Non-WebVR mode, enable depth testing and clear the primary buffers. |
| 649 glEnable(GL_CULL_FACE); |
| 650 glEnable(GL_DEPTH_TEST); |
| 651 glDepthMask(GL_TRUE); |
586 | 652 |
587 glEnable(GL_CULL_FACE); | |
588 glEnable(GL_DEPTH_TEST); | |
589 glDepthMask(GL_TRUE); | |
590 | |
591 if (not_web_vr) { | |
592 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); | 653 glClearColor(0.1f, 0.1f, 0.1f, 1.0f); |
593 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 654 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
594 } | 655 } |
595 | 656 |
596 DrawUiView(&head_pose, world_elements); | 657 if (!world_elements.empty()) { |
| 658 DrawUiView(&head_pose, world_elements, render_size_primary_, |
| 659 kViewportListPrimaryOffset); |
| 660 } |
597 | 661 |
598 if (!head_locked_elements.empty()) { | 662 if (!head_locked_elements.empty()) { |
599 // Switch to head-locked viewports. | 663 // Add head-locked viewports. The list gets reset to just |
600 size_t last_viewport = buffer_viewport_list_->GetSize(); | 664 // the recommended viewports (for the primary buffer) each frame. |
601 buffer_viewport_list_->SetBufferViewport(last_viewport++, | 665 buffer_viewport_list_->SetBufferViewport( |
| 666 kViewportListHeadlockedOffset + GVR_LEFT_EYE, |
602 *headlocked_left_viewport_); | 667 *headlocked_left_viewport_); |
603 buffer_viewport_list_->SetBufferViewport(last_viewport++, | 668 buffer_viewport_list_->SetBufferViewport( |
| 669 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, |
604 *headlocked_right_viewport_); | 670 *headlocked_right_viewport_); |
605 | 671 |
606 // Bind the headlocked framebuffer. | 672 // Bind the headlocked framebuffer. |
607 frame.BindBuffer(kFrameHeadlockedBuffer); | 673 frame.BindBuffer(kFrameHeadlockedBuffer); |
608 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 674 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
609 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 675 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
610 DrawUiView(nullptr, head_locked_elements); | 676 DrawUiView(nullptr, head_locked_elements, render_size_headlocked_, |
| 677 kViewportListHeadlockedOffset); |
611 } | 678 } |
612 } | 679 } |
613 | 680 |
| 681 void VrShell::SetWebVRRenderSurfaceSize(int width, int height) { |
| 682 render_size_primary_webvr_.width = width; |
| 683 render_size_primary_webvr_.height = height; |
| 684 // TODO(klausw,crbug.com/655722): set the WebVR render surface size here once |
| 685 // we have that. |
| 686 } |
| 687 |
| 688 gvr::Sizei VrShell::GetWebVRCompositorSurfaceSize() { |
| 689 // This is a stopgap while we're using the WebVR compositor rendering path. |
| 690 // TODO(klausw,crbug.com/655722): Remove this method and member once we're |
| 691 // using a separate WebVR render surface. |
| 692 return content_tex_pixels_for_webvr_; |
| 693 } |
| 694 |
| 695 |
614 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, | 696 void VrShell::DrawUiView(const gvr::Mat4f* head_pose, |
615 const std::vector<const ContentRectangle*>& elements) { | 697 const std::vector<const ContentRectangle*>& elements, |
| 698 const gvr::Sizei& render_size, int viewport_offset) { |
616 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { | 699 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { |
617 buffer_viewport_list_->GetBufferViewport(eye, buffer_viewport_.get()); | 700 buffer_viewport_list_->GetBufferViewport( |
| 701 eye + viewport_offset, buffer_viewport_.get()); |
618 | 702 |
619 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); | 703 gvr::Mat4f view_matrix = gvr_api_->GetEyeFromHeadMatrix(eye); |
620 if (head_pose != nullptr) { | 704 if (head_pose != nullptr) { |
621 view_matrix = MatrixMul(view_matrix, *head_pose); | 705 view_matrix = MatrixMul(view_matrix, *head_pose); |
622 } | 706 } |
623 | 707 |
624 gvr::Recti pixel_rect = | 708 gvr::Recti pixel_rect = |
625 CalculatePixelSpaceRect(render_size_, buffer_viewport_->GetSourceUv()); | 709 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv()); |
626 glViewport(pixel_rect.left, pixel_rect.bottom, | 710 glViewport(pixel_rect.left, pixel_rect.bottom, |
627 pixel_rect.right - pixel_rect.left, | 711 pixel_rect.right - pixel_rect.left, |
628 pixel_rect.top - pixel_rect.bottom); | 712 pixel_rect.top - pixel_rect.bottom); |
629 | 713 |
630 const gvr::Mat4f render_matrix = MatrixMul( | 714 const gvr::Mat4f render_matrix = MatrixMul( |
631 PerspectiveMatrixFromView( | 715 PerspectiveMatrixFromView( |
632 buffer_viewport_->GetSourceFov(), kZNear, kZFar), | 716 buffer_viewport_->GetSourceFov(), kZNear, kZFar), |
633 view_matrix); | 717 view_matrix); |
634 | 718 |
635 DrawElements(render_matrix, elements); | 719 DrawElements(render_matrix, elements); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 | 824 |
741 void VrShell::DrawWebVr() { | 825 void VrShell::DrawWebVr() { |
742 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 826 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
743 glDisable(GL_CULL_FACE); | 827 glDisable(GL_CULL_FACE); |
744 glDepthMask(GL_FALSE); | 828 glDepthMask(GL_FALSE); |
745 glDisable(GL_DEPTH_TEST); | 829 glDisable(GL_DEPTH_TEST); |
746 glDisable(GL_SCISSOR_TEST); | 830 glDisable(GL_SCISSOR_TEST); |
747 glDisable(GL_BLEND); | 831 glDisable(GL_BLEND); |
748 glDisable(GL_POLYGON_OFFSET_FILL); | 832 glDisable(GL_POLYGON_OFFSET_FILL); |
749 | 833 |
750 glViewport(0, 0, render_size_.width, render_size_.height); | 834 glViewport(0, 0, render_size_primary_.width, render_size_primary_.height); |
751 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 835 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_); |
752 | 836 |
753 buffer_viewport_list_->SetBufferViewport(0, *webvr_left_viewport_); | 837 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE, |
754 buffer_viewport_list_->SetBufferViewport(1, *webvr_right_viewport_); | 838 *webvr_left_viewport_); |
| 839 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE, |
| 840 *webvr_right_viewport_); |
755 } | 841 } |
756 | 842 |
757 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 843 void VrShell::OnTriggerEvent(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
758 // Set a flag to handle this on the render thread at the next frame. | 844 // Set a flag to handle this on the render thread at the next frame. |
759 touch_pending_ = true; | 845 touch_pending_ = true; |
760 } | 846 } |
761 | 847 |
762 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 848 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
763 if (gvr_api_ == nullptr) | 849 if (gvr_api_ == nullptr) |
764 return; | 850 return; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 | 909 |
824 gvr::GvrApi* VrShell::gvr_api() { | 910 gvr::GvrApi* VrShell::gvr_api() { |
825 return gvr_api_.get(); | 911 return gvr_api_.get(); |
826 } | 912 } |
827 | 913 |
828 void VrShell::ContentSurfaceChanged(JNIEnv* env, | 914 void VrShell::ContentSurfaceChanged(JNIEnv* env, |
829 const JavaParamRef<jobject>& object, | 915 const JavaParamRef<jobject>& object, |
830 jint width, | 916 jint width, |
831 jint height, | 917 jint height, |
832 const JavaParamRef<jobject>& surface) { | 918 const JavaParamRef<jobject>& surface) { |
| 919 // If we have a delegate, must trigger "ready" callback one time only. |
| 920 // Do so the first time we got a nonzero size. (This assumes it doesn't |
| 921 // change, but once we get resize ability we'll no longer need this hack.) |
| 922 // TODO(klausw,crbug.com/655722): remove when we have surface support. |
| 923 bool delegate_not_ready = delegate_ && !content_tex_pixels_for_webvr_.width; |
| 924 |
833 content_compositor_->SurfaceChanged((int)width, (int)height, surface); | 925 content_compositor_->SurfaceChanged((int)width, (int)height, surface); |
| 926 content_tex_pixels_for_webvr_.width = width; |
| 927 content_tex_pixels_for_webvr_.height = height; |
834 float scale_factor = display::Screen::GetScreen() | 928 float scale_factor = display::Screen::GetScreen() |
835 ->GetPrimaryDisplay().device_scale_factor(); | 929 ->GetPrimaryDisplay().device_scale_factor(); |
836 content_tex_width_ = width / scale_factor; | 930 content_tex_width_ = width / scale_factor; |
837 content_tex_height_ = height / scale_factor; | 931 content_tex_height_ = height / scale_factor; |
| 932 |
| 933 // TODO(klausw,crbug.com/655722): move this back to GvrInit once we have |
| 934 // our own WebVR surface. |
| 935 if (delegate_ && delegate_not_ready) { |
| 936 main_thread_task_runner_->PostTask( |
| 937 FROM_HERE, base::Bind(&device::GvrDeviceProvider::OnGvrDelegateReady, |
| 938 delegate_->GetDeviceProvider(), |
| 939 weak_ptr_factory_.GetWeakPtr())); |
| 940 } |
838 } | 941 } |
839 | 942 |
840 void VrShell::UiSurfaceChanged(JNIEnv* env, | 943 void VrShell::UiSurfaceChanged(JNIEnv* env, |
841 const JavaParamRef<jobject>& object, | 944 const JavaParamRef<jobject>& object, |
842 jint width, | 945 jint width, |
843 jint height, | 946 jint height, |
844 const JavaParamRef<jobject>& surface) { | 947 const JavaParamRef<jobject>& surface) { |
845 ui_compositor_->SurfaceChanged((int)width, (int)height, surface); | 948 ui_compositor_->SurfaceChanged((int)width, (int)height, surface); |
846 float scale_factor = display::Screen::GetScreen() | 949 float scale_factor = display::Screen::GetScreen() |
847 ->GetPrimaryDisplay().device_scale_factor(); | 950 ->GetPrimaryDisplay().device_scale_factor(); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 const JavaParamRef<jobject>& ui_web_contents, | 1028 const JavaParamRef<jobject>& ui_web_contents, |
926 jlong ui_window_android) { | 1029 jlong ui_window_android) { |
927 return reinterpret_cast<intptr_t>(new VrShell( | 1030 return reinterpret_cast<intptr_t>(new VrShell( |
928 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), | 1031 env, obj, content::WebContents::FromJavaWebContents(content_web_contents), |
929 reinterpret_cast<ui::WindowAndroid*>(content_window_android), | 1032 reinterpret_cast<ui::WindowAndroid*>(content_window_android), |
930 content::WebContents::FromJavaWebContents(ui_web_contents), | 1033 content::WebContents::FromJavaWebContents(ui_web_contents), |
931 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 1034 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
932 } | 1035 } |
933 | 1036 |
934 } // namespace vr_shell | 1037 } // namespace vr_shell |
OLD | NEW |