OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/vr_shell/vr_shell.h" | 5 #include "chrome/browser/android/vr_shell/vr_shell.h" |
6 | 6 |
7 #include <thread> | 7 #include <thread> |
8 | 8 |
9 #include "chrome/browser/android/vr_shell/ui_scene.h" | 9 #include "chrome/browser/android/vr_shell/ui_scene.h" |
10 #include "chrome/browser/android/vr_shell/vr_compositor.h" | 10 #include "chrome/browser/android/vr_shell/vr_compositor.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 static constexpr float kReticleOffset = 0.99f; | 65 static constexpr float kReticleOffset = 0.99f; |
66 | 66 |
67 // Limit the rendering distance of the reticle to the distance to a corner of | 67 // Limit the rendering distance of the reticle to the distance to a corner of |
68 // the content quad, times this value. This lets the rendering distance | 68 // the content quad, times this value. This lets the rendering distance |
69 // adjust according to content quad placement. | 69 // adjust according to content quad placement. |
70 static constexpr float kReticleDistanceMultiplier = 1.5f; | 70 static constexpr float kReticleDistanceMultiplier = 1.5f; |
71 | 71 |
72 // UI element 0 is the browser content rectangle. | 72 // UI element 0 is the browser content rectangle. |
73 static constexpr int kBrowserUiElementId = 0; | 73 static constexpr int kBrowserUiElementId = 0; |
74 | 74 |
75 // Positions and sizes of statically placed UI elements in the UI texture. | |
76 // TODO(klausw): replace the hardcoded positions with JS position/offset | |
77 // retrieval once the infrastructure for that is hooked up. | |
78 // | |
79 // UI is designed with 1 pixel = 1mm at 1m distance. It's rescaled to | |
80 // maintain the same angular resolution if placed closer or further. | |
81 // The warning overlays should be fairly close since they cut holes | |
82 // into geometry (they ignore the Z buffer), leading to odd effects | |
83 // if they are far away. | |
84 static constexpr vr_shell::Recti kWebVrWarningTransientRect = { | |
85 0, 128, 512, 256}; | |
86 static constexpr vr_shell::Recti kWebVrWarningPermanentRect = {0, 0, 512, 128}; | |
87 static constexpr float kWebVrWarningDistance = 0.7f; // meters | |
88 static constexpr float kWebVrWarningPermanentAngle = 16.3f; // degrees up | |
89 | |
75 vr_shell::VrShell* g_instance; | 90 vr_shell::VrShell* g_instance; |
76 | 91 |
77 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; | 92 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; |
78 | 93 |
79 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { | 94 float Distance(const gvr::Vec3f& vec1, const gvr::Vec3f& vec2) { |
80 float xdiff = (vec1.x - vec2.x); | 95 float xdiff = (vec1.x - vec2.x); |
81 float ydiff = (vec1.y - vec2.y); | 96 float ydiff = (vec1.y - vec2.y); |
82 float zdiff = (vec1.z - vec2.z); | 97 float zdiff = (vec1.z - vec2.z); |
83 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; | 98 float scale = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff; |
84 return std::sqrt(scale); | 99 return std::sqrt(scale); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 // TODO: Not sure what object_from_reference_matrix is. The new api removed | 317 // TODO: Not sure what object_from_reference_matrix is. The new api removed |
303 // it. For now, removing it seems working fine. | 318 // it. For now, removing it seems working fine. |
304 ApplyNeckModel(head_pose); | 319 ApplyNeckModel(head_pose); |
305 } | 320 } |
306 | 321 |
307 // Bind back to the default framebuffer. | 322 // Bind back to the default framebuffer. |
308 frame.BindBuffer(0); | 323 frame.BindBuffer(0); |
309 | 324 |
310 if (webvr_mode_) { | 325 if (webvr_mode_) { |
311 DrawWebVr(); | 326 DrawWebVr(); |
327 if (!webvr_secure_origin_) { | |
328 DrawWebVrOverlay(target_time.monotonic_system_time_nanos); | |
329 } | |
312 } else { | 330 } else { |
313 DrawVrShell(head_pose); | 331 DrawVrShell(head_pose); |
314 } | 332 } |
315 | 333 |
316 frame.Unbind(); | 334 frame.Unbind(); |
317 frame.Submit(*buffer_viewport_list_, head_pose); | 335 frame.Submit(*buffer_viewport_list_, head_pose); |
318 } | 336 } |
319 | 337 |
320 void VrShell::DrawVrShell(const gvr::Mat4f& head_pose) { | 338 void VrShell::DrawVrShell(const gvr::Mat4f& head_pose) { |
321 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 339 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar), | 383 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar), |
366 view_matrix); | 384 view_matrix); |
367 | 385 |
368 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | 386 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
369 | 387 |
370 // TODO(mthiesse): Draw order for transparency. | 388 // TODO(mthiesse): Draw order for transparency. |
371 DrawUI(render_matrix); | 389 DrawUI(render_matrix); |
372 DrawCursor(render_matrix); | 390 DrawCursor(render_matrix); |
373 } | 391 } |
374 | 392 |
393 bool VrShell::IsUiTextureReady() { | |
394 return ui_tex_width_ > 0 && ui_tex_height_ > 0; | |
395 } | |
396 | |
397 Rectf VrShell::MakeUiGlCopyRect(Recti pixel_rect) { | |
398 DCHECK(IsUiTextureReady()); | |
mthiesse
2016/10/03 17:47:30
This is for a security warning, so CHECK is probab
klausw
2016/10/03 20:55:12
Done. Without the CHECK it would fail with a "divi
| |
399 return Rectf({ | |
400 static_cast<float>(pixel_rect.x) / ui_tex_width_, | |
401 static_cast<float>(pixel_rect.y) / ui_tex_height_, | |
402 static_cast<float>(pixel_rect.width) / ui_tex_width_, | |
403 static_cast<float>(pixel_rect.height) / ui_tex_height_}); | |
404 } | |
405 | |
375 void VrShell::DrawUI(const gvr::Mat4f& render_matrix) { | 406 void VrShell::DrawUI(const gvr::Mat4f& render_matrix) { |
376 for (const auto& rect : scene_.GetUiElements()) { | 407 for (const auto& rect : scene_.GetUiElements()) { |
377 if (!rect->visible) { | 408 if (!rect->visible) { |
378 continue; | 409 continue; |
379 } | 410 } |
380 | 411 |
381 Rectf copy_rect; | 412 Rectf copy_rect; |
382 jint texture_handle; | 413 jint texture_handle; |
383 if (rect->id == kBrowserUiElementId) { | 414 if (rect->id == kBrowserUiElementId) { |
384 copy_rect = {0, 0, 1, 1}; | 415 copy_rect = {0, 0, 1, 1}; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 glDepthMask(GL_FALSE); | 492 glDepthMask(GL_FALSE); |
462 glDisable(GL_DEPTH_TEST); | 493 glDisable(GL_DEPTH_TEST); |
463 glDisable(GL_SCISSOR_TEST); | 494 glDisable(GL_SCISSOR_TEST); |
464 glDisable(GL_BLEND); | 495 glDisable(GL_BLEND); |
465 glDisable(GL_POLYGON_OFFSET_FILL); | 496 glDisable(GL_POLYGON_OFFSET_FILL); |
466 | 497 |
467 // Don't need to clear, since we're drawing over the entire render target. | 498 // Don't need to clear, since we're drawing over the entire render target. |
468 | 499 |
469 glViewport(0, 0, render_size_.width, render_size_.height); | 500 glViewport(0, 0, render_size_.width, render_size_.height); |
470 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 501 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); |
502 } | |
471 | 503 |
472 if (!webvr_secure_origin_) { | 504 void VrShell::DrawWebVrOverlay(int64_t present_time_nanos) { |
473 // TODO(klausw): Draw the insecure origin warning here. | 505 // Draw WebVR security warning overlays for each eye. This uses the |
506 // eye-from-head matrices but not the pose, goal is to place the icons in an | |
507 // eye-relative position so that they follow along with head rotations. | |
508 | |
509 gvr::Mat4f left_eye_view_matrix = | |
510 gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE); | |
511 gvr::Mat4f right_eye_view_matrix = | |
512 gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE); | |
513 | |
514 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, | |
515 buffer_viewport_.get()); | |
516 DrawWebVrEye(left_eye_view_matrix, *buffer_viewport_, present_time_nanos); | |
517 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, | |
518 buffer_viewport_.get()); | |
519 DrawWebVrEye(right_eye_view_matrix, *buffer_viewport_, present_time_nanos); | |
520 } | |
521 | |
522 void VrShell::DrawWebVrEye(const gvr::Mat4f& view_matrix, | |
523 const gvr::BufferViewport& params, | |
524 int64_t present_time_nanos) { | |
525 gvr::Recti pixel_rect = | |
526 CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); | |
527 glViewport(pixel_rect.left, pixel_rect.bottom, | |
528 pixel_rect.right - pixel_rect.left, | |
529 pixel_rect.top - pixel_rect.bottom); | |
530 glScissor(pixel_rect.left, pixel_rect.bottom, | |
531 pixel_rect.right - pixel_rect.left, | |
532 pixel_rect.top - pixel_rect.bottom); | |
533 | |
534 gvr::Mat4f projection_matrix = | |
535 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar); | |
536 | |
537 if (!IsUiTextureReady()) { | |
538 // If the UI texture hasn't been initialized yet, we can't draw the overlay. | |
539 return; | |
474 } | 540 } |
541 | |
542 // Show IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_PERMANENT text. | |
543 gvr::Mat4f icon_pos; | |
544 SetIdentityM(icon_pos); | |
545 const float small_icon_width = | |
546 kWebVrWarningPermanentRect.width / 1000.f * kWebVrWarningDistance; | |
mthiesse
2016/10/03 17:47:30
What is this 1000.0f factor?
klausw
2016/10/03 20:55:12
Added a comment:
// The UI is designed in pixel
| |
547 const float small_icon_height = | |
548 kWebVrWarningPermanentRect.height / 1000.f * kWebVrWarningDistance; | |
549 const float small_icon_angle = | |
550 kWebVrWarningPermanentAngle * M_PI / 180.f; // Degrees to radians. | |
551 ScaleM(icon_pos, icon_pos, small_icon_width, small_icon_height, 1.0f); | |
552 TranslateM(icon_pos, icon_pos, 0.0f, 0.0f, -kWebVrWarningDistance); | |
553 icon_pos = MatrixMul( | |
554 QuatToMatrix(QuatFromAxisAngle({1.f, 0.f, 0.f}, small_icon_angle)), | |
555 icon_pos); | |
556 gvr::Mat4f combined = MatrixMul(projection_matrix, | |
557 MatrixMul(view_matrix, icon_pos)); | |
558 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( | |
559 ui_texture_id_, combined, MakeUiGlCopyRect(kWebVrWarningPermanentRect)); | |
560 | |
561 // Check if we also need to show the transient warning. | |
562 if (present_time_nanos > webvr_warning_end_nanos_) { | |
563 return; | |
564 } | |
565 | |
566 // Show IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_TRANSIENT text. | |
567 SetIdentityM(icon_pos); | |
568 const float large_icon_width = | |
569 kWebVrWarningTransientRect.width / 1000.f * kWebVrWarningDistance; | |
570 const float large_icon_height = | |
571 kWebVrWarningTransientRect.height / 1000.f * kWebVrWarningDistance; | |
572 ScaleM(icon_pos, icon_pos, large_icon_width, large_icon_height, 1.0f); | |
573 TranslateM(icon_pos, icon_pos, 0.0f, 0.0f, -kWebVrWarningDistance); | |
574 combined = MatrixMul(projection_matrix, | |
575 MatrixMul(view_matrix, icon_pos)); | |
576 vr_shell_renderer_->GetTexturedQuadRenderer()->Draw( | |
577 ui_texture_id_, combined, MakeUiGlCopyRect(kWebVrWarningTransientRect)); | |
578 | |
475 } | 579 } |
476 | 580 |
477 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 581 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
478 if (gvr_api_ == nullptr) | 582 if (gvr_api_ == nullptr) |
479 return; | 583 return; |
480 gvr_api_->PauseTracking(); | 584 gvr_api_->PauseTracking(); |
481 } | 585 } |
482 | 586 |
483 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 587 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
484 if (gvr_api_ == nullptr) | 588 if (gvr_api_ == nullptr) |
(...skipping 26 matching lines...) Expand all Loading... | |
511 // TODO(bshe): ui_text_width_ and ui_tex_height_ should be only used on render | 615 // TODO(bshe): ui_text_width_ and ui_tex_height_ should be only used on render |
512 // thread. | 616 // thread. |
513 ui_tex_width_ = width; | 617 ui_tex_width_ = width; |
514 ui_tex_height_ = height; | 618 ui_tex_height_ = height; |
515 } | 619 } |
516 | 620 |
517 void VrShell::SetWebVrMode(JNIEnv* env, | 621 void VrShell::SetWebVrMode(JNIEnv* env, |
518 const base::android::JavaParamRef<jobject>& obj, | 622 const base::android::JavaParamRef<jobject>& obj, |
519 bool enabled) { | 623 bool enabled) { |
520 webvr_mode_ = enabled; | 624 webvr_mode_ = enabled; |
625 if (enabled) { | |
626 const int64_t warning_seconds = 30; | |
mthiesse
2016/10/03 17:47:30
Move constant to top of file.
klausw
2016/10/03 20:55:12
Done.
| |
627 int64_t now = gvr::GvrApi::GetTimePointNow().monotonic_system_time_nanos; | |
628 webvr_warning_end_nanos_ = now + warning_seconds * 1000 * 1000 * 1000; | |
mthiesse
2016/10/03 17:47:30
Extract constant for seconds to nanos.
klausw
2016/10/03 20:55:12
Done.
| |
629 } else { | |
630 webvr_warning_end_nanos_ = 0; | |
631 } | |
521 } | 632 } |
522 | 633 |
523 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { | 634 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { |
524 webvr_secure_origin_ = secure_origin; | 635 webvr_secure_origin_ = secure_origin; |
525 } | 636 } |
526 | 637 |
527 void VrShell::SubmitWebVRFrame() { | 638 void VrShell::SubmitWebVRFrame() { |
528 } | 639 } |
529 | 640 |
530 void VrShell::UpdateWebVRTextureBounds( | 641 void VrShell::UpdateWebVRTextureBounds( |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
593 content::WebContents::FromJavaWebContents(content_web_contents)); | 704 content::WebContents::FromJavaWebContents(content_web_contents)); |
594 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( | 705 content::ContentViewCore* ui_core = content::ContentViewCore::FromWebContents( |
595 content::WebContents::FromJavaWebContents(ui_web_contents)); | 706 content::WebContents::FromJavaWebContents(ui_web_contents)); |
596 return reinterpret_cast<intptr_t>(new VrShell( | 707 return reinterpret_cast<intptr_t>(new VrShell( |
597 env, obj, c_core, | 708 env, obj, c_core, |
598 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, | 709 reinterpret_cast<ui::WindowAndroid*>(content_window_android), ui_core, |
599 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); | 710 reinterpret_cast<ui::WindowAndroid*>(ui_window_android))); |
600 } | 711 } |
601 | 712 |
602 } // namespace vr_shell | 713 } // namespace vr_shell |
OLD | NEW |