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