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" |
11 #include "chrome/browser/android/vr_shell/vr_gl_util.h" | 11 #include "chrome/browser/android/vr_shell/vr_gl_util.h" |
12 #include "chrome/browser/android/vr_shell/vr_math.h" | 12 #include "chrome/browser/android/vr_shell/vr_math.h" |
13 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" | 13 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" |
14 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" | 14 #include "chrome/browser/android/vr_shell/vr_shell_renderer.h" |
| 15 #include "chrome/grit/generated_resources.h" |
15 #include "content/public/browser/android/content_view_core.h" | 16 #include "content/public/browser/android/content_view_core.h" |
16 #include "content/public/browser/render_widget_host.h" | 17 #include "content/public/browser/render_widget_host.h" |
17 #include "content/public/browser/render_widget_host_view.h" | 18 #include "content/public/browser/render_widget_host_view.h" |
18 #include "content/public/browser/web_contents.h" | 19 #include "content/public/browser/web_contents.h" |
19 #include "jni/VrShell_jni.h" | 20 #include "jni/VrShell_jni.h" |
20 #include "ui/android/view_android.h" | 21 #include "ui/android/view_android.h" |
21 #include "ui/android/window_android.h" | 22 #include "ui/android/window_android.h" |
| 23 #include "ui/base/l10n/l10n_util.h" |
22 #include "ui/gl/gl_bindings.h" | 24 #include "ui/gl/gl_bindings.h" |
23 #include "ui/gl/init/gl_factory.h" | 25 #include "ui/gl/init/gl_factory.h" |
24 | 26 |
25 using base::android::JavaParamRef; | 27 using base::android::JavaParamRef; |
26 | 28 |
27 namespace { | 29 namespace { |
28 // Constant taken from treasure_hunt demo. | 30 // Constant taken from treasure_hunt demo. |
29 static constexpr long kPredictionTimeWithoutVsyncNanos = 50000000; | 31 static constexpr long kPredictionTimeWithoutVsyncNanos = 50000000; |
30 | 32 |
31 static constexpr float kZNear = 0.1f; | 33 static constexpr float kZNear = 0.1f; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 } | 119 } |
118 | 120 |
119 void VrShell::GvrInit(JNIEnv* env, | 121 void VrShell::GvrInit(JNIEnv* env, |
120 const JavaParamRef<jobject>& obj, | 122 const JavaParamRef<jobject>& obj, |
121 jlong native_gvr_api) { | 123 jlong native_gvr_api) { |
122 gvr_api_ = | 124 gvr_api_ = |
123 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); | 125 gvr::GvrApi::WrapNonOwned(reinterpret_cast<gvr_context*>(native_gvr_api)); |
124 | 126 |
125 if (delegate_) | 127 if (delegate_) |
126 delegate_->OnVrShellReady(this); | 128 delegate_->OnVrShellReady(this); |
| 129 |
| 130 // We can't currently draw text in GL content due to a prerequisite |
| 131 // patch not being ready yet. For now, we're using compiled-in |
| 132 // bitmaps instead as a placeholder, their content matches the |
| 133 // strings in generated_resources.grd. For now, just look up the |
| 134 // string resources here to confirm they are properly integrated. |
| 135 // |
| 136 // TODO(klausw): use these to build localized message textures. |
| 137 CHECK(l10n_util::GetStringUTF8( |
| 138 IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_TRANSIENT).length() > 0); |
| 139 CHECK(l10n_util::GetStringUTF8( |
| 140 IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_PERMANENT).length() > 0); |
127 } | 141 } |
128 | 142 |
129 void VrShell::InitializeGl(JNIEnv* env, | 143 void VrShell::InitializeGl(JNIEnv* env, |
130 const JavaParamRef<jobject>& obj, | 144 const JavaParamRef<jobject>& obj, |
131 jint texture_data_handle) { | 145 jint texture_data_handle) { |
132 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || | 146 CHECK(gl::GetGLImplementation() != gl::kGLImplementationNone || |
133 gl::init::InitializeGLOneOff()); | 147 gl::init::InitializeGLOneOff()); |
134 | 148 |
135 content_texture_id_ = texture_data_handle; | 149 content_texture_id_ = texture_data_handle; |
136 gvr_api_->InitializeGl(); | 150 gvr_api_->InitializeGl(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 gvr::Frame frame = swap_chain_->AcquireFrame(); | 233 gvr::Frame frame = swap_chain_->AcquireFrame(); |
220 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); | 234 gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); |
221 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; | 235 target_time.monotonic_system_time_nanos += kPredictionTimeWithoutVsyncNanos; |
222 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); | 236 head_pose_ = gvr_api_->GetHeadPoseInStartSpace(target_time); |
223 | 237 |
224 // Bind back to the default framebuffer. | 238 // Bind back to the default framebuffer. |
225 frame.BindBuffer(0); | 239 frame.BindBuffer(0); |
226 | 240 |
227 if (webvr_mode_) { | 241 if (webvr_mode_) { |
228 DrawWebVr(); | 242 DrawWebVr(); |
| 243 if (!webvr_secure_origin_) { |
| 244 DrawWebVrOverlay(); |
| 245 } |
229 } else { | 246 } else { |
230 DrawVrShell(target_time.monotonic_system_time_nanos); | 247 DrawVrShell(target_time.monotonic_system_time_nanos); |
231 } | 248 } |
232 | 249 |
233 frame.Unbind(); | 250 frame.Unbind(); |
234 frame.Submit(*buffer_viewport_list_, head_pose_); | 251 frame.Submit(*buffer_viewport_list_, head_pose_); |
235 } | 252 } |
236 | 253 |
237 void VrShell::DrawVrShell(int64_t time) { | 254 void VrShell::DrawVrShell(int64_t time) { |
238 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; | 255 float screen_tilt = desktop_screen_tilt_ * M_PI / 180.0f; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 glDepthMask(GL_FALSE); | 398 glDepthMask(GL_FALSE); |
382 glDisable(GL_DEPTH_TEST); | 399 glDisable(GL_DEPTH_TEST); |
383 glDisable(GL_SCISSOR_TEST); | 400 glDisable(GL_SCISSOR_TEST); |
384 glDisable(GL_BLEND); | 401 glDisable(GL_BLEND); |
385 glDisable(GL_POLYGON_OFFSET_FILL); | 402 glDisable(GL_POLYGON_OFFSET_FILL); |
386 | 403 |
387 // Don't need to clear, since we're drawing over the entire render target. | 404 // Don't need to clear, since we're drawing over the entire render target. |
388 | 405 |
389 glViewport(0, 0, render_size_.width, render_size_.height); | 406 glViewport(0, 0, render_size_.width, render_size_.height); |
390 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); | 407 vr_shell_renderer_->GetWebVrRenderer()->Draw(content_texture_id_); |
| 408 } |
391 | 409 |
392 if (!webvr_secure_origin_) { | 410 void VrShell::DrawWebVrOverlay() { |
393 // TODO(klausw): Draw the insecure origin warning here. | 411 // Draw WebVR security warning overlays for each eye. This uses |
| 412 // the eye-from-head matrices but not the pose, goal is to place |
| 413 // the icons in an eye-relative position so that they follow along |
| 414 // with head rotations. |
| 415 |
| 416 gvr::Mat4f left_eye_view_matrix = |
| 417 gvr_api_->GetEyeFromHeadMatrix(GVR_LEFT_EYE); |
| 418 gvr::Mat4f right_eye_view_matrix = |
| 419 gvr_api_->GetEyeFromHeadMatrix(GVR_RIGHT_EYE); |
| 420 |
| 421 buffer_viewport_list_->GetBufferViewport(GVR_LEFT_EYE, |
| 422 buffer_viewport_.get()); |
| 423 DrawWebVrEye(left_eye_view_matrix, *buffer_viewport_); |
| 424 buffer_viewport_list_->GetBufferViewport(GVR_RIGHT_EYE, |
| 425 buffer_viewport_.get()); |
| 426 DrawWebVrEye(right_eye_view_matrix, *buffer_viewport_); |
| 427 } |
| 428 |
| 429 void VrShell::DrawWebVrEye(const gvr::Mat4f& view_matrix, |
| 430 const gvr::BufferViewport& params) { |
| 431 gvr::Recti pixel_rect = |
| 432 CalculatePixelSpaceRect(render_size_, params.GetSourceUv()); |
| 433 glViewport(pixel_rect.left, pixel_rect.bottom, |
| 434 pixel_rect.right - pixel_rect.left, |
| 435 pixel_rect.top - pixel_rect.bottom); |
| 436 glScissor(pixel_rect.left, pixel_rect.bottom, |
| 437 pixel_rect.right - pixel_rect.left, |
| 438 pixel_rect.top - pixel_rect.bottom); |
| 439 |
| 440 gvr::Mat4f projection_matrix = |
| 441 PerspectiveMatrixFromView(params.GetSourceFov(), kZNear, kZFar); |
| 442 |
| 443 // Draw insecure content warning icons. |
| 444 const float warning_depth = 0.7f; // Distance in meters. |
| 445 |
| 446 // Show IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_PERMANENT text. |
| 447 gvr::Mat4f icon_pos; |
| 448 SetIdentityM(icon_pos); |
| 449 const float small_icon_width = 0.15f * warning_depth; |
| 450 const float small_icon_height = small_icon_width / 2.0f; // 2:1 aspect. |
| 451 const float small_icon_angle = 20.0f * M_PI / 180.f; // Degrees to radians. |
| 452 ScaleM(icon_pos, icon_pos, small_icon_width, small_icon_height, 1.0f); |
| 453 TranslateM(icon_pos, icon_pos, 0.0f, 0.0f, -warning_depth); |
| 454 icon_pos = MatrixMul( |
| 455 QuatToMatrix(QuatFromAxisAngle(1.f, 0.f, 0.f, small_icon_angle)), |
| 456 icon_pos); |
| 457 gvr::Mat4f combined = MatrixMul(projection_matrix, |
| 458 MatrixMul(view_matrix, icon_pos)); |
| 459 vr_shell_renderer_->GetOverlayIconRenderer()->Draw( |
| 460 combined, ICON_INSECURE_PERMANENT); |
| 461 |
| 462 // Do we need to show the transient warning also? |
| 463 if (webvr_warning_frames_ == 0) { |
| 464 return; |
394 } | 465 } |
| 466 --webvr_warning_frames_; |
| 467 |
| 468 // Show IDS_WEBSITE_SETTINGS_INSECURE_WEBVR_CONTENT_TRANSIENT text. |
| 469 SetIdentityM(icon_pos); |
| 470 const float large_icon_width = 0.25f * warning_depth; |
| 471 const float large_icon_height = large_icon_width / 2.0f; // 2:1 aspect. |
| 472 ScaleM(icon_pos, icon_pos, large_icon_width, large_icon_height, 1.0f); |
| 473 TranslateM(icon_pos, icon_pos, 0.0f, 0.0f, -warning_depth); |
| 474 combined = MatrixMul(projection_matrix, |
| 475 MatrixMul(view_matrix, icon_pos)); |
| 476 vr_shell_renderer_->GetOverlayIconRenderer()->Draw( |
| 477 combined, ICON_INSECURE_TRANSIENT); |
395 } | 478 } |
396 | 479 |
397 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 480 void VrShell::OnPause(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
398 if (gvr_api_ == nullptr) | 481 if (gvr_api_ == nullptr) |
399 return; | 482 return; |
400 gvr_api_->PauseTracking(); | 483 gvr_api_->PauseTracking(); |
401 } | 484 } |
402 | 485 |
403 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 486 void VrShell::OnResume(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
404 if (gvr_api_ == nullptr) | 487 if (gvr_api_ == nullptr) |
(...skipping 18 matching lines...) Expand all Loading... |
423 // TODO(bshe): ui_text_width_ and ui_tex_height_ should be only used on render | 506 // TODO(bshe): ui_text_width_ and ui_tex_height_ should be only used on render |
424 // thread. | 507 // thread. |
425 ui_tex_width_ = width; | 508 ui_tex_width_ = width; |
426 ui_tex_height_ = height; | 509 ui_tex_height_ = height; |
427 } | 510 } |
428 | 511 |
429 void VrShell::SetWebVrMode(JNIEnv* env, | 512 void VrShell::SetWebVrMode(JNIEnv* env, |
430 const base::android::JavaParamRef<jobject>& obj, | 513 const base::android::JavaParamRef<jobject>& obj, |
431 bool enabled) { | 514 bool enabled) { |
432 webvr_mode_ = enabled; | 515 webvr_mode_ = enabled; |
| 516 if (enabled) { |
| 517 const int warning_seconds = 30; |
| 518 webvr_warning_frames_ = warning_seconds * 60; |
| 519 } else { |
| 520 webvr_warning_frames_ = 0; |
| 521 } |
433 } | 522 } |
434 | 523 |
435 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { | 524 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { |
436 webvr_secure_origin_ = secure_origin; | 525 webvr_secure_origin_ = secure_origin; |
437 } | 526 } |
438 | 527 |
439 void VrShell::SubmitWebVRFrame() { | 528 void VrShell::SubmitWebVRFrame() { |
440 } | 529 } |
441 | 530 |
442 void VrShell::UpdateWebVRTextureBounds( | 531 void VrShell::UpdateWebVRTextureBounds( |
(...skipping 28 matching lines...) Expand all Loading... |
471 const JavaParamRef<jobject>& content_web_contents, | 560 const JavaParamRef<jobject>& content_web_contents, |
472 jlong content_window_android) { | 561 jlong content_window_android) { |
473 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( | 562 content::ContentViewCore* c_core = content::ContentViewCore::FromWebContents( |
474 content::WebContents::FromJavaWebContents(content_web_contents)); | 563 content::WebContents::FromJavaWebContents(content_web_contents)); |
475 return reinterpret_cast<intptr_t>(new VrShell( | 564 return reinterpret_cast<intptr_t>(new VrShell( |
476 env, obj, c_core, | 565 env, obj, c_core, |
477 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); | 566 reinterpret_cast<ui::WindowAndroid*>(content_window_android))); |
478 } | 567 } |
479 | 568 |
480 } // namespace vr_shell | 569 } // namespace vr_shell |
OLD | NEW |