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/non_presenting_gvr_delegate.h" | 5 #include "chrome/browser/android/vr_shell/non_presenting_gvr_delegate.h" |
6 | 6 |
| 7 #include "base/callback_helpers.h" |
7 #include "chrome/browser/android/vr_shell/vr_shell.h" | 8 #include "chrome/browser/android/vr_shell/vr_shell.h" |
8 | 9 |
9 namespace vr_shell { | 10 namespace vr_shell { |
10 | 11 |
11 namespace { | 12 namespace { |
12 static constexpr long kPredictionTimeWithoutVsyncNanos = 50000000; | 13 static constexpr long kPredictionTimeWithoutVsyncNanos = 50000000; |
13 } // namespace | 14 } // namespace |
14 | 15 |
15 NonPresentingGvrDelegate::NonPresentingGvrDelegate(long context) | 16 NonPresentingGvrDelegate::NonPresentingGvrDelegate(long context) |
16 : task_runner_(base::ThreadTaskRunnerHandle::Get()), | 17 : task_runner_(base::ThreadTaskRunnerHandle::Get()), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 device::mojom::VRVSyncProviderRequest | 58 device::mojom::VRVSyncProviderRequest |
58 NonPresentingGvrDelegate::OnSwitchToPresentingDelegate() { | 59 NonPresentingGvrDelegate::OnSwitchToPresentingDelegate() { |
59 StopVSyncLoop(); | 60 StopVSyncLoop(); |
60 if (binding_.is_bound()) | 61 if (binding_.is_bound()) |
61 return binding_.Unbind(); | 62 return binding_.Unbind(); |
62 return nullptr; | 63 return nullptr; |
63 } | 64 } |
64 | 65 |
65 void NonPresentingGvrDelegate::StopVSyncLoop() { | 66 void NonPresentingGvrDelegate::StopVSyncLoop() { |
66 vsync_task_.Cancel(); | 67 vsync_task_.Cancel(); |
67 if (!callback_.is_null()) | 68 if (!callback_.is_null()) { |
68 callback_.Run(nullptr, base::TimeDelta()); | 69 base::ResetAndReturn(&callback_).Run(nullptr, base::TimeDelta(), -1); |
69 callback_.Reset(); | 70 } |
70 gvr_api_->PauseTracking(); | 71 gvr_api_->PauseTracking(); |
71 // If the loop is stopped, it's not considered to be paused. | 72 // If the loop is stopped, it's not considered to be paused. |
72 vsync_paused_ = false; | 73 vsync_paused_ = false; |
73 } | 74 } |
74 | 75 |
75 void NonPresentingGvrDelegate::StartVSyncLoop() { | 76 void NonPresentingGvrDelegate::StartVSyncLoop() { |
76 vsync_task_.Reset( | 77 vsync_task_.Reset( |
77 base::Bind(&NonPresentingGvrDelegate::OnVSync, base::Unretained(this))); | 78 base::Bind(&NonPresentingGvrDelegate::OnVSync, base::Unretained(this))); |
78 gvr_api_->RefreshViewerProfile(); | 79 gvr_api_->RefreshViewerProfile(); |
79 gvr_api_->ResumeTracking(); | 80 gvr_api_->ResumeTracking(); |
(...skipping 15 matching lines...) Expand all Loading... |
95 target = now + vsync_interval_; | 96 target = now + vsync_interval_; |
96 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; | 97 int64_t intervals = (target - vsync_timebase_) / vsync_interval_; |
97 target = vsync_timebase_ + intervals * vsync_interval_; | 98 target = vsync_timebase_ + intervals * vsync_interval_; |
98 if (!vsync_task_.IsCancelled()) { | 99 if (!vsync_task_.IsCancelled()) { |
99 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), | 100 task_runner_->PostDelayedTask(FROM_HERE, vsync_task_.callback(), |
100 target - now); | 101 target - now); |
101 } | 102 } |
102 | 103 |
103 base::TimeDelta time = intervals * vsync_interval_; | 104 base::TimeDelta time = intervals * vsync_interval_; |
104 if (!callback_.is_null()) { | 105 if (!callback_.is_null()) { |
105 callback_.Run(GetPose(), time); | 106 SendVSync(time, base::ResetAndReturn(&callback_)); |
106 callback_.Reset(); | |
107 } else { | 107 } else { |
108 pending_vsync_ = true; | 108 pending_vsync_ = true; |
109 pending_time_ = time; | 109 pending_time_ = time; |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 void NonPresentingGvrDelegate::GetVSync(const GetVSyncCallback& callback) { | 113 void NonPresentingGvrDelegate::GetVSync(const GetVSyncCallback& callback) { |
114 if (!pending_vsync_) { | 114 if (!pending_vsync_) { |
115 if (!callback_.is_null()) { | 115 if (!callback_.is_null()) { |
116 mojo::ReportBadMessage("Requested VSync before waiting for response to " | 116 mojo::ReportBadMessage("Requested VSync before waiting for response to " |
117 "previous request."); | 117 "previous request."); |
118 return; | 118 return; |
119 } | 119 } |
120 callback_ = callback; | 120 callback_ = callback; |
121 return; | 121 return; |
122 } | 122 } |
123 pending_vsync_ = false; | 123 pending_vsync_ = false; |
124 callback.Run(GetPose(), pending_time_); | 124 SendVSync(pending_time_, callback); |
125 } | 125 } |
126 | 126 |
127 void NonPresentingGvrDelegate::UpdateVSyncInterval(long timebase_nanos, | 127 void NonPresentingGvrDelegate::UpdateVSyncInterval(long timebase_nanos, |
128 double interval_seconds) { | 128 double interval_seconds) { |
129 vsync_timebase_ = base::TimeTicks(); | 129 vsync_timebase_ = base::TimeTicks(); |
130 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); | 130 vsync_timebase_ += base::TimeDelta::FromMicroseconds(timebase_nanos / 1000); |
131 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); | 131 vsync_interval_ = base::TimeDelta::FromSecondsD(interval_seconds); |
132 StartVSyncLoop(); | 132 StartVSyncLoop(); |
133 } | 133 } |
134 | 134 |
135 device::mojom::VRPosePtr NonPresentingGvrDelegate::GetPose() { | 135 void NonPresentingGvrDelegate::SendVSync(base::TimeDelta time, |
| 136 const GetVSyncCallback& callback) { |
136 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 137 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
137 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 138 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
138 | 139 |
139 gvr::Mat4f head_mat = | 140 gvr::Mat4f head_mat = gvr_api_->ApplyNeckModel( |
140 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time); | 141 gvr_api_->GetHeadSpaceFromStartSpaceRotation(target_time), 1.0f); |
141 head_mat = gvr_api_->ApplyNeckModel(head_mat, 1.0f); | 142 callback.Run(VrShell::VRPosePtrFromGvrPose(head_mat), time, -1); |
142 | |
143 uint32_t pose_index = pose_index_++; | |
144 | |
145 return VrShell::VRPosePtrFromGvrPose(head_mat, pose_index); | |
146 } | 143 } |
147 | 144 |
148 } // namespace vr_shell | 145 } // namespace vr_shell |
OLD | NEW |