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/mailbox_to_surface_bridge.h" | 16 #include "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h" |
17 #include "chrome/browser/android/vr_shell/ui_elements.h" | 17 #include "chrome/browser/android/vr_shell/ui_elements.h" |
18 #include "chrome/browser/android/vr_shell/ui_interface.h" | 18 #include "chrome/browser/android/vr_shell/ui_interface.h" |
19 #include "chrome/browser/android/vr_shell/ui_scene.h" | 19 #include "chrome/browser/android/vr_shell/ui_scene.h" |
20 #include "chrome/browser/android/vr_shell/vr_controller.h" | 20 #include "chrome/browser/android/vr_shell/vr_controller.h" |
21 #include "chrome/browser/android/vr_shell/vr_gl_util.h" | 21 #include "chrome/browser/android/vr_shell/vr_gl_util.h" |
22 #include "chrome/browser/android/vr_shell/vr_math.h" | |
23 #include "chrome/browser/android/vr_shell/vr_shell.h" | 22 #include "chrome/browser/android/vr_shell/vr_shell.h" |
24 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" | 23 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
25 #include "device/vr/android/gvr/gvr_delegate.h" | 24 #include "device/vr/android/gvr/gvr_delegate.h" |
26 #include "device/vr/android/gvr/gvr_device.h" | 25 #include "device/vr/android/gvr/gvr_device.h" |
27 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" | 26 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h" |
| 27 #include "device/vr/vr_math.h" |
28 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 28 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
29 #include "third_party/WebKit/public/platform/WebMouseEvent.h" | 29 #include "third_party/WebKit/public/platform/WebMouseEvent.h" |
30 #include "ui/gl/android/scoped_java_surface.h" | 30 #include "ui/gl/android/scoped_java_surface.h" |
31 #include "ui/gl/android/surface_texture.h" | 31 #include "ui/gl/android/surface_texture.h" |
32 #include "ui/gl/gl_bindings.h" | 32 #include "ui/gl/gl_bindings.h" |
33 #include "ui/gl/gl_context.h" | 33 #include "ui/gl/gl_context.h" |
34 #include "ui/gl/gl_surface.h" | 34 #include "ui/gl/gl_surface.h" |
35 #include "ui/gl/init/gl_factory.h" | 35 #include "ui/gl/init/gl_factory.h" |
36 | 36 |
37 namespace vr_shell { | 37 namespace vr_shell { |
38 | 38 |
39 namespace { | 39 namespace { |
40 static constexpr float kZNear = 0.1f; | 40 static constexpr float kZNear = 0.1f; |
41 static constexpr float kZFar = 1000.0f; | 41 static constexpr float kZFar = 1000.0f; |
42 | 42 |
43 static constexpr float kReticleWidth = 0.025f; | 43 static constexpr float kReticleWidth = 0.025f; |
44 static constexpr float kReticleHeight = 0.025f; | 44 static constexpr float kReticleHeight = 0.025f; |
45 | 45 |
46 static constexpr float kLaserWidth = 0.01f; | 46 static constexpr float kLaserWidth = 0.01f; |
47 | 47 |
48 // Angle (radians) the beam down from the controller axis, for wrist comfort. | 48 // Angle (radians) the beam down from the controller axis, for wrist comfort. |
49 static constexpr float kErgoAngleOffset = 0.26f; | 49 static constexpr float kErgoAngleOffset = 0.26f; |
50 | 50 |
51 static constexpr gvr::Vec3f kOrigin = {0.0f, 0.0f, 0.0f}; | 51 static constexpr gfx::Point3F kOrigin = {0.0f, 0.0f, 0.0f}; |
52 | 52 |
53 // In lieu of an elbow model, we assume a position for the user's hand. | 53 // In lieu of an elbow model, we assume a position for the user's hand. |
54 // TODO(mthiesse): Handedness options. | 54 // TODO(mthiesse): Handedness options. |
55 static constexpr gvr::Vec3f kHandPosition = {0.2f, -0.5f, -0.2f}; | 55 static constexpr gfx::Point3F kHandPosition = {0.2f, -0.5f, -0.2f}; |
56 | 56 |
57 // Fraction of the distance to the object the cursor is drawn at to avoid | 57 // Fraction of the distance to the object the cursor is drawn at to avoid |
58 // rounding errors drawing the cursor behind the object. | 58 // rounding errors drawing the cursor behind the object. |
59 static constexpr float kReticleOffset = 0.99f; | 59 static constexpr float kReticleOffset = 0.99f; |
60 | 60 |
61 // GVR buffer indices for use with viewport->SetSourceBufferIndex | 61 // GVR buffer indices for use with viewport->SetSourceBufferIndex |
62 // or frame.BindBuffer. We use one for world content (with reprojection) | 62 // or frame.BindBuffer. We use one for world content (with reprojection) |
63 // including main VrShell and WebVR content plus world-space UI. | 63 // including main VrShell and WebVR content plus world-space UI. |
64 // The headlocked buffer is for UI that should not use reprojection. | 64 // The headlocked buffer is for UI that should not use reprojection. |
65 static constexpr int kFramePrimaryBuffer = 0; | 65 static constexpr int kFramePrimaryBuffer = 0; |
66 static constexpr int kFrameHeadlockedBuffer = 1; | 66 static constexpr int kFrameHeadlockedBuffer = 1; |
67 | 67 |
68 // Pixel dimensions and field of view for the head-locked content. This | 68 // Pixel dimensions and field of view for the head-locked content. This |
69 // is currently sized to fit the WebVR "insecure transport" warnings, | 69 // is currently sized to fit the WebVR "insecure transport" warnings, |
70 // adjust it as needed if there is additional content. | 70 // adjust it as needed if there is additional content. |
71 static constexpr gvr::Sizei kHeadlockedBufferDimensions = {1024, 1024}; | 71 static constexpr gfx::Size kHeadlockedBufferDimensions = {1024, 1024}; |
72 static constexpr gvr::Rectf kHeadlockedBufferFov = {20.f, 20.f, 20.f, 20.f}; | 72 static constexpr gvr::Rectf kHeadlockedBufferFov = {20.f, 20.f, 20.f, 20.f}; |
73 | 73 |
74 // The GVR viewport list has two entries (left eye and right eye) for each | 74 // The GVR viewport list has two entries (left eye and right eye) for each |
75 // GVR buffer. | 75 // GVR buffer. |
76 static constexpr int kViewportListPrimaryOffset = 0; | 76 static constexpr int kViewportListPrimaryOffset = 0; |
77 static constexpr int kViewportListHeadlockedOffset = 2; | 77 static constexpr int kViewportListHeadlockedOffset = 2; |
78 | 78 |
79 // Buffer size large enough to handle the current backlog of poses which is | 79 // Buffer size large enough to handle the current backlog of poses which is |
80 // 2-3 frames. | 80 // 2-3 frames. |
81 static constexpr unsigned kPoseRingBufferSize = 8; | 81 static constexpr unsigned kPoseRingBufferSize = 8; |
82 | 82 |
83 // Criteria for considering holding the app button in combination with | 83 // Criteria for considering holding the app button in combination with |
84 // controller movement as a gesture. | 84 // controller movement as a gesture. |
85 static constexpr float kMinAppButtonGestureAngleRad = 0.25; | 85 static constexpr float kMinAppButtonGestureAngleRad = 0.25; |
86 | 86 |
87 // Generate a quaternion representing the rotation from the negative Z axis | 87 // Generate a quaternion representing the rotation from the negative Z axis |
88 // (0, 0, -1) to a specified vector. This is an optimized version of a more | 88 // (0, 0, -1) to a specified vector. This is an optimized version of a more |
89 // general vector-to-vector calculation. | 89 // general vector-to-vector calculation. |
90 gvr::Quatf GetRotationFromZAxis(gvr::Vec3f vec) { | 90 vr::Quatf GetRotationFromZAxis(gfx::Vector3dF vec) { |
91 vr_shell::NormalizeVector(vec); | 91 vr::NormalizeVector(&vec); |
92 gvr::Quatf quat; | 92 vr::Quatf quat; |
93 quat.qw = 1.0f - vec.z; | 93 quat.qw = 1.0f - vec.z(); |
94 if (quat.qw < 1e-6f) { | 94 if (quat.qw < 1e-6f) { |
95 // Degenerate case: vectors are exactly opposite. Replace by an | 95 // Degenerate case: vectors are exactly opposite. Replace by an |
96 // arbitrary 180 degree rotation to avoid invalid normalization. | 96 // arbitrary 180 degree rotation to avoid invalid normalization. |
97 quat.qx = 1.0f; | 97 quat.qx = 1.0f; |
98 quat.qy = 0.0f; | 98 quat.qy = 0.0f; |
99 quat.qz = 0.0f; | 99 quat.qz = 0.0f; |
100 quat.qw = 0.0f; | 100 quat.qw = 0.0f; |
101 } else { | 101 } else { |
102 quat.qx = vec.y; | 102 quat.qx = vec.y(); |
103 quat.qy = -vec.x; | 103 quat.qy = -vec.x(); |
104 quat.qz = 0.0f; | 104 quat.qz = 0.0f; |
105 vr_shell::NormalizeQuat(quat); | 105 vr::NormalizeQuat(&quat); |
106 } | 106 } |
107 return quat; | 107 return quat; |
108 } | 108 } |
109 | 109 |
110 std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(WebInputEvent::Type type, | 110 std::unique_ptr<blink::WebMouseEvent> MakeMouseEvent(WebInputEvent::Type type, |
111 double timestamp, | 111 double timestamp, |
112 float x, | 112 float x, |
113 float y) { | 113 float y) { |
114 std::unique_ptr<blink::WebMouseEvent> mouse_event(new blink::WebMouseEvent( | 114 std::unique_ptr<blink::WebMouseEvent> mouse_event(new blink::WebMouseEvent( |
115 type, blink::WebInputEvent::kNoModifiers, timestamp)); | 115 type, blink::WebInputEvent::kNoModifiers, timestamp)); |
(...skipping 10 matching lines...) Expand all Loading... |
126 DAYDREAM = 2, | 126 DAYDREAM = 2, |
127 VIEWER_TYPE_MAX, | 127 VIEWER_TYPE_MAX, |
128 }; | 128 }; |
129 | 129 |
130 void RunVRDisplayInfoCallback( | 130 void RunVRDisplayInfoCallback( |
131 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, | 131 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, |
132 device::mojom::VRDisplayInfoPtr info) { | 132 device::mojom::VRDisplayInfoPtr info) { |
133 callback.Run(std::move(info)); | 133 callback.Run(std::move(info)); |
134 } | 134 } |
135 | 135 |
| 136 void MatfToGvrMat(const vr::Mat4f& in, gvr::Mat4f* out) { |
| 137 // If our std::array implementation doesn't have any non-data members, we can |
| 138 // just cast the gvr matrix to an std::array. |
| 139 static_assert(sizeof(in) == sizeof(*out), |
| 140 "Cannot reinterpret gvr::Mat4f as vr::Matf"); |
| 141 *out = *reinterpret_cast<gvr::Mat4f*>(const_cast<vr::Mat4f*>(&in)); |
| 142 } |
| 143 |
| 144 void GvrMatToMatf(const gvr::Mat4f& in, vr::Mat4f* out) { |
| 145 // If our std::array implementation doesn't have any non-data members, we can |
| 146 // just cast the gvr matrix to an std::array. |
| 147 static_assert(sizeof(in) == sizeof(*out), |
| 148 "Cannot reinterpret gvr::Mat4f as vr::Matf"); |
| 149 *out = *reinterpret_cast<vr::Mat4f*>(const_cast<gvr::Mat4f*>(&in)); |
| 150 } |
| 151 |
136 } // namespace | 152 } // namespace |
137 | 153 |
138 VrShellGl::VrShellGl( | 154 VrShellGl::VrShellGl( |
139 const base::WeakPtr<VrShell>& weak_vr_shell, | 155 const base::WeakPtr<VrShell>& weak_vr_shell, |
140 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, | 156 scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner, |
141 gvr_context* gvr_api, | 157 gvr_context* gvr_api, |
142 bool initially_web_vr, | 158 bool initially_web_vr, |
143 bool reprojected_rendering) | 159 bool reprojected_rendering) |
144 : web_vr_mode_(initially_web_vr), | 160 : web_vr_mode_(initially_web_vr), |
145 surfaceless_rendering_(reprojected_rendering), | 161 surfaceless_rendering_(reprojected_rendering), |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 content_surface_texture_ = gl::SurfaceTexture::Create(content_texture_id_); | 238 content_surface_texture_ = gl::SurfaceTexture::Create(content_texture_id_); |
223 webvr_surface_texture_ = gl::SurfaceTexture::Create(webvr_texture_id_); | 239 webvr_surface_texture_ = gl::SurfaceTexture::Create(webvr_texture_id_); |
224 CreateUiSurface(); | 240 CreateUiSurface(); |
225 CreateContentSurface(); | 241 CreateContentSurface(); |
226 ui_surface_texture_->SetFrameAvailableCallback(base::Bind( | 242 ui_surface_texture_->SetFrameAvailableCallback(base::Bind( |
227 &VrShellGl::OnUIFrameAvailable, weak_ptr_factory_.GetWeakPtr())); | 243 &VrShellGl::OnUIFrameAvailable, weak_ptr_factory_.GetWeakPtr())); |
228 content_surface_texture_->SetFrameAvailableCallback(base::Bind( | 244 content_surface_texture_->SetFrameAvailableCallback(base::Bind( |
229 &VrShellGl::OnContentFrameAvailable, weak_ptr_factory_.GetWeakPtr())); | 245 &VrShellGl::OnContentFrameAvailable, weak_ptr_factory_.GetWeakPtr())); |
230 webvr_surface_texture_->SetFrameAvailableCallback(base::Bind( | 246 webvr_surface_texture_->SetFrameAvailableCallback(base::Bind( |
231 &VrShellGl::OnWebVRFrameAvailable, weak_ptr_factory_.GetWeakPtr())); | 247 &VrShellGl::OnWebVRFrameAvailable, weak_ptr_factory_.GetWeakPtr())); |
232 ui_surface_texture_->SetDefaultBufferSize(ui_tex_physical_size_.width, | 248 ui_surface_texture_->SetDefaultBufferSize(ui_tex_physical_size_.width(), |
233 ui_tex_physical_size_.height); | 249 ui_tex_physical_size_.height()); |
234 content_surface_texture_->SetDefaultBufferSize( | 250 content_surface_texture_->SetDefaultBufferSize( |
235 content_tex_physical_size_.width, content_tex_physical_size_.height); | 251 content_tex_physical_size_.width(), content_tex_physical_size_.height()); |
236 InitializeRenderer(); | 252 InitializeRenderer(); |
237 | 253 |
238 gvr::Sizei webvr_size = | 254 gfx::Size webvr_size = |
239 device::GvrDelegate::GetRecommendedWebVrSize(gvr_api_.get()); | 255 device::GvrDelegate::GetRecommendedWebVrSize(gvr_api_.get()); |
240 DVLOG(1) << __FUNCTION__ << ": resize initial to " << webvr_size.width << "x" | 256 DVLOG(1) << __FUNCTION__ << ": resize initial to " << webvr_size.width() |
241 << webvr_size.height; | 257 << "x" << webvr_size.height(); |
242 | 258 |
243 CreateOrResizeWebVRSurface(webvr_size); | 259 CreateOrResizeWebVRSurface(webvr_size); |
244 | 260 |
245 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); | 261 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); |
246 OnVSync(); | 262 OnVSync(); |
247 | 263 |
248 ready_to_draw_ = true; | 264 ready_to_draw_ = true; |
249 } | 265 } |
250 | 266 |
251 void VrShellGl::CreateContentSurface() { | 267 void VrShellGl::CreateContentSurface() { |
252 content_surface_ = | 268 content_surface_ = |
253 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get()); | 269 base::MakeUnique<gl::ScopedJavaSurface>(content_surface_texture_.get()); |
254 main_thread_task_runner_->PostTask( | 270 main_thread_task_runner_->PostTask( |
255 FROM_HERE, base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_, | 271 FROM_HERE, base::Bind(&VrShell::ContentSurfaceChanged, weak_vr_shell_, |
256 content_surface_->j_surface().obj())); | 272 content_surface_->j_surface().obj())); |
257 } | 273 } |
258 | 274 |
259 void VrShellGl::CreateUiSurface() { | 275 void VrShellGl::CreateUiSurface() { |
260 ui_surface_ = | 276 ui_surface_ = |
261 base::MakeUnique<gl::ScopedJavaSurface>(ui_surface_texture_.get()); | 277 base::MakeUnique<gl::ScopedJavaSurface>(ui_surface_texture_.get()); |
262 main_thread_task_runner_->PostTask( | 278 main_thread_task_runner_->PostTask( |
263 FROM_HERE, base::Bind(&VrShell::UiSurfaceChanged, weak_vr_shell_, | 279 FROM_HERE, base::Bind(&VrShell::UiSurfaceChanged, weak_vr_shell_, |
264 ui_surface_->j_surface().obj())); | 280 ui_surface_->j_surface().obj())); |
265 } | 281 } |
266 | 282 |
267 void VrShellGl::CreateOrResizeWebVRSurface(const gvr::Sizei& size) { | 283 void VrShellGl::CreateOrResizeWebVRSurface(const gfx::Size& size) { |
268 if (!webvr_surface_texture_) { | 284 if (!webvr_surface_texture_) { |
269 DLOG(ERROR) << "No WebVR surface texture available"; | 285 DLOG(ERROR) << "No WebVR surface texture available"; |
270 return; | 286 return; |
271 } | 287 } |
272 | 288 |
273 // ContentPhysicalBoundsChanged is getting called twice with | 289 // ContentPhysicalBoundsChanged is getting called twice with |
274 // identical sizes? Avoid thrashing the existing context. | 290 // identical sizes? Avoid thrashing the existing context. |
275 if (size == webvr_surface_size_) { | 291 if (size == webvr_surface_size_) { |
276 return; | 292 return; |
277 } | 293 } |
278 | 294 |
279 if (!size.width || !size.height) { | 295 if (!size.width() || !size.height()) { |
280 // Invalid size, defer until a new size arrives on a future bounds update. | 296 // Invalid size, defer until a new size arrives on a future bounds update. |
281 return; | 297 return; |
282 } | 298 } |
283 | 299 |
284 webvr_surface_texture_->SetDefaultBufferSize(size.width, size.height); | 300 webvr_surface_texture_->SetDefaultBufferSize(size.width(), size.height()); |
285 webvr_surface_size_ = size; | 301 webvr_surface_size_ = size; |
286 | 302 |
287 if (mailbox_bridge_) { | 303 if (mailbox_bridge_) { |
288 mailbox_bridge_->ResizeSurface(size.width, size.height); | 304 mailbox_bridge_->ResizeSurface(size.width(), size.height()); |
289 } else { | 305 } else { |
290 mailbox_bridge_ = base::MakeUnique<MailboxToSurfaceBridge>(); | 306 mailbox_bridge_ = base::MakeUnique<MailboxToSurfaceBridge>(); |
291 mailbox_bridge_->CreateSurface(webvr_surface_texture_.get()); | 307 mailbox_bridge_->CreateSurface(webvr_surface_texture_.get()); |
292 } | 308 } |
293 } | 309 } |
294 | 310 |
295 void VrShellGl::SubmitWebVRFrame(int16_t frame_index, | 311 void VrShellGl::SubmitWebVRFrame(int16_t frame_index, |
296 const gpu::MailboxHolder& mailbox) { | 312 const gpu::MailboxHolder& mailbox) { |
297 TRACE_EVENT0("gpu", "VrShellGl::SubmitWebVRFrame"); | 313 TRACE_EVENT0("gpu", "VrShellGl::SubmitWebVRFrame"); |
298 | 314 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 NOTREACHED(); | 398 NOTREACHED(); |
383 viewerType = ViewerType::UNKNOWN_TYPE; | 399 viewerType = ViewerType::UNKNOWN_TYPE; |
384 break; | 400 break; |
385 } | 401 } |
386 UMA_HISTOGRAM_ENUMERATION("VRViewerType", static_cast<int>(viewerType), | 402 UMA_HISTOGRAM_ENUMERATION("VRViewerType", static_cast<int>(viewerType), |
387 static_cast<int>(ViewerType::VIEWER_TYPE_MAX)); | 403 static_cast<int>(ViewerType::VIEWER_TYPE_MAX)); |
388 } | 404 } |
389 | 405 |
390 void VrShellGl::InitializeRenderer() { | 406 void VrShellGl::InitializeRenderer() { |
391 gvr_api_->InitializeGl(); | 407 gvr_api_->InitializeGl(); |
392 webvr_head_pose_.assign(kPoseRingBufferSize, | 408 vr::Mat4f head_pose; |
393 gvr_api_->GetHeadSpaceFromStartSpaceRotation( | 409 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose); |
394 gvr::GvrApi::GetTimePointNow())); | 410 webvr_head_pose_.assign(kPoseRingBufferSize, head_pose); |
395 | 411 |
396 std::vector<gvr::BufferSpec> specs; | 412 std::vector<gvr::BufferSpec> specs; |
397 // For kFramePrimaryBuffer (primary VrShell and WebVR content) | 413 // For kFramePrimaryBuffer (primary VrShell and WebVR content) |
398 specs.push_back(gvr_api_->CreateBufferSpec()); | 414 specs.push_back(gvr_api_->CreateBufferSpec()); |
399 render_size_primary_ = specs[kFramePrimaryBuffer].GetSize(); | 415 gvr::Sizei render_size_primary = specs[kFramePrimaryBuffer].GetSize(); |
| 416 render_size_primary_ = {render_size_primary.width, |
| 417 render_size_primary.height}; |
400 render_size_vrshell_ = render_size_primary_; | 418 render_size_vrshell_ = render_size_primary_; |
401 | 419 |
402 // For kFrameHeadlockedBuffer (for WebVR insecure content warning). | 420 // For kFrameHeadlockedBuffer (for WebVR insecure content warning). |
403 // Set this up at fixed resolution, the (smaller) FOV gets set below. | 421 // Set this up at fixed resolution, the (smaller) FOV gets set below. |
404 specs.push_back(gvr_api_->CreateBufferSpec()); | 422 specs.push_back(gvr_api_->CreateBufferSpec()); |
405 specs.back().SetSize(kHeadlockedBufferDimensions); | 423 specs.back().SetSize({kHeadlockedBufferDimensions.width(), |
406 render_size_headlocked_ = specs[kFrameHeadlockedBuffer].GetSize(); | 424 kHeadlockedBufferDimensions.height()}); |
| 425 gvr::Sizei render_size_headlocked = specs[kFrameHeadlockedBuffer].GetSize(); |
| 426 render_size_headlocked_ = {render_size_headlocked.width, |
| 427 render_size_headlocked.height}; |
407 | 428 |
408 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); | 429 swap_chain_.reset(new gvr::SwapChain(gvr_api_->CreateSwapChain(specs))); |
409 | 430 |
410 vr_shell_renderer_.reset(new VrShellRenderer()); | 431 vr_shell_renderer_.reset(new VrShellRenderer()); |
411 | 432 |
412 // Allocate a buffer viewport for use in UI drawing. This isn't | 433 // Allocate a buffer viewport for use in UI drawing. This isn't |
413 // initialized at this point, it'll be set from other viewport list | 434 // initialized at this point, it'll be set from other viewport list |
414 // entries as needed. | 435 // entries as needed. |
415 buffer_viewport_.reset( | 436 buffer_viewport_.reset( |
416 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); | 437 new gvr::BufferViewport(gvr_api_->CreateBufferViewport())); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } | 482 } |
462 | 483 |
463 void VrShellGl::UpdateController() { | 484 void VrShellGl::UpdateController() { |
464 controller_->UpdateState(); | 485 controller_->UpdateState(); |
465 | 486 |
466 device::GvrGamepadData pad = controller_->GetGamepadData(); | 487 device::GvrGamepadData pad = controller_->GetGamepadData(); |
467 main_thread_task_runner_->PostTask( | 488 main_thread_task_runner_->PostTask( |
468 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); | 489 FROM_HERE, base::Bind(&VrShell::UpdateGamepadData, weak_vr_shell_, pad)); |
469 } | 490 } |
470 | 491 |
471 void VrShellGl::HandleControllerInput(const gvr::Vec3f& forward_vector) { | 492 void VrShellGl::HandleControllerInput(const gfx::Vector3dF& forward_vector) { |
472 if (ShouldDrawWebVr()) { | 493 if (ShouldDrawWebVr()) { |
473 // Process screen touch events for Cardboard button compatibility. | 494 // Process screen touch events for Cardboard button compatibility. |
474 // Also send tap events for controller "touchpad click" events. | 495 // Also send tap events for controller "touchpad click" events. |
475 if (touch_pending_ || | 496 if (touch_pending_ || |
476 controller_->ButtonUpHappened( | 497 controller_->ButtonUpHappened( |
477 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { | 498 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_CLICK)) { |
478 touch_pending_ = false; | 499 touch_pending_ = false; |
479 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( | 500 std::unique_ptr<WebGestureEvent> gesture(new WebGestureEvent( |
480 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, | 501 WebInputEvent::kGestureTapDown, WebInputEvent::kNoModifiers, |
481 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); | 502 (base::TimeTicks::Now() - base::TimeTicks()).InSecondsF())); |
482 gesture->source_device = blink::kWebGestureDeviceTouchpad; | 503 gesture->source_device = blink::kWebGestureDeviceTouchpad; |
483 gesture->x = 0; | 504 gesture->x = 0; |
484 gesture->y = 0; | 505 gesture->y = 0; |
485 SendGesture(InputTarget::CONTENT, std::move(gesture)); | 506 SendGesture(InputTarget::CONTENT, std::move(gesture)); |
486 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; | 507 DVLOG(1) << __FUNCTION__ << ": sent CLICK gesture"; |
487 } | 508 } |
488 } | 509 } |
489 | 510 |
490 gvr::Vec3f ergo_neutral_pose; | 511 gfx::Vector3dF ergo_neutral_pose; |
491 if (!controller_->IsConnected()) { | 512 if (!controller_->IsConnected()) { |
492 // No controller detected, set up a gaze cursor that tracks the | 513 // No controller detected, set up a gaze cursor that tracks the |
493 // forward direction. | 514 // forward direction. |
494 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; | 515 ergo_neutral_pose = {0.0f, 0.0f, -1.0f}; |
495 controller_quat_ = GetRotationFromZAxis(forward_vector); | 516 controller_quat_ = GetRotationFromZAxis(forward_vector); |
496 } else { | 517 } else { |
497 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; | 518 ergo_neutral_pose = {0.0f, -sin(kErgoAngleOffset), -cos(kErgoAngleOffset)}; |
498 controller_quat_ = controller_->Orientation(); | 519 controller_quat_ = controller_->Orientation(); |
499 } | 520 } |
500 | 521 |
501 gvr::Mat4f mat = QuatToMatrix(controller_quat_); | 522 vr::Mat4f mat; |
502 gvr::Vec3f controller_direction = MatrixVectorMul(mat, ergo_neutral_pose); | 523 QuatToMatrix(controller_quat_, &mat); |
| 524 gfx::Vector3dF controller_direction = |
| 525 vr::MatrixVectorMul(mat, ergo_neutral_pose); |
503 | 526 |
504 HandleControllerAppButtonActivity(controller_direction); | 527 HandleControllerAppButtonActivity(controller_direction); |
505 | 528 |
506 if (ShouldDrawWebVr()) { | 529 if (ShouldDrawWebVr()) { |
507 return; | 530 return; |
508 } | 531 } |
509 | 532 |
510 // If we place the reticle based on elements intersecting the controller beam, | 533 // If we place the reticle based on elements intersecting the controller beam, |
511 // we can end up with the reticle hiding behind elements, or jumping laterally | 534 // we can end up with the reticle hiding behind elements, or jumping laterally |
512 // in the field of view. This is physically correct, but hard to use. For | 535 // in the field of view. This is physically correct, but hard to use. For |
513 // usability, do the following instead: | 536 // usability, do the following instead: |
514 // | 537 // |
515 // - Project the controller laser onto a distance-limiting sphere. | 538 // - Project the controller laser onto a distance-limiting sphere. |
516 // - Create a vector between the eyes and the outer surface point. | 539 // - Create a vector between the eyes and the outer surface point. |
517 // - If any UI elements intersect this vector, and is within the bounding | 540 // - If any UI elements intersect this vector, and is within the bounding |
518 // sphere, choose the closest to the eyes, and place the reticle at the | 541 // sphere, choose the closest to the eyes, and place the reticle at the |
519 // intersection point. | 542 // intersection point. |
520 | 543 |
521 // Compute the distance from the eyes to the distance limiting sphere. Note | 544 // Compute the distance from the eyes to the distance limiting sphere. Note |
522 // that the sphere is centered at the controller, rather than the eye, for | 545 // that the sphere is centered at the controller, rather than the eye, for |
523 // simplicity. | 546 // simplicity. |
524 float distance = scene_->GetBackgroundDistance(); | 547 float distance = scene_->GetBackgroundDistance(); |
525 target_point_ = GetRayPoint(kHandPosition, controller_direction, distance); | 548 target_point_ = |
526 gvr::Vec3f eye_to_target = target_point_; | 549 vr::GetRayPoint(kHandPosition, controller_direction, distance); |
527 NormalizeVector(eye_to_target); | 550 gfx::Vector3dF eye_to_target = target_point_ - kOrigin; |
| 551 vr::NormalizeVector(&eye_to_target); |
528 | 552 |
529 // Determine which UI element (if any) intersects the line between the eyes | 553 // Determine which UI element (if any) intersects the line between the eyes |
530 // and the controller target position. | 554 // and the controller target position. |
531 float closest_element_distance = VectorLength(target_point_); | 555 float closest_element_distance = (target_point_ - kOrigin).Length(); |
532 target_element_ = nullptr; | 556 target_element_ = nullptr; |
533 float target_x; | 557 float target_x; |
534 float target_y; | 558 float target_y; |
535 | 559 |
536 for (const auto& plane : scene_->GetUiElements()) { | 560 for (const auto& plane : scene_->GetUiElements()) { |
537 if (!plane->IsHitTestable()) | 561 if (!plane->IsHitTestable()) |
538 continue; | 562 continue; |
539 | 563 |
540 float distance_to_plane; | 564 float distance_to_plane; |
541 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) | 565 if (!plane->GetRayDistance(kOrigin, eye_to_target, &distance_to_plane)) |
542 continue; | 566 continue; |
543 | 567 |
544 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) | 568 if (distance_to_plane < 0 || distance_to_plane >= closest_element_distance) |
545 continue; | 569 continue; |
546 | 570 |
547 gvr::Vec3f plane_intersection_point = | 571 gfx::Point3F plane_intersection_point = |
548 GetRayPoint(kOrigin, eye_to_target, distance_to_plane); | 572 vr::GetRayPoint(kOrigin, eye_to_target, distance_to_plane); |
549 gvr::Vec2f unit_xy_point = | 573 gfx::PointF unit_xy_point = |
550 plane->GetUnitRectangleCoordinates(plane_intersection_point); | 574 plane->GetUnitRectangleCoordinates(plane_intersection_point); |
551 | 575 |
552 float x = 0.5f + unit_xy_point.x; | 576 float x = 0.5f + unit_xy_point.x(); |
553 float y = 0.5f - unit_xy_point.y; | 577 float y = 0.5f - unit_xy_point.y(); |
554 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) | 578 if (x < 0.0f || x >= 1.0f || y < 0.0f || y >= 1.0f) |
555 continue; | 579 continue; |
556 | 580 |
557 closest_element_distance = distance_to_plane; | 581 closest_element_distance = distance_to_plane; |
558 target_point_ = plane_intersection_point; | 582 target_point_ = plane_intersection_point; |
559 target_element_ = plane.get(); | 583 target_element_ = plane.get(); |
560 target_x = x; | 584 target_x = x; |
561 target_y = y; | 585 target_y = y; |
562 } | 586 } |
563 | 587 |
564 // Treat UI elements, which do not show web content, as NONE input | 588 // Treat UI elements, which do not show web content, as NONE input |
565 // targets since they cannot make use of the input anyway. | 589 // targets since they cannot make use of the input anyway. |
566 InputTarget input_target = InputTarget::NONE; | 590 InputTarget input_target = InputTarget::NONE; |
567 int pixel_x = 0; | 591 int pixel_x = 0; |
568 int pixel_y = 0; | 592 int pixel_y = 0; |
569 | 593 |
570 if (target_element_ != nullptr) { | 594 if (target_element_ != nullptr) { |
571 Rectf pixel_rect; | 595 gfx::RectF pixel_rect; |
572 if (target_element_->fill == Fill::CONTENT) { | 596 if (target_element_->fill == Fill::CONTENT) { |
573 pixel_rect = {0, 0, content_tex_css_width_, content_tex_css_height_}; | 597 pixel_rect.SetRect(0, 0, content_tex_css_width_, content_tex_css_height_); |
574 } else { | 598 } else { |
575 pixel_rect = {target_element_->copy_rect.x, target_element_->copy_rect.y, | 599 pixel_rect.SetRect(target_element_->copy_rect.x(), |
576 target_element_->copy_rect.width, | 600 target_element_->copy_rect.y(), |
577 target_element_->copy_rect.height}; | 601 target_element_->copy_rect.width(), |
| 602 target_element_->copy_rect.height()); |
578 } | 603 } |
579 pixel_x = pixel_rect.x + pixel_rect.width * target_x; | 604 pixel_x = pixel_rect.x() + pixel_rect.width() * target_x; |
580 pixel_y = pixel_rect.y + pixel_rect.height * target_y; | 605 pixel_y = pixel_rect.y() + pixel_rect.height() * target_y; |
581 | 606 |
582 switch (target_element_->fill) { | 607 switch (target_element_->fill) { |
583 case Fill::CONTENT: | 608 case Fill::CONTENT: |
584 input_target = InputTarget::CONTENT; | 609 input_target = InputTarget::CONTENT; |
585 break; | 610 break; |
586 case Fill::SPRITE: | 611 case Fill::SPRITE: |
587 input_target = InputTarget::UI; | 612 input_target = InputTarget::UI; |
588 break; | 613 break; |
589 default: | 614 default: |
590 break; | 615 break; |
591 } | 616 } |
592 } | 617 } |
593 SendEventsToTarget(input_target, pixel_x, pixel_y); | 618 SendEventsToTarget(input_target, pixel_x, pixel_y); |
594 } | 619 } |
595 | 620 |
596 void VrShellGl::HandleControllerAppButtonActivity( | 621 void VrShellGl::HandleControllerAppButtonActivity( |
597 const gvr::Vec3f& controller_direction) { | 622 const gfx::Vector3dF& controller_direction) { |
598 // Note that button up/down state is transient, so ButtonDownHappened only | 623 // Note that button up/down state is transient, so ButtonDownHappened only |
599 // returns true for a single frame (and we're guaranteed not to miss it). | 624 // returns true for a single frame (and we're guaranteed not to miss it). |
600 if (controller_->ButtonDownHappened( | 625 if (controller_->ButtonDownHappened( |
601 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | 626 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { |
602 controller_start_direction_ = controller_direction; | 627 controller_start_direction_ = controller_direction; |
603 } | 628 } |
604 if (controller_->ButtonUpHappened( | 629 if (controller_->ButtonUpHappened( |
605 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { | 630 gvr::ControllerButton::GVR_CONTROLLER_BUTTON_APP)) { |
606 // A gesture is a movement of the controller while holding the App button. | 631 // A gesture is a movement of the controller while holding the App button. |
607 // If the angle of the movement is within a threshold, the action is | 632 // If the angle of the movement is within a threshold, the action is |
608 // considered a regular click | 633 // considered a regular click |
609 // TODO(asimjour1): We need to refactor the gesture recognition outside of | 634 // TODO(asimjour1): We need to refactor the gesture recognition outside of |
610 // VrShellGl. | 635 // VrShellGl. |
611 UiInterface::Direction direction = UiInterface::NONE; | 636 UiInterface::Direction direction = UiInterface::NONE; |
612 float gesture_xz_angle; | 637 float gesture_xz_angle; |
613 if (XZAngle(controller_start_direction_, controller_direction, | 638 if (vr::XZAngle(controller_start_direction_, controller_direction, |
614 &gesture_xz_angle)) { | 639 &gesture_xz_angle)) { |
615 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { | 640 if (fabs(gesture_xz_angle) > kMinAppButtonGestureAngleRad) { |
616 direction = | 641 direction = |
617 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; | 642 gesture_xz_angle < 0 ? UiInterface::LEFT : UiInterface::RIGHT; |
618 main_thread_task_runner_->PostTask( | 643 main_thread_task_runner_->PostTask( |
619 FROM_HERE, base::Bind(&VrShell::AppButtonGesturePerformed, | 644 FROM_HERE, base::Bind(&VrShell::AppButtonGesturePerformed, |
620 weak_vr_shell_, direction)); | 645 weak_vr_shell_, direction)); |
621 } | 646 } |
622 } | 647 } |
623 if (direction == UiInterface::NONE) { | 648 if (direction == UiInterface::NONE) { |
624 main_thread_task_runner_->PostTask( | 649 main_thread_task_runner_->PostTask( |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 if (index < frame_index) | 764 if (index < frame_index) |
740 index += max; | 765 index += max; |
741 // If the pending bounds change is for an upcoming frame | 766 // If the pending bounds change is for an upcoming frame |
742 // within our buffer size, wait to apply it. Otherwise, apply | 767 // within our buffer size, wait to apply it. Otherwise, apply |
743 // it immediately. This guarantees that even if we miss many | 768 // it immediately. This guarantees that even if we miss many |
744 // frames, the queue can't fill up with stale bounds. | 769 // frames, the queue can't fill up with stale bounds. |
745 if (index > frame_index && index <= frame_index + kPoseRingBufferSize) | 770 if (index > frame_index && index <= frame_index + kPoseRingBufferSize) |
746 break; | 771 break; |
747 | 772 |
748 const WebVrBounds& bounds = pending_bounds_.front().second; | 773 const WebVrBounds& bounds = pending_bounds_.front().second; |
749 webvr_left_viewport_->SetSourceUv(bounds.left_bounds); | 774 const gfx::RectF& left = bounds.left_bounds; |
750 webvr_right_viewport_->SetSourceUv(bounds.right_bounds); | 775 const gfx::RectF& right = bounds.right_bounds; |
| 776 gvr::Rectf gvr_left_bounds = {left.x(), left.x() + left.width(), |
| 777 left.y() + left.height(), left.y()}; |
| 778 webvr_left_viewport_->SetSourceUv(gvr_left_bounds); |
| 779 gvr::Rectf gvr_right_bounds = {right.x(), right.x() + right.width(), |
| 780 right.y() + right.height(), right.y()}; |
| 781 webvr_right_viewport_->SetSourceUv(gvr_right_bounds); |
751 DVLOG(1) << __FUNCTION__ << ": resize from pending_bounds to " | 782 DVLOG(1) << __FUNCTION__ << ": resize from pending_bounds to " |
752 << bounds.source_size.width << "x" << bounds.source_size.height; | 783 << bounds.source_size.width() << "x" |
| 784 << bounds.source_size.height(); |
753 CreateOrResizeWebVRSurface(bounds.source_size); | 785 CreateOrResizeWebVRSurface(bounds.source_size); |
754 pending_bounds_.pop(); | 786 pending_bounds_.pop(); |
755 } | 787 } |
756 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE, | 788 buffer_viewport_list_->SetBufferViewport(GVR_LEFT_EYE, |
757 *webvr_left_viewport_); | 789 *webvr_left_viewport_); |
758 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE, | 790 buffer_viewport_list_->SetBufferViewport(GVR_RIGHT_EYE, |
759 *webvr_right_viewport_); | 791 *webvr_right_viewport_); |
760 if (render_size_primary_ != webvr_surface_size_) { | 792 if (render_size_primary_ != webvr_surface_size_) { |
761 if (!webvr_surface_size_.width) { | 793 if (!webvr_surface_size_.width()) { |
762 // Don't try to resize to 0x0 pixels, drop frames until we get a | 794 // Don't try to resize to 0x0 pixels, drop frames until we get a |
763 // valid size. | 795 // valid size. |
764 return; | 796 return; |
765 } | 797 } |
766 | 798 |
767 render_size_primary_ = webvr_surface_size_; | 799 render_size_primary_ = webvr_surface_size_; |
768 DVLOG(1) << __FUNCTION__ << ": resize GVR to " | 800 DVLOG(1) << __FUNCTION__ << ": resize GVR to " |
769 << render_size_primary_.width << "x" | 801 << render_size_primary_.width() << "x" |
770 << render_size_primary_.height; | 802 << render_size_primary_.height(); |
771 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_); | 803 swap_chain_->ResizeBuffer( |
| 804 kFramePrimaryBuffer, |
| 805 {render_size_primary_.width(), render_size_primary_.height()}); |
772 } | 806 } |
773 } else { | 807 } else { |
774 if (render_size_primary_ != render_size_vrshell_) { | 808 if (render_size_primary_ != render_size_vrshell_) { |
775 render_size_primary_ = render_size_vrshell_; | 809 render_size_primary_ = render_size_vrshell_; |
776 swap_chain_->ResizeBuffer(kFramePrimaryBuffer, render_size_primary_); | 810 swap_chain_->ResizeBuffer( |
| 811 kFramePrimaryBuffer, |
| 812 {render_size_primary_.width(), render_size_primary_.height()}); |
777 } | 813 } |
778 } | 814 } |
779 | 815 |
780 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame"); | 816 TRACE_EVENT_BEGIN0("gpu", "VrShellGl::AcquireFrame"); |
781 gvr::Frame frame = swap_chain_->AcquireFrame(); | 817 gvr::Frame frame = swap_chain_->AcquireFrame(); |
782 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame"); | 818 TRACE_EVENT_END0("gpu", "VrShellGl::AcquireFrame"); |
783 if (!frame.is_valid()) { | 819 if (!frame.is_valid()) { |
784 return; | 820 return; |
785 } | 821 } |
786 frame.BindBuffer(kFramePrimaryBuffer); | 822 frame.BindBuffer(kFramePrimaryBuffer); |
787 | 823 |
788 if (ShouldDrawWebVr()) { | 824 if (ShouldDrawWebVr()) { |
789 DrawWebVr(); | 825 DrawWebVr(); |
790 } | 826 } |
791 | 827 |
792 gvr::Mat4f head_pose; | 828 vr::Mat4f head_pose; |
793 | 829 |
794 // When using async reprojection, we need to know which pose was | 830 // When using async reprojection, we need to know which pose was |
795 // used in the WebVR app for drawing this frame and supply it when | 831 // used in the WebVR app for drawing this frame and supply it when |
796 // submitting. Technically we don't need a pose if not reprojecting, | 832 // submitting. Technically we don't need a pose if not reprojecting, |
797 // but keeping it uninitialized seems likely to cause problems down | 833 // but keeping it uninitialized seems likely to cause problems down |
798 // the road. Copying it is cheaper than fetching a new one. | 834 // the road. Copying it is cheaper than fetching a new one. |
799 if (ShouldDrawWebVr()) { | 835 if (ShouldDrawWebVr()) { |
800 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), | 836 static_assert(!((kPoseRingBufferSize - 1) & kPoseRingBufferSize), |
801 "kPoseRingBufferSize must be a power of 2"); | 837 "kPoseRingBufferSize must be a power of 2"); |
802 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize]; | 838 head_pose = webvr_head_pose_[frame_index % kPoseRingBufferSize]; |
803 } else { | 839 } else { |
804 head_pose = device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get()); | 840 device::GvrDelegate::GetGvrPoseWithNeckModel(gvr_api_.get(), &head_pose); |
805 } | 841 } |
806 | 842 |
807 // Update the render position of all UI elements (including desktop). | 843 // Update the render position of all UI elements (including desktop). |
808 scene_->UpdateTransforms(current_time); | 844 scene_->UpdateTransforms(current_time); |
809 | 845 |
810 { | 846 { |
811 // TODO(crbug.com/704690): Acquire controller state in a way that's timely | 847 // TODO(crbug.com/704690): Acquire controller state in a way that's timely |
812 // for both the gamepad API and UI input handling. | 848 // for both the gamepad API and UI input handling. |
813 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); | 849 TRACE_EVENT0("gpu", "VrShellGl::UpdateController"); |
814 UpdateController(); | 850 UpdateController(); |
815 HandleControllerInput(GetForwardVector(head_pose)); | 851 HandleControllerInput(vr::GetForwardVector(head_pose)); |
816 } | 852 } |
817 | 853 |
818 DrawWorldElements(head_pose); | 854 DrawWorldElements(head_pose); |
819 | 855 |
820 frame.Unbind(); | 856 frame.Unbind(); |
821 | 857 |
822 // Draw head-locked elements to a separate, non-reprojected buffer. | 858 // Draw head-locked elements to a separate, non-reprojected buffer. |
823 if (scene_->HasVisibleHeadLockedElements()) { | 859 if (scene_->HasVisibleHeadLockedElements()) { |
824 frame.BindBuffer(kFrameHeadlockedBuffer); | 860 frame.BindBuffer(kFrameHeadlockedBuffer); |
825 DrawHeadLockedElements(); | 861 DrawHeadLockedElements(); |
826 frame.Unbind(); | 862 frame.Unbind(); |
827 } | 863 } |
828 | 864 |
829 { | 865 { |
830 TRACE_EVENT0("gpu", "VrShellGl::Submit"); | 866 TRACE_EVENT0("gpu", "VrShellGl::Submit"); |
831 frame.Submit(*buffer_viewport_list_, head_pose); | 867 gvr::Mat4f mat; |
| 868 MatfToGvrMat(head_pose, &mat); |
| 869 frame.Submit(*buffer_viewport_list_, mat); |
832 } | 870 } |
833 | 871 |
834 // No need to swap buffers for surfaceless rendering. | 872 // No need to swap buffers for surfaceless rendering. |
835 if (!surfaceless_rendering_) { | 873 if (!surfaceless_rendering_) { |
836 // TODO(mthiesse): Support asynchronous SwapBuffers. | 874 // TODO(mthiesse): Support asynchronous SwapBuffers. |
837 TRACE_EVENT0("gpu", "VrShellGl::SwapBuffers"); | 875 TRACE_EVENT0("gpu", "VrShellGl::SwapBuffers"); |
838 surface_->SwapBuffers(); | 876 surface_->SwapBuffers(); |
839 } | 877 } |
840 } | 878 } |
841 | 879 |
842 void VrShellGl::DrawWorldElements(const gvr::Mat4f& head_pose) { | 880 void VrShellGl::DrawWorldElements(const vr::Mat4f& head_pose) { |
843 TRACE_EVENT0("gpu", "VrShellGl::DrawWorldElements"); | 881 TRACE_EVENT0("gpu", "VrShellGl::DrawWorldElements"); |
844 | 882 |
845 if (ShouldDrawWebVr()) { | 883 if (ShouldDrawWebVr()) { |
846 // WebVR is incompatible with 3D world compositing since the | 884 // WebVR is incompatible with 3D world compositing since the |
847 // depth buffer was already populated with unknown scaling - the | 885 // depth buffer was already populated with unknown scaling - the |
848 // WebVR app has full control over zNear/zFar. Just leave the | 886 // WebVR app has full control over zNear/zFar. Just leave the |
849 // existing content in place in the primary buffer without | 887 // existing content in place in the primary buffer without |
850 // clearing. Currently, there aren't any world elements in WebVR | 888 // clearing. Currently, there aren't any world elements in WebVR |
851 // mode, this will need further testing if those get added | 889 // mode, this will need further testing if those get added |
852 // later. | 890 // later. |
853 } else { | 891 } else { |
854 // Non-WebVR mode, enable depth testing and clear the primary buffers. | 892 // Non-WebVR mode, enable depth testing and clear the primary buffers. |
855 glEnable(GL_CULL_FACE); | 893 glEnable(GL_CULL_FACE); |
856 glEnable(GL_DEPTH_TEST); | 894 glEnable(GL_DEPTH_TEST); |
857 glDepthMask(GL_TRUE); | 895 glDepthMask(GL_TRUE); |
858 | 896 |
859 const Colorf& backgroundColor = scene_->GetBackgroundColor(); | 897 const vr::Colorf& backgroundColor = scene_->GetBackgroundColor(); |
860 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, | 898 glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, |
861 backgroundColor.a); | 899 backgroundColor.a); |
862 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 900 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
863 } | 901 } |
864 std::vector<const ContentRectangle*> elements = scene_->GetWorldElements(); | 902 std::vector<const ContentRectangle*> elements = scene_->GetWorldElements(); |
865 DrawUiView(head_pose, elements, render_size_primary_, | 903 DrawUiView(head_pose, elements, render_size_primary_, |
866 kViewportListPrimaryOffset, !ShouldDrawWebVr()); | 904 kViewportListPrimaryOffset, !ShouldDrawWebVr()); |
867 } | 905 } |
868 | 906 |
869 void VrShellGl::DrawHeadLockedElements() { | 907 void VrShellGl::DrawHeadLockedElements() { |
870 TRACE_EVENT0("gpu", "VrShellGl::DrawHeadLockedElements"); | 908 TRACE_EVENT0("gpu", "VrShellGl::DrawHeadLockedElements"); |
871 std::vector<const ContentRectangle*> elements = | 909 std::vector<const ContentRectangle*> elements = |
872 scene_->GetHeadLockedElements(); | 910 scene_->GetHeadLockedElements(); |
873 | 911 |
874 // Add head-locked viewports. The list gets reset to just | 912 // Add head-locked viewports. The list gets reset to just |
875 // the recommended viewports (for the primary buffer) each frame. | 913 // the recommended viewports (for the primary buffer) each frame. |
876 buffer_viewport_list_->SetBufferViewport( | 914 buffer_viewport_list_->SetBufferViewport( |
877 kViewportListHeadlockedOffset + GVR_LEFT_EYE, *headlocked_left_viewport_); | 915 kViewportListHeadlockedOffset + GVR_LEFT_EYE, *headlocked_left_viewport_); |
878 buffer_viewport_list_->SetBufferViewport( | 916 buffer_viewport_list_->SetBufferViewport( |
879 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, | 917 kViewportListHeadlockedOffset + GVR_RIGHT_EYE, |
880 *headlocked_right_viewport_); | 918 *headlocked_right_viewport_); |
881 | 919 |
882 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | 920 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
883 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 921 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
884 gvr::Mat4f identity_matrix; | 922 vr::Mat4f identity_matrix; |
885 SetIdentityM(identity_matrix); | 923 vr::SetIdentityM(&identity_matrix); |
886 DrawUiView(identity_matrix, elements, render_size_headlocked_, | 924 DrawUiView(identity_matrix, elements, render_size_headlocked_, |
887 kViewportListHeadlockedOffset, false); | 925 kViewportListHeadlockedOffset, false); |
888 } | 926 } |
889 | 927 |
890 void VrShellGl::DrawUiView(const gvr::Mat4f& head_pose, | 928 void VrShellGl::DrawUiView(const vr::Mat4f& head_pose, |
891 const std::vector<const ContentRectangle*>& elements, | 929 const std::vector<const ContentRectangle*>& elements, |
892 const gvr::Sizei& render_size, | 930 const gfx::Size& render_size, |
893 int viewport_offset, | 931 int viewport_offset, |
894 bool draw_cursor) { | 932 bool draw_cursor) { |
895 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); | 933 TRACE_EVENT0("gpu", "VrShellGl::DrawUiView"); |
896 | 934 |
897 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements); | 935 auto elementsInDrawOrder = GetElementsInDrawOrder(head_pose, elements); |
898 | 936 |
899 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { | 937 for (auto eye : {GVR_LEFT_EYE, GVR_RIGHT_EYE}) { |
900 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, | 938 buffer_viewport_list_->GetBufferViewport(eye + viewport_offset, |
901 buffer_viewport_.get()); | 939 buffer_viewport_.get()); |
902 | 940 |
903 const gvr::Mat4f eye_view_matrix = | 941 vr::Mat4f eye_view_matrix; |
904 MatrixMul(gvr_api_->GetEyeFromHeadMatrix(eye), head_pose); | 942 vr::Mat4f eye_matrix; |
| 943 GvrMatToMatf(gvr_api_->GetEyeFromHeadMatrix(eye), &eye_matrix); |
| 944 vr::MatrixMul(eye_matrix, head_pose, &eye_view_matrix); |
905 | 945 |
906 gvr::Recti pixel_rect = | 946 gvr::Rectf gvr_rect = buffer_viewport_->GetSourceUv(); |
907 CalculatePixelSpaceRect(render_size, buffer_viewport_->GetSourceUv()); | 947 gfx::RectF rect(gvr_rect.left, gvr_rect.top, gvr_rect.right - gvr_rect.left, |
908 glViewport(pixel_rect.left, pixel_rect.bottom, | 948 gvr_rect.bottom - gvr_rect.top); |
909 pixel_rect.right - pixel_rect.left, | 949 gfx::Rect pixel_rect = CalculatePixelSpaceRect(render_size, rect); |
910 pixel_rect.top - pixel_rect.bottom); | 950 glViewport(pixel_rect.x(), pixel_rect.y(), pixel_rect.width(), |
| 951 pixel_rect.height()); |
911 | 952 |
912 const gvr::Mat4f render_matrix = | 953 vr::Mat4f render_matrix; |
913 MatrixMul(PerspectiveMatrixFromView(buffer_viewport_->GetSourceFov(), | 954 vr::Mat4f perspective_matrix; |
914 kZNear, kZFar), | 955 gvr::Rectf fov = buffer_viewport_->GetSourceFov(); |
915 eye_view_matrix); | 956 vr::PerspectiveMatrixFromView( |
| 957 {fov.left, fov.top, fov.right - fov.left, fov.bottom - fov.top}, kZNear, |
| 958 kZFar, &perspective_matrix); |
| 959 vr::MatrixMul(perspective_matrix, eye_view_matrix, &render_matrix); |
916 | 960 |
917 DrawElements(render_matrix, elementsInDrawOrder); | 961 DrawElements(render_matrix, elementsInDrawOrder); |
918 if (draw_cursor) { | 962 if (draw_cursor) { |
919 DrawCursor(render_matrix); | 963 DrawCursor(render_matrix); |
920 DrawController(render_matrix); | 964 DrawController(render_matrix); |
921 } | 965 } |
922 } | 966 } |
923 } | 967 } |
924 | 968 |
925 void VrShellGl::DrawElements( | 969 void VrShellGl::DrawElements( |
926 const gvr::Mat4f& view_proj_matrix, | 970 const vr::Mat4f& view_proj_matrix, |
927 const std::vector<const ContentRectangle*>& elements) { | 971 const std::vector<const ContentRectangle*>& elements) { |
928 for (const auto* rect : elements) { | 972 for (const auto* rect : elements) { |
929 gvr::Mat4f transform = MatrixMul(view_proj_matrix, rect->TransformMatrix()); | 973 vr::Mat4f transform; |
| 974 vr::MatrixMul(view_proj_matrix, rect->TransformMatrix(), &transform); |
930 | 975 |
931 switch (rect->fill) { | 976 switch (rect->fill) { |
932 case Fill::SPRITE: { | 977 case Fill::SPRITE: { |
933 Rectf copy_rect; | 978 gfx::RectF copy_rect( |
934 copy_rect.x = static_cast<float>(rect->copy_rect.x) / ui_tex_css_width_; | 979 static_cast<float>(rect->copy_rect.x()) / ui_tex_css_width_, |
935 copy_rect.y = | 980 static_cast<float>(rect->copy_rect.y()) / ui_tex_css_height_, |
936 static_cast<float>(rect->copy_rect.y) / ui_tex_css_height_; | 981 static_cast<float>(rect->copy_rect.width()) / ui_tex_css_width_, |
937 copy_rect.width = | 982 static_cast<float>(rect->copy_rect.height()) / ui_tex_css_height_); |
938 static_cast<float>(rect->copy_rect.width) / ui_tex_css_width_; | |
939 copy_rect.height = | |
940 static_cast<float>(rect->copy_rect.height) / ui_tex_css_height_; | |
941 jint texture_handle = ui_texture_id_; | 983 jint texture_handle = ui_texture_id_; |
942 vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad( | 984 vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad( |
943 texture_handle, transform, copy_rect, rect->computed_opacity); | 985 texture_handle, transform, copy_rect, rect->computed_opacity); |
944 break; | 986 break; |
945 } | 987 } |
946 case Fill::OPAQUE_GRADIENT: { | 988 case Fill::OPAQUE_GRADIENT: { |
947 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); | 989 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); |
948 vr_shell_renderer_->GetGradientQuadRenderer()->Draw( | 990 vr_shell_renderer_->GetGradientQuadRenderer()->Draw( |
949 transform, rect->edge_color, rect->center_color, | 991 transform, rect->edge_color, rect->center_color, |
950 rect->computed_opacity); | 992 rect->computed_opacity); |
951 break; | 993 break; |
952 } | 994 } |
953 case Fill::GRID_GRADIENT: { | 995 case Fill::GRID_GRADIENT: { |
954 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); | 996 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); |
955 vr_shell_renderer_->GetGradientGridRenderer()->Draw( | 997 vr_shell_renderer_->GetGradientGridRenderer()->Draw( |
956 transform, rect->edge_color, rect->center_color, | 998 transform, rect->edge_color, rect->center_color, |
957 rect->gridline_count, rect->computed_opacity); | 999 rect->gridline_count, rect->computed_opacity); |
958 break; | 1000 break; |
959 } | 1001 } |
960 case Fill::CONTENT: { | 1002 case Fill::CONTENT: { |
961 Rectf copy_rect = {0, 0, 1, 1}; | 1003 gfx::RectF copy_rect = {0, 0, 1, 1}; |
962 jint texture_handle = content_texture_id_; | 1004 jint texture_handle = content_texture_id_; |
963 vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad( | 1005 vr_shell_renderer_->GetTexturedQuadRenderer()->AddQuad( |
964 texture_handle, transform, copy_rect, rect->computed_opacity); | 1006 texture_handle, transform, copy_rect, rect->computed_opacity); |
965 break; | 1007 break; |
966 } | 1008 } |
967 default: | 1009 default: |
968 break; | 1010 break; |
969 } | 1011 } |
970 } | 1012 } |
971 | 1013 |
972 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); | 1014 vr_shell_renderer_->GetTexturedQuadRenderer()->Flush(); |
973 } | 1015 } |
974 | 1016 |
975 std::vector<const ContentRectangle*> VrShellGl::GetElementsInDrawOrder( | 1017 std::vector<const ContentRectangle*> VrShellGl::GetElementsInDrawOrder( |
976 const gvr::Mat4f& view_matrix, | 1018 const vr::Mat4f& view_matrix, |
977 const std::vector<const ContentRectangle*>& elements) { | 1019 const std::vector<const ContentRectangle*>& elements) { |
978 typedef std::pair<float, const ContentRectangle*> DistanceElementPair; | 1020 typedef std::pair<float, const ContentRectangle*> DistanceElementPair; |
979 std::vector<DistanceElementPair> zOrderedElementPairs; | 1021 std::vector<DistanceElementPair> zOrderedElementPairs; |
980 zOrderedElementPairs.reserve(elements.size()); | 1022 zOrderedElementPairs.reserve(elements.size()); |
981 | 1023 |
982 for (const auto* element : elements) { | 1024 for (const auto* element : elements) { |
983 // Distance is the abs(z) value in view space. | 1025 // Distance is the abs(z) value in view space. |
984 gvr::Vec3f element_position = GetTranslation(element->TransformMatrix()); | 1026 gfx::Vector3dF element_position = |
| 1027 vr::GetTranslation(element->TransformMatrix()); |
| 1028 |
985 float distance = | 1029 float distance = |
986 std::fabs(MatrixVectorMul(view_matrix, element_position).z); | 1030 std::fabs(vr::MatrixVectorMul(view_matrix, element_position).z()); |
987 zOrderedElementPairs.push_back(std::make_pair(distance, element)); | 1031 zOrderedElementPairs.push_back(std::make_pair(distance, element)); |
988 } | 1032 } |
989 | 1033 |
990 // Sort elements primarily based on their draw phase (lower draw phase first) | 1034 // Sort elements primarily based on their draw phase (lower draw phase first) |
991 // and secondarily based on their distance (larger distance first). | 1035 // and secondarily based on their distance (larger distance first). |
992 std::sort( | 1036 std::sort( |
993 zOrderedElementPairs.begin(), zOrderedElementPairs.end(), | 1037 zOrderedElementPairs.begin(), zOrderedElementPairs.end(), |
994 [](const DistanceElementPair& first, const DistanceElementPair& second) { | 1038 [](const DistanceElementPair& first, const DistanceElementPair& second) { |
995 if (first.second->draw_phase != second.second->draw_phase) { | 1039 if (first.second->draw_phase != second.second->draw_phase) { |
996 return first.second->draw_phase < second.second->draw_phase; | 1040 return first.second->draw_phase < second.second->draw_phase; |
997 } else { | 1041 } else { |
998 return first.first > second.first; | 1042 return first.first > second.first; |
999 } | 1043 } |
1000 }); | 1044 }); |
1001 | 1045 |
1002 std::vector<const ContentRectangle*> zOrderedElements; | 1046 std::vector<const ContentRectangle*> zOrderedElements; |
1003 zOrderedElements.reserve(elements.size()); | 1047 zOrderedElements.reserve(elements.size()); |
1004 for (auto distanceElementPair : zOrderedElementPairs) { | 1048 for (auto distanceElementPair : zOrderedElementPairs) { |
1005 zOrderedElements.push_back(distanceElementPair.second); | 1049 zOrderedElements.push_back(distanceElementPair.second); |
1006 } | 1050 } |
1007 return zOrderedElements; | 1051 return zOrderedElements; |
1008 } | 1052 } |
1009 | 1053 |
1010 void VrShellGl::DrawCursor(const gvr::Mat4f& render_matrix) { | 1054 void VrShellGl::DrawCursor(const vr::Mat4f& render_matrix) { |
1011 gvr::Mat4f mat; | 1055 vr::Mat4f mat; |
1012 SetIdentityM(mat); | 1056 vr::SetIdentityM(&mat); |
1013 | 1057 |
1014 // Draw the reticle. | 1058 // Draw the reticle. |
1015 | 1059 |
1016 // Scale the pointer to have a fixed FOV size at any distance. | 1060 // Scale the pointer to have a fixed FOV size at any distance. |
1017 const float eye_to_target = Distance(target_point_, kOrigin); | 1061 const float eye_to_target = |
1018 ScaleM(mat, mat, kReticleWidth * eye_to_target, | 1062 std::sqrt(target_point_.SquaredDistanceTo(kOrigin)); |
1019 kReticleHeight * eye_to_target, 1.0f); | 1063 vr::ScaleM( |
| 1064 mat, |
| 1065 {kReticleWidth * eye_to_target, kReticleHeight * eye_to_target, 1.0f}, |
| 1066 &mat); |
1020 | 1067 |
1021 gvr::Quatf rotation; | 1068 vr::Quatf rotation; |
1022 if (target_element_ != nullptr) { | 1069 if (target_element_ != nullptr) { |
1023 // Make the reticle planar to the element it's hitting. | 1070 // Make the reticle planar to the element it's hitting. |
1024 rotation = GetRotationFromZAxis(target_element_->GetNormal()); | 1071 rotation = GetRotationFromZAxis(target_element_->GetNormal()); |
1025 } else { | 1072 } else { |
1026 // Rotate the cursor to directly face the eyes. | 1073 // Rotate the cursor to directly face the eyes. |
1027 rotation = GetRotationFromZAxis(target_point_); | 1074 rotation = GetRotationFromZAxis(target_point_ - kOrigin); |
1028 } | 1075 } |
1029 mat = MatrixMul(QuatToMatrix(rotation), mat); | 1076 vr::Mat4f rotation_mat; |
| 1077 vr::QuatToMatrix(rotation, &rotation_mat); |
| 1078 vr::MatrixMul(rotation_mat, mat, &mat); |
1030 | 1079 |
| 1080 gfx::Point3F target_point = ScalePoint(target_point_, kReticleOffset); |
1031 // Place the pointer slightly in front of the plane intersection point. | 1081 // Place the pointer slightly in front of the plane intersection point. |
1032 TranslateM(mat, mat, target_point_.x * kReticleOffset, | 1082 vr::TranslateM(mat, target_point - kOrigin, &mat); |
1033 target_point_.y * kReticleOffset, | |
1034 target_point_.z * kReticleOffset); | |
1035 | 1083 |
1036 gvr::Mat4f transform = MatrixMul(render_matrix, mat); | 1084 vr::Mat4f transform; |
| 1085 vr::MatrixMul(render_matrix, mat, &transform); |
1037 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); | 1086 vr_shell_renderer_->GetReticleRenderer()->Draw(transform); |
1038 | 1087 |
1039 // Draw the laser. | 1088 // Draw the laser. |
1040 | 1089 |
1041 // Find the length of the beam (from hand to target). | 1090 // Find the length of the beam (from hand to target). |
1042 const float laser_length = Distance(kHandPosition, target_point_); | 1091 const float laser_length = |
| 1092 std::sqrt(kHandPosition.SquaredDistanceTo(target_point)); |
1043 | 1093 |
1044 // Build a beam, originating from the origin. | 1094 // Build a beam, originating from the origin. |
1045 SetIdentityM(mat); | 1095 vr::SetIdentityM(&mat); |
1046 | 1096 |
1047 // Move the beam half its height so that its end sits on the origin. | 1097 // Move the beam half its height so that its end sits on the origin. |
1048 TranslateM(mat, mat, 0.0f, 0.5f, 0.0f); | 1098 vr::TranslateM(mat, {0.0f, 0.5f, 0.0f}, &mat); |
1049 ScaleM(mat, mat, kLaserWidth, laser_length, 1); | 1099 vr::ScaleM(mat, {kLaserWidth, laser_length, 1}, &mat); |
1050 | 1100 |
1051 // Tip back 90 degrees to flat, pointing at the scene. | 1101 // Tip back 90 degrees to flat, pointing at the scene. |
1052 const gvr::Quatf q = QuatFromAxisAngle({1.0f, 0.0f, 0.0f}, -M_PI / 2); | 1102 const vr::Quatf quat = vr::QuatFromAxisAngle({1.0f, 0.0f, 0.0f, -M_PI / 2}); |
1053 mat = MatrixMul(QuatToMatrix(q), mat); | 1103 vr::QuatToMatrix(quat, &rotation_mat); |
| 1104 vr::MatrixMul(rotation_mat, mat, &mat); |
1054 | 1105 |
1055 const gvr::Vec3f beam_direction = {target_point_.x - kHandPosition.x, | 1106 const gfx::Vector3dF beam_direction = target_point_ - kHandPosition; |
1056 target_point_.y - kHandPosition.y, | 1107 |
1057 target_point_.z - kHandPosition.z}; | 1108 vr::Mat4f beam_direction_mat; |
1058 const gvr::Mat4f beam_direction_mat = | 1109 vr::QuatToMatrix(GetRotationFromZAxis(beam_direction), &beam_direction_mat); |
1059 QuatToMatrix(GetRotationFromZAxis(beam_direction)); | |
1060 | 1110 |
1061 // Render multiple faces to make the laser appear cylindrical. | 1111 // Render multiple faces to make the laser appear cylindrical. |
1062 const int faces = 4; | 1112 const int faces = 4; |
1063 for (int i = 0; i < faces; i++) { | 1113 for (int i = 0; i < faces; i++) { |
1064 // Rotate around Z. | 1114 // Rotate around Z. |
1065 const float angle = M_PI * 2 * i / faces; | 1115 const float angle = M_PI * 2 * i / faces; |
1066 const gvr::Quatf rot = QuatFromAxisAngle({0.0f, 0.0f, 1.0f}, angle); | 1116 const vr::Quatf rot = vr::QuatFromAxisAngle({0.0f, 0.0f, 1.0f, angle}); |
1067 gvr::Mat4f face_transform = MatrixMul(QuatToMatrix(rot), mat); | 1117 vr::Mat4f face_transform; |
1068 | 1118 vr::QuatToMatrix(rot, &face_transform); |
| 1119 vr::MatrixMul(face_transform, mat, &face_transform); |
1069 // Orient according to target direction. | 1120 // Orient according to target direction. |
1070 face_transform = MatrixMul(beam_direction_mat, face_transform); | 1121 vr::MatrixMul(beam_direction_mat, face_transform, &face_transform); |
1071 | 1122 |
1072 // Move the beam origin to the hand. | 1123 // Move the beam origin to the hand. |
1073 TranslateM(face_transform, face_transform, kHandPosition.x, kHandPosition.y, | 1124 vr::TranslateM(face_transform, kHandPosition - kOrigin, &face_transform); |
1074 kHandPosition.z); | |
1075 | 1125 |
1076 transform = MatrixMul(render_matrix, face_transform); | 1126 vr::MatrixMul(render_matrix, face_transform, &transform); |
1077 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); | 1127 vr_shell_renderer_->GetLaserRenderer()->Draw(transform); |
1078 } | 1128 } |
1079 } | 1129 } |
1080 | 1130 |
1081 void VrShellGl::DrawController(const gvr::Mat4f& view_proj_matrix) { | 1131 void VrShellGl::DrawController(const vr::Mat4f& view_proj_matrix) { |
1082 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) | 1132 if (!vr_shell_renderer_->GetControllerRenderer()->IsSetUp()) |
1083 return; | 1133 return; |
1084 auto transform = MatrixMul(view_proj_matrix, controller_->GetTransform()); | 1134 vr::Mat4f controller_transform; |
| 1135 controller_->GetTransform(&controller_transform); |
| 1136 vr::Mat4f transform; |
| 1137 vr::MatrixMul(view_proj_matrix, controller_transform, &transform); |
1085 auto state = controller_->GetModelState(); | 1138 auto state = controller_->GetModelState(); |
1086 vr_shell_renderer_->GetControllerRenderer()->Draw(state, transform); | 1139 vr_shell_renderer_->GetControllerRenderer()->Draw(state, transform); |
1087 } | 1140 } |
1088 | 1141 |
1089 bool VrShellGl::ShouldDrawWebVr() { | 1142 bool VrShellGl::ShouldDrawWebVr() { |
1090 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled(); | 1143 return web_vr_mode_ && scene_->GetWebVrRenderingEnabled(); |
1091 } | 1144 } |
1092 | 1145 |
1093 void VrShellGl::DrawWebVr() { | 1146 void VrShellGl::DrawWebVr() { |
1094 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); | 1147 TRACE_EVENT0("gpu", "VrShellGl::DrawWebVr"); |
1095 // Don't need face culling, depth testing, blending, etc. Turn it all off. | 1148 // Don't need face culling, depth testing, blending, etc. Turn it all off. |
1096 glDisable(GL_CULL_FACE); | 1149 glDisable(GL_CULL_FACE); |
1097 glDepthMask(GL_FALSE); | 1150 glDepthMask(GL_FALSE); |
1098 glDisable(GL_DEPTH_TEST); | 1151 glDisable(GL_DEPTH_TEST); |
1099 glDisable(GL_SCISSOR_TEST); | 1152 glDisable(GL_SCISSOR_TEST); |
1100 glDisable(GL_BLEND); | 1153 glDisable(GL_BLEND); |
1101 glDisable(GL_POLYGON_OFFSET_FILL); | 1154 glDisable(GL_POLYGON_OFFSET_FILL); |
1102 | 1155 |
1103 // We're redrawing over the entire viewport, but it's generally more | 1156 // We're redrawing over the entire viewport, but it's generally more |
1104 // efficient on mobile tiling GPUs to clear anyway as a hint that | 1157 // efficient on mobile tiling GPUs to clear anyway as a hint that |
1105 // we're done with the old content. TODO(klausw,crbug.com/700389): | 1158 // we're done with the old content. TODO(klausw,crbug.com/700389): |
1106 // investigate using glDiscardFramebufferEXT here since that's more | 1159 // investigate using glDiscardFramebufferEXT here since that's more |
1107 // efficient on desktop, but it would need a capability check since | 1160 // efficient on desktop, but it would need a capability check since |
1108 // it's not supported on older devices such as Nexus 5X. | 1161 // it's not supported on older devices such as Nexus 5X. |
1109 glClear(GL_COLOR_BUFFER_BIT); | 1162 glClear(GL_COLOR_BUFFER_BIT); |
1110 | 1163 |
1111 glViewport(0, 0, webvr_surface_size_.width, webvr_surface_size_.height); | 1164 glViewport(0, 0, webvr_surface_size_.width(), webvr_surface_size_.height()); |
1112 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_); | 1165 vr_shell_renderer_->GetWebVrRenderer()->Draw(webvr_texture_id_); |
1113 } | 1166 } |
1114 | 1167 |
1115 void VrShellGl::OnTriggerEvent() { | 1168 void VrShellGl::OnTriggerEvent() { |
1116 // Set a flag to handle this on the render thread at the next frame. | 1169 // Set a flag to handle this on the render thread at the next frame. |
1117 touch_pending_ = true; | 1170 touch_pending_ = true; |
1118 } | 1171 } |
1119 | 1172 |
1120 void VrShellGl::OnPause() { | 1173 void VrShellGl::OnPause() { |
1121 vsync_task_.Cancel(); | 1174 vsync_task_.Cancel(); |
1122 controller_->OnPause(); | 1175 controller_->OnPause(); |
1123 gvr_api_->PauseTracking(); | 1176 gvr_api_->PauseTracking(); |
1124 } | 1177 } |
1125 | 1178 |
1126 void VrShellGl::OnResume() { | 1179 void VrShellGl::OnResume() { |
1127 gvr_api_->RefreshViewerProfile(); | 1180 gvr_api_->RefreshViewerProfile(); |
1128 gvr_api_->ResumeTracking(); | 1181 gvr_api_->ResumeTracking(); |
1129 controller_->OnResume(); | 1182 controller_->OnResume(); |
1130 if (ready_to_draw_) { | 1183 if (ready_to_draw_) { |
1131 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); | 1184 vsync_task_.Reset(base::Bind(&VrShellGl::OnVSync, base::Unretained(this))); |
1132 OnVSync(); | 1185 OnVSync(); |
1133 } | 1186 } |
1134 } | 1187 } |
1135 | 1188 |
1136 void VrShellGl::SetWebVrMode(bool enabled) { | 1189 void VrShellGl::SetWebVrMode(bool enabled) { |
1137 web_vr_mode_ = enabled; | 1190 web_vr_mode_ = enabled; |
1138 } | 1191 } |
1139 | 1192 |
1140 void VrShellGl::UpdateWebVRTextureBounds(int16_t frame_index, | 1193 void VrShellGl::UpdateWebVRTextureBounds(int16_t frame_index, |
1141 const gvr::Rectf& left_bounds, | 1194 const gfx::RectF& left_bounds, |
1142 const gvr::Rectf& right_bounds, | 1195 const gfx::RectF& right_bounds, |
1143 const gvr::Sizei& source_size) { | 1196 const gfx::Size& source_size) { |
1144 if (frame_index < 0) { | 1197 if (frame_index < 0) { |
1145 webvr_left_viewport_->SetSourceUv(left_bounds); | 1198 gvr::Rectf left = {left_bounds.x(), left_bounds.right(), |
1146 webvr_right_viewport_->SetSourceUv(right_bounds); | 1199 left_bounds.bottom(), left_bounds.y()}; |
| 1200 webvr_left_viewport_->SetSourceUv(left); |
| 1201 gvr::Rectf right = {right_bounds.x(), right_bounds.right(), |
| 1202 right_bounds.bottom(), right_bounds.y()}; |
| 1203 webvr_right_viewport_->SetSourceUv(right); |
1147 CreateOrResizeWebVRSurface(source_size); | 1204 CreateOrResizeWebVRSurface(source_size); |
1148 } else { | 1205 } else { |
1149 pending_bounds_.emplace( | 1206 pending_bounds_.emplace( |
1150 frame_index, WebVrBounds(left_bounds, right_bounds, source_size)); | 1207 frame_index, WebVrBounds(left_bounds, right_bounds, source_size)); |
1151 } | 1208 } |
1152 } | 1209 } |
1153 | 1210 |
1154 void VrShellGl::ContentBoundsChanged(int width, int height) { | 1211 void VrShellGl::ContentBoundsChanged(int width, int height) { |
1155 TRACE_EVENT0("gpu", "VrShellGl::ContentBoundsChanged"); | 1212 TRACE_EVENT0("gpu", "VrShellGl::ContentBoundsChanged"); |
1156 content_tex_css_width_ = width; | 1213 content_tex_css_width_ = width; |
1157 content_tex_css_height_ = height; | 1214 content_tex_css_height_ = height; |
1158 } | 1215 } |
1159 | 1216 |
1160 void VrShellGl::ContentPhysicalBoundsChanged(int width, int height) { | 1217 void VrShellGl::ContentPhysicalBoundsChanged(int width, int height) { |
1161 if (content_surface_texture_.get()) | 1218 if (content_surface_texture_.get()) |
1162 content_surface_texture_->SetDefaultBufferSize(width, height); | 1219 content_surface_texture_->SetDefaultBufferSize(width, height); |
1163 content_tex_physical_size_.width = width; | 1220 content_tex_physical_size_.set_width(width); |
1164 content_tex_physical_size_.height = height; | 1221 content_tex_physical_size_.set_height(height); |
1165 } | 1222 } |
1166 | 1223 |
1167 void VrShellGl::UIBoundsChanged(int width, int height) { | 1224 void VrShellGl::UIBoundsChanged(int width, int height) { |
1168 ui_tex_css_width_ = width; | 1225 ui_tex_css_width_ = width; |
1169 ui_tex_css_height_ = height; | 1226 ui_tex_css_height_ = height; |
1170 } | 1227 } |
1171 | 1228 |
1172 void VrShellGl::UIPhysicalBoundsChanged(int width, int height) { | 1229 void VrShellGl::UIPhysicalBoundsChanged(int width, int height) { |
1173 if (ui_surface_texture_.get()) | 1230 if (ui_surface_texture_.get()) |
1174 ui_surface_texture_->SetDefaultBufferSize(width, height); | 1231 ui_surface_texture_->SetDefaultBufferSize(width, height); |
1175 ui_tex_physical_size_.width = width; | 1232 ui_tex_physical_size_.set_width(width); |
1176 ui_tex_physical_size_.height = height; | 1233 ui_tex_physical_size_.set_height(height); |
1177 } | 1234 } |
1178 | 1235 |
1179 base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() { | 1236 base::WeakPtr<VrShellGl> VrShellGl::GetWeakPtr() { |
1180 return weak_ptr_factory_.GetWeakPtr(); | 1237 return weak_ptr_factory_.GetWeakPtr(); |
1181 } | 1238 } |
1182 | 1239 |
1183 void VrShellGl::SetControllerModel(std::unique_ptr<VrControllerModel> model) { | 1240 void VrShellGl::SetControllerModel(std::unique_ptr<VrControllerModel> model) { |
1184 vr_shell_renderer_->GetControllerRenderer()->SetUp(std::move(model)); | 1241 vr_shell_renderer_->GetControllerRenderer()->SetUp(std::move(model)); |
1185 } | 1242 } |
1186 | 1243 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1252 void VrShellGl::UpdateScene(std::unique_ptr<base::ListValue> commands) { | 1309 void VrShellGl::UpdateScene(std::unique_ptr<base::ListValue> commands) { |
1253 scene_->HandleCommands(std::move(commands), base::TimeTicks::Now()); | 1310 scene_->HandleCommands(std::move(commands), base::TimeTicks::Now()); |
1254 } | 1311 } |
1255 | 1312 |
1256 void VrShellGl::SendVSync(base::TimeDelta time, | 1313 void VrShellGl::SendVSync(base::TimeDelta time, |
1257 const GetVSyncCallback& callback) { | 1314 const GetVSyncCallback& callback) { |
1258 uint8_t frame_index = frame_index_++; | 1315 uint8_t frame_index = frame_index_++; |
1259 | 1316 |
1260 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); | 1317 TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); |
1261 | 1318 |
1262 gvr::Mat4f head_mat; | 1319 vr::Mat4f head_mat; |
1263 device::mojom::VRPosePtr pose = | 1320 device::mojom::VRPosePtr pose = |
1264 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat); | 1321 device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat); |
1265 | 1322 |
1266 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; | 1323 webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; |
1267 | 1324 |
1268 callback.Run(std::move(pose), time, frame_index, | 1325 callback.Run(std::move(pose), time, frame_index, |
1269 device::mojom::VRVSyncProvider::Status::SUCCESS); | 1326 device::mojom::VRVSyncProvider::Status::SUCCESS); |
1270 } | 1327 } |
1271 | 1328 |
1272 void VrShellGl::CreateVRDisplayInfo( | 1329 void VrShellGl::CreateVRDisplayInfo( |
1273 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, | 1330 const base::Callback<void(device::mojom::VRDisplayInfoPtr)>& callback, |
1274 uint32_t device_id) { | 1331 uint32_t device_id) { |
1275 // This assumes that the initial webvr_surface_size_ was set to the | 1332 // This assumes that the initial webvr_surface_size_ was set to the |
1276 // appropriate recommended render resolution as the default size during | 1333 // appropriate recommended render resolution as the default size during |
1277 // InitializeGl. Revisit if the initialization order changes. | 1334 // InitializeGl. Revisit if the initialization order changes. |
1278 device::mojom::VRDisplayInfoPtr info = | 1335 device::mojom::VRDisplayInfoPtr info = |
1279 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), | 1336 device::GvrDelegate::CreateVRDisplayInfo(gvr_api_.get(), |
1280 webvr_surface_size_, device_id); | 1337 webvr_surface_size_, device_id); |
1281 main_thread_task_runner_->PostTask( | 1338 main_thread_task_runner_->PostTask( |
1282 FROM_HERE, | 1339 FROM_HERE, |
1283 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); | 1340 base::Bind(&RunVRDisplayInfoCallback, callback, base::Passed(&info))); |
1284 } | 1341 } |
1285 | 1342 |
1286 } // namespace vr_shell | 1343 } // namespace vr_shell |
OLD | NEW |