| 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_gl.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" |
| 6 | 6 |
| 7 #include <chrono> | 7 #include <chrono> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/android/jni_android.h" | 11 #include "base/android/jni_android.h" |
| 12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "chrome/browser/android/vr_shell/fps_meter.h" | 16 #include "chrome/browser/android/vr_shell/fps_meter.h" |
| 17 #include "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h" | 17 #include "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h" |
| 18 #include "chrome/browser/android/vr_shell/ui_elements/ui_element.h" | 18 #include "chrome/browser/android/vr_shell/ui_elements/ui_element.h" |
| 19 #include "chrome/browser/android/vr_shell/ui_interface.h" | 19 #include "chrome/browser/android/vr_shell/ui_interface.h" |
| 20 #include "chrome/browser/android/vr_shell/ui_scene.h" | 20 #include "chrome/browser/android/vr_shell/ui_scene.h" |
| 21 #include "chrome/browser/android/vr_shell/ui_scene_manager.h" | 21 #include "chrome/browser/android/vr_shell/ui_scene_manager.h" |
| 22 #include "chrome/browser/android/vr_shell/vr_controller.h" | 22 #include "chrome/browser/android/vr_shell/vr_controller.h" |
| 23 #include "chrome/browser/android/vr_shell/vr_gl_thread.h" |
| 23 #include "chrome/browser/android/vr_shell/vr_gl_util.h" | 24 #include "chrome/browser/android/vr_shell/vr_gl_util.h" |
| 24 #include "chrome/browser/android/vr_shell/vr_shell.h" | 25 #include "chrome/browser/android/vr_shell/vr_shell.h" |
| 25 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" | 26 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
| 26 #include "device/vr/android/gvr/gvr_delegate.h" | 27 #include "device/vr/android/gvr/gvr_delegate.h" |
| 27 #include "device/vr/android/gvr/gvr_device.h" | 28 #include "device/vr/android/gvr/gvr_device.h" |
| 28 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" | 29 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" |
| 29 #include "device/vr/vr_math.h" | 30 #include "device/vr/vr_math.h" |
| 30 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 31 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
| 31 #include "third_party/WebKit/public/platform/WebMouseEvent.h" | 32 #include "third_party/WebKit/public/platform/WebMouseEvent.h" |
| 32 #include "ui/gl/android/scoped_java_surface.h" | 33 #include "ui/gl/android/scoped_java_surface.h" |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 1.0f - rect.y()}; | 184 1.0f - rect.y()}; |
| 184 } | 185 } |
| 185 | 186 |
| 186 gfx::RectF GfxRectFromUV(gvr::Rectf rect) { | 187 gfx::RectF GfxRectFromUV(gvr::Rectf rect) { |
| 187 return gfx::RectF(rect.left, 1.0 - rect.top, rect.right - rect.left, | 188 return gfx::RectF(rect.left, 1.0 - rect.top, rect.right - rect.left, |
| 188 rect.top - rect.bottom); | 189 rect.top - rect.bottom); |
| 189 } | 190 } |
| 190 | 191 |
| 191 } // namespace | 192 } // namespace |
| 192 | 193 |
| 193 VrShellGl::VrShellGl( | 194 VrShellGl::VrShellGl(const base::WeakPtr<VrGLThread>& weak_vr_gl_thread, |
| 194 const base::WeakPtr<VrShell>& weak_vr_shell, | 195 gvr_context* gvr_api, |
| 195 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, | 196 bool initially_web_vr, |
| 196 gvr_context* gvr_api, | 197 bool reprojected_rendering, |
| 197 bool initially_web_vr, | 198 UiScene* scene) |
| 198 bool reprojected_rendering, | |
| 199 UiScene* scene) | |
| 200 : web_vr_mode_(initially_web_vr), | 199 : web_vr_mode_(initially_web_vr), |
| 201 surfaceless_rendering_(reprojected_rendering), | 200 surfaceless_rendering_(reprojected_rendering), |
| 202 task_runner_(base::ThreadTaskRunnerHandle::Get()), | 201 task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| 203 binding_(this), | 202 binding_(this), |
| 204 weak_vr_shell_(weak_vr_shell), | 203 weak_vr_gl_thread_(weak_vr_gl_thread), |
| 205 main_thread_task_runner_(std::move(main_thread_task_runner)), | |
| 206 scene_(scene), | 204 scene_(scene), |
| 207 #if DCHECK_IS_ON() | 205 #if DCHECK_IS_ON() |
| 208 fps_meter_(new FPSMeter()), | 206 fps_meter_(new FPSMeter()), |
| 209 #endif | 207 #endif |
| 210 weak_ptr_factory_(this) { | 208 weak_ptr_factory_(this) { |
| 211 GvrInit(gvr_api); | 209 GvrInit(gvr_api); |
| 212 } | 210 } |
| 213 | 211 |
| 214 VrShellGl::~VrShellGl() { | 212 VrShellGl::~VrShellGl() { |
| 215 vsync_task_.Cancel(); | 213 vsync_task_.Cancel(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 296 |
| 299 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); | 297 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); |
| 300 OnVSync(); | 298 OnVSync(); |
| 301 | 299 |
| 302 ready_to_draw_ = true; | 300 ready_to_draw_ = true; |
| 303 } | 301 } |
| 304 | 302 |
| 305 void VrShellGl::CreateContentSurface() { | 303 void VrShellGl::CreateContentSurface() { |
| 306 content_surface_ = | 304 content_surface_ = |
| 307 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get()); | 305 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get()); |
| 308 main_thread_task_runner_->PostTask( | 306 weak_vr_gl_thread_->PostTaskToMainThreadShell( |
| 309 FROM_HERE, base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_, | 307 &VrShell::ContentSurfaceChanged, content_surface_->j_surface().obj()); |
| 310 content_surface_->j_surface().obj())); | |
| 311 } | 308 } |
| 312 | 309 |
| 313 void VrShellGl::CreateOrResizeWebVRSurface(const gfx::Size& size) { | 310 void VrShellGl::CreateOrResizeWebVRSurface(const gfx::Size& size) { |
| 314 if (!webvr_surface_texture_) { | 311 if (!webvr_surface_texture_) { |
| 315 DLOG(ERROR) << "No WebVR surface texture available"; | 312 DLOG(ERROR) << "No WebVR surface texture available"; |
| 316 return; | 313 return; |
| 317 } | 314 } |
| 318 | 315 |
| 319 // ContentPhysicalBoundsChanged is getting called twice with | 316 // ContentPhysicalBoundsChanged is getting called twice with |
| 320 // identical sizes? Avoid thrashing the existing context. | 317 // identical sizes? Avoid thrashing the existing context. |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | 493 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
| 497 webvr_left_viewport_.get()); | 494 webvr_left_viewport_.get()); |
| 498 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); | 495 webvr_left_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); |
| 499 | 496 |
| 500 webvr_right_viewport_.reset( | 497 webvr_right_viewport_.reset( |
| 501 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 498 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
| 502 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | 499 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
| 503 webvr_right_viewport_.get()); | 500 webvr_right_viewport_.get()); |
| 504 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); | 501 webvr_right_viewport_->SetSourceBufferIndex(kFramePrimaryBuffer); |
| 505 | 502 |
| 506 main_thread_task_runner_->PostTask( | 503 weak_vr_gl_thread_->PostTaskToMainThreadShell(&VrShell::GvrDelegateReady); |
| 507 FROM_HERE, base::Bind(&VrShell::GvrDelegateReady, weak_vr_shell_)); | |
| 508 } | 504 } |
| 509 | 505 |
| 510 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) { | 506 void VrShellGl::UpdateController(const gfx::Vector3dF& head_direction) { |
| 511 controller_->UpdateState(head_direction); | 507 controller_->UpdateState(head_direction); |
| 512 pointer_start_ = controller_->GetPointerStart(); | 508 pointer_start_ = controller_->GetPointerStart(); |
| 513 | 509 |
| 514 device::GvrGamepadData pad = controller_->GetGamepadData(); | 510 device::GvrGamepadData pad = controller_->GetGamepadData(); |
| 515 main_thread_task_runner_->PostTask( | 511 weak_vr_gl_thread_->PostTaskToMainThreadShell(&VrShell::UpdateGamepadData, |
| 516 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); | 512 pad); |
| 517 } | 513 } |
| 518 | 514 |
| 519 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) { | 515 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& head_direction) { |
| 520 if (ShouldDrawWebVr()) { | 516 if (ShouldDrawWebVr()) { |
| 521 // Process screen touch events for Cardboard button compatibility. | 517 // Process screen touch events for Cardboard button compatibility. |
| 522 // Also send tap events for controller "touchpad click" events. | 518 // Also send tap events for controller "touchpad click" events. |
| 523 if (touch_pending_ || | 519 if (touch_pending_ || |
| 524 controller_->ButtonUpHappened( | 520 controller_->ButtonUpHappened( |
| 525 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { | 521 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { |
| 526 touch_pending_ = false; | 522 touch_pending_ = false; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 646 // considered a regular click | 642 // considered a regular click |
| 647 // TODO(asimjour1): We need to refactor the gesture recognition outside of | 643 // TODO(asimjour1): We need to refactor the gesture recognition outside of |
| 648 // VrShellGl. | 644 // VrShellGl. |
| 649 UiInterface::Direction direction = UiInterface::NONE; | 645 UiInterface::Direction direction = UiInterface::NONE; |
| 650 float gesture_xz_angle; | 646 float gesture_xz_angle; |
| 651 if (vr::XZAngle(controller_start_direction_, controller_direction, | 647 if (vr::XZAngle(controller_start_direction_, controller_direction, |
| 652 &gesture_xz_angle)) { | 648 &gesture_xz_angle)) { |
| 653 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { | 649 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { |
| 654 direction = | 650 direction = |
| 655 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; | 651 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; |
| 656 main_thread_task_runner_->PostTask( | 652 weak_vr_gl_thread_->PostTaskToMainThreadShell( |
| 657 FROM_HERE, base::Bind(&VrShell::AppButtonGesturePerformed, | 653 &VrShell::AppButtonGesturePerformed, direction); |
| 658 weak_vr_shell_, direction)); | |
| 659 } | 654 } |
| 660 } | 655 } |
| 661 if (direction == UiInterface::NONE) { | 656 if (direction == UiInterface::NONE) { |
| 662 main_thread_task_runner_->PostTask( | 657 task_runner_->PostTask(FROM_HERE, |
| 663 FROM_HERE, base::Bind(&VrShell::AppButtonPressed, weak_vr_shell_)); | 658 base::Bind(&UiSceneManager::AppButtonPressed, |
| 659 weak_vr_gl_thread_->GetSceneManager())); |
| 664 } | 660 } |
| 665 } | 661 } |
| 666 } | 662 } |
| 667 | 663 |
| 668 void VrShellGl::SendInputToContent(InputTarget input_target, | 664 void VrShellGl::SendInputToContent(InputTarget input_target, |
| 669 int pixel_x, | 665 int pixel_x, |
| 670 int pixel_y) { | 666 int pixel_y) { |
| 671 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = | 667 std::vector<std::unique_ptr<WebGestureEvent>> gesture_list = |
| 672 controller_->DetectGestures(); | 668 controller_->DetectGestures(); |
| 673 double timestamp = gesture_list.front()->TimeStampSeconds(); | 669 double timestamp = gesture_list.front()->TimeStampSeconds(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 base::Bind(&UiElement::OnButtonUp, | 775 base::Bind(&UiElement::OnButtonUp, |
| 780 base::Unretained(target_element))); | 776 base::Unretained(target_element))); |
| 781 } | 777 } |
| 782 click_target_element_ = nullptr; | 778 click_target_element_ = nullptr; |
| 783 } | 779 } |
| 784 } | 780 } |
| 785 } | 781 } |
| 786 | 782 |
| 787 void VrShellGl::SendGestureToContent( | 783 void VrShellGl::SendGestureToContent( |
| 788 std::unique_ptr<blink::WebInputEvent> event) { | 784 std::unique_ptr<blink::WebInputEvent> event) { |
| 789 main_thread_task_runner_->PostTask( | 785 weak_vr_gl_thread_->PostTaskToMainThreadShell(&VrShell::ProcessContentGesture, |
| 790 FROM_HERE, base::Bind(&VrShell::ProcessContentGesture, weak_vr_shell_, | 786 base::Passed(std::move(event))); |
| 791 base::Passed(std::move(event)))); | |
| 792 } | 787 } |
| 793 | 788 |
| 794 void VrShellGl::DrawFrame(int16_t frame_index) { | 789 void VrShellGl::DrawFrame(int16_t frame_index) { |
| 795 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); | 790 TRACE_EVENT1("gpu", "VrShellGl::DrawFrame", "frame", frame_index); |
| 796 | 791 |
| 797 base::TimeTicks current_time = base::TimeTicks::Now(); | 792 base::TimeTicks current_time = base::TimeTicks::Now(); |
| 798 | 793 |
| 799 // Reset the viewport list to just the pair of viewports for the | 794 // Reset the viewport list to just the pair of viewports for the |
| 800 // primary buffer each frame. Head-locked viewports get added by | 795 // primary buffer each frame. Head-locked viewports get added by |
| 801 // DrawVrShell if needed. | 796 // DrawVrShell if needed. |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 void VrShellGl::UpdateVSyncInterval(int64_t timebase_nanos, | 1318 void VrShellGl::UpdateVSyncInterval(int64_t timebase_nanos, |
| 1324 double interval_seconds) { | 1319 double interval_seconds) { |
| 1325 vsync_timebase_ = base::TimeTicks(); | 1320 vsync_timebase_ = base::TimeTicks(); |
| 1326 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); | 1321 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); |
| 1327 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); | 1322 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); |
| 1328 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); | 1323 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); |
| 1329 OnVSync(); | 1324 OnVSync(); |
| 1330 } | 1325 } |
| 1331 | 1326 |
| 1332 void VrShellGl::ForceExitVr() { | 1327 void VrShellGl::ForceExitVr() { |
| 1333 main_thread_task_runner_->PostTask( | 1328 weak_vr_gl_thread_->PostTaskToMainThreadShell(&VrShell::ForceExitVr); |
| 1334 FROM_HERE, base::Bind(&VrShell::ForceExitVr, weak_vr_shell_)); | |
| 1335 } | 1329 } |
| 1336 | 1330 |
| 1337 void VrShellGl::SendVSync(base::TimeDelta time, | 1331 void VrShellGl::SendVSync(base::TimeDelta time, |
| 1338 const GetVSyncCallback& callback) { | 1332 const GetVSyncCallback& callback) { |
| 1339 uint8_t frame_index = frame_index_++; | 1333 uint8_t frame_index = frame_index_++; |
| 1340 | 1334 |
| 1341 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); | 1335 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); |
| 1342 | 1336 |
| 1343 vr::Mat4f head_mat; | 1337 vr::Mat4f head_mat; |
| 1344 device::mojom::VRPosePtr pose = | 1338 device::mojom::VRPosePtr pose = |
| 1345 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat); | 1339 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat); |
| 1346 | 1340 |
| 1347 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; | 1341 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; |
| 1348 | 1342 |
| 1349 callback.Run(std::move(pose), time, frame_index, | 1343 callback.Run(std::move(pose), time, frame_index, |
| 1350 device::mojom::VRVSyncProvider::Status::SUCCESS); | 1344 device::mojom::VRVSyncProvider::Status::SUCCESS); |
| 1351 } | 1345 } |
| 1352 | 1346 |
| 1353 void VrShellGl::CreateVRDisplayInfo( | 1347 void VrShellGl::CreateVRDisplayInfo( |
| 1354 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, | 1348 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, |
| 1355 uint32_t device_id) { | 1349 uint32_t device_id) { |
| 1356 // This assumes that the initial webvr_surface_size_ was set to the | 1350 // This assumes that the initial webvr_surface_size_ was set to the |
| 1357 // appropriate recommended render resolution as the default size during | 1351 // appropriate recommended render resolution as the default size during |
| 1358 // InitializeGl. Revisit if the initialization order changes. | 1352 // InitializeGl. Revisit if the initialization order changes. |
| 1359 device::mojom::VRDisplayInfoPtr info = | 1353 device::mojom::VRDisplayInfoPtr info = |
| 1360 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), | 1354 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), |
| 1361 webvr_surface_size_, device_id); | 1355 webvr_surface_size_, device_id); |
| 1362 main_thread_task_runner_->PostTask( | 1356 weak_vr_gl_thread_->PostTaskToMainThread(&RunVRDisplayInfoCallback, callback, |
| 1363 FROM_HERE, | 1357 base::Passed(&info)); |
| 1364 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | |
| 1365 } | 1358 } |
| 1366 | 1359 |
| 1367 } // namespace vr_shell | 1360 } // namespace vr_shell |
| OLD | NEW |