Chromium Code Reviews| 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 <android/native_window_jni.h> | 7 #include <android/native_window_jni.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/android/jni_string.h" | 12 #include "base/android/jni_string.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/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
| 16 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
| 17 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "base/values.h" | 19 #include "base/values.h" |
| 20 #include "chrome/browser/android/tab_android.h" | 20 #include "chrome/browser/android/tab_android.h" |
| 21 #include "chrome/browser/android/vr_shell/android_ui_gesture_target.h" | 21 #include "chrome/browser/android/vr_shell/android_ui_gesture_target.h" |
| 22 #include "chrome/browser/android/vr_shell/ui_interface.h" | 22 #include "chrome/browser/android/vr_shell/ui_interface.h" |
| 23 #include "chrome/browser/android/vr_shell/vr_compositor.h" | 23 #include "chrome/browser/android/vr_shell/vr_compositor.h" |
| 24 #include "chrome/browser/android/vr_shell/vr_gl_thread.h" | 24 #include "chrome/browser/android/vr_shell/vr_gl_thread.h" |
| 25 #include "chrome/browser/android/vr_shell/vr_input_manager.h" | 25 #include "chrome/browser/android/vr_shell/vr_input_manager.h" |
| 26 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" | 26 #include "chrome/browser/android/vr_shell/vr_shell_delegate.h" |
| 27 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" | 27 #include "chrome/browser/android/vr_shell/vr_shell_gl.h" |
| 28 #include "chrome/browser/android/vr_shell/vr_shell_gpu_renderer.h" | |
| 28 #include "chrome/browser/android/vr_shell/vr_usage_monitor.h" | 29 #include "chrome/browser/android/vr_shell/vr_usage_monitor.h" |
| 29 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h" | 30 #include "chrome/browser/android/vr_shell/vr_web_contents_observer.h" |
| 30 #include "content/public/browser/navigation_controller.h" | 31 #include "content/public/browser/navigation_controller.h" |
| 31 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
| 32 #include "content/public/browser/render_widget_host.h" | 33 #include "content/public/browser/render_widget_host.h" |
| 33 #include "content/public/browser/render_widget_host_view.h" | 34 #include "content/public/browser/render_widget_host_view.h" |
| 34 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 35 #include "content/public/common/content_features.h" | 36 #include "content/public/common/content_features.h" |
| 36 #include "content/public/common/referrer.h" | 37 #include "content/public/common/referrer.h" |
| 37 #include "device/vr/android/gvr/gvr_device.h" | 38 #include "device/vr/android/gvr/gvr_device.h" |
| 38 #include "device/vr/android/gvr/gvr_device_provider.h" | 39 #include "device/vr/android/gvr/gvr_device_provider.h" |
| 39 #include "jni/VrShellImpl_jni.h" | 40 #include "jni/VrShellImpl_jni.h" |
| 40 #include "third_party/WebKit/public/platform/WebInputEvent.h" | 41 #include "third_party/WebKit/public/platform/WebInputEvent.h" |
| 41 #include "ui/android/view_android.h" | 42 #include "ui/android/view_android.h" |
| 42 #include "ui/android/window_android.h" | 43 #include "ui/android/window_android.h" |
| 43 #include "ui/base/page_transition_types.h" | 44 #include "ui/base/page_transition_types.h" |
| 44 #include "ui/display/display.h" | 45 #include "ui/display/display.h" |
| 45 #include "ui/display/screen.h" | 46 #include "ui/display/screen.h" |
| 46 #include "ui/gfx/transform.h" | 47 #include "ui/gfx/transform.h" |
| 47 #include "ui/gfx/transform_util.h" | 48 #include "ui/gfx/transform_util.h" |
| 48 | 49 |
| 50 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" | |
| 51 #include "content/browser/renderer_host/context_provider_factory_impl_android.h" | |
| 52 #include "gpu/command_buffer/client/gles2_interface.h" | |
| 53 //#include "cc/output/output_surface.h" | |
| 54 #include "gpu/command_buffer/common/mailbox.h" | |
| 55 | |
| 49 using base::android::JavaParamRef; | 56 using base::android::JavaParamRef; |
| 50 using base::android::JavaRef; | 57 using base::android::JavaRef; |
| 51 | 58 |
| 52 namespace vr_shell { | 59 namespace vr_shell { |
| 53 | 60 |
| 54 namespace { | 61 namespace { |
| 55 vr_shell::VrShell* g_instance; | 62 vr_shell::VrShell* g_instance; |
| 56 | 63 |
| 57 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; | 64 static const char kVrShellUIURL[] = "chrome://vr-shell-ui"; |
| 58 | 65 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 main_thread_task_runner_, gvr_api, for_web_vr, reprojected_rendering_); | 103 main_thread_task_runner_, gvr_api, for_web_vr, reprojected_rendering_); |
| 97 | 104 |
| 98 base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0); | 105 base::Thread::Options options(base::MessageLoop::TYPE_DEFAULT, 0); |
| 99 options.priority = base::ThreadPriority::DISPLAY; | 106 options.priority = base::ThreadPriority::DISPLAY; |
| 100 gl_thread_->StartWithOptions(options); | 107 gl_thread_->StartWithOptions(options); |
| 101 | 108 |
| 102 html_interface_ = base::MakeUnique<UiInterface>( | 109 html_interface_ = base::MakeUnique<UiInterface>( |
| 103 for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD); | 110 for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD); |
| 104 } | 111 } |
| 105 | 112 |
| 113 void VrShell::OnWebVrGpuChannelEstablished( | |
|
mthiesse
2017/03/01 16:38:21
Should this code all live in vr_shell_gl?
klausw
2017/03/02 08:16:13
Done.
| |
| 114 scoped_refptr<gpu::GpuChannelHost> gpu_channel_host, | |
| 115 ui::ContextProviderFactory::GpuChannelHostResult result) { | |
| 116 | |
| 117 VLOG(1) << __FUNCTION__ << ";;;"; | |
| 118 switch (result) { | |
| 119 // Don't retry if we are shutting down. | |
| 120 case ui::ContextProviderFactory::GpuChannelHostResult:: | |
| 121 FAILURE_FACTORY_SHUTDOWN: | |
| 122 break; | |
| 123 case ui::ContextProviderFactory::GpuChannelHostResult:: | |
| 124 FAILURE_GPU_PROCESS_INITIALIZATION_FAILED: | |
| 125 //HandlePendingCompositorFrameSinkRequest(); | |
| 126 break; | |
| 127 case ui::ContextProviderFactory::GpuChannelHostResult::SUCCESS: | |
| 128 VLOG(1) << __FUNCTION__ << ";;; Success!"; | |
| 129 | |
| 130 const size_t full_screen_texture_size_in_bytes = 4000 * 3000 * 4; | |
| 131 gpu::SharedMemoryLimits limits; | |
| 132 limits.command_buffer_size = 64 * 1024; | |
| 133 limits.start_transfer_buffer_size = 64 * 1024; | |
| 134 limits.min_transfer_buffer_size = 64 * 1024; | |
| 135 limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes; | |
| 136 limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes; | |
| 137 | |
| 138 gpu::gles2::ContextCreationAttribHelper attributes; | |
| 139 attributes.alpha_size = 0; | |
| 140 attributes.stencil_size = 0; | |
| 141 attributes.depth_size = 0; | |
| 142 attributes.samples = 0; | |
| 143 attributes.sample_buffers = 0; | |
| 144 attributes.bind_generates_resource = false; | |
| 145 | |
| 146 scoped_refptr<cc::ContextProvider> context_provider = | |
| 147 content::ContextProviderFactoryImpl::GetInstance() | |
| 148 ->CreateDisplayContextProvider( | |
| 149 webvr_surface_handle_, limits, | |
| 150 attributes, | |
| 151 false /*support_locking*/, false /*automatic_flushes*/, | |
| 152 std::move(gpu_channel_host)); | |
| 153 | |
| 154 webvr_context_provider_command_buffer_ = | |
| 155 static_cast<ui::ContextProviderCommandBuffer*>( | |
| 156 context_provider.get()); | |
| 157 | |
| 158 VLOG(1) << __FUNCTION__ << ";;; webvr_context_provider_command_buffer=" << | |
| 159 webvr_context_provider_command_buffer_; | |
| 160 if (!webvr_context_provider_command_buffer_->BindToCurrentThread()) { | |
| 161 LOG(ERROR) << __FUNCTION__ << ": failed to init ContextProvider"; | |
| 162 break; | |
| 163 } | |
| 164 VLOG(1) << __FUNCTION__ << ";;; bind succeeded"; | |
| 165 | |
| 166 #if 0 | |
| 167 auto display_output_surface = base::MakeUnique<AndroidOutputSurface>( | |
| 168 std::move(context_provider_command_buffer)); | |
| 169 InitializeDisplay(std::move(display_output_surface), nullptr, | |
| 170 std::move(context_provider)); | |
| 171 #endif | |
| 172 | |
| 173 webvr_surface_gl_ = webvr_context_provider_command_buffer_->ContextGL(); | |
| 174 VLOG(1) << __FUNCTION__ << ";;; webvr_surface_gl_=" << webvr_surface_gl_; | |
| 175 | |
| 176 #if 0 | |
| 177 auto gl = webvr_surface_gl_; | |
| 178 VLOG(1) << __FUNCTION__ << ";;; drawing some stuff"; | |
| 179 gl->ClearColor(1.0f, 0.0f, 0.0f, 1.0f); | |
| 180 gl->Clear(GL_COLOR_BUFFER_BIT); | |
| 181 //gl->ResizeCHROMIUM(1888, 888, 1.0f, true); | |
| 182 VLOG(1) << __FUNCTION__ << ";;; drawing done"; | |
| 183 #endif | |
| 184 break; | |
| 185 } | |
| 186 } | |
| 187 | |
| 106 void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { | 188 void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) { |
| 107 delete this; | 189 delete this; |
| 108 } | 190 } |
| 109 | 191 |
| 110 void VrShell::SwapContents( | 192 void VrShell::SwapContents( |
| 111 JNIEnv* env, | 193 JNIEnv* env, |
| 112 const JavaParamRef<jobject>& obj, | 194 const JavaParamRef<jobject>& obj, |
| 113 const JavaParamRef<jobject>& web_contents, | 195 const JavaParamRef<jobject>& web_contents, |
| 114 const JavaParamRef<jobject>& touch_event_synthesizer) { | 196 const JavaParamRef<jobject>& touch_event_synthesizer) { |
| 115 content::WebContents* contents = | 197 content::WebContents* contents = |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 317 jboolean incognito, | 399 jboolean incognito, |
| 318 jint id) { | 400 jint id) { |
| 319 html_interface_->RemoveTab(incognito, id); | 401 html_interface_->RemoveTab(incognito, id); |
| 320 } | 402 } |
| 321 | 403 |
| 322 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { | 404 void VrShell::SetWebVRSecureOrigin(bool secure_origin) { |
| 323 // TODO(cjgrant): Align this state with the logic that drives the omnibox. | 405 // TODO(cjgrant): Align this state with the logic that drives the omnibox. |
| 324 html_interface_->SetWebVRSecureOrigin(secure_origin); | 406 html_interface_->SetWebVRSecureOrigin(secure_origin); |
| 325 } | 407 } |
| 326 | 408 |
| 327 void VrShell::SubmitWebVRFrame() {} | 409 void VrShell::SubmitWebVRFrame(int frame_index, const gpu::Mailbox& mailbox) { |
| 410 auto gl = webvr_surface_gl_; | |
| 411 if (!gl) { | |
| 412 VLOG(1) << __FUNCTION__ << ";;; drop, no GL context"; | |
| 413 return; | |
| 414 } | |
| 415 VLOG(1) << __FUNCTION__ << ";;; frame=" << frame_index << " gl=" << gl; | |
| 416 | |
| 417 // Default viewport size seems ok, don't set one here and leave it | |
| 418 //alone elsewhere. | |
| 419 //gl->Viewport(0, 0, 2560, 1440); // FIXME! | |
| 420 | |
| 421 static GpuRenderer* copyRenderer = nullptr; | |
| 422 if (!copyRenderer) { | |
| 423 copyRenderer = new GpuRenderer(gl); | |
| 424 } | |
| 425 | |
| 426 #if 0 | |
| 427 gl->ClearColor((frame_index & 255) / 255.0f, | |
| 428 ((frame_index >> 16) & 255) / 255.0f, 1.0f, 1.0f); | |
| 429 gl->Clear(GL_COLOR_BUFFER_BIT); | |
| 430 #endif | |
| 431 | |
| 432 //if (mailbox.HasSyncToken()) | |
| 433 // gl->WaitSyncTokenCHROMIUM(mailbox.GetSyncTokenData()); | |
| 434 //gpu::SyncToken sync_token; | |
| 435 //cc::TextureMailbox texture_mailbox(mailbox, sync_token, GL_TEXTURE_2D); | |
| 436 VLOG(1) << __FUNCTION__ << ";;; got mailbox, name=" << | |
| 437 (int)mailbox.name[0] << "," << (int)mailbox.name[1] << "..."; | |
| 438 GLuint vrSourceTexture = gl->CreateAndConsumeTextureCHROMIUM( | |
| 439 GL_TEXTURE_2D, mailbox.name); | |
| 440 VLOG(1) << __FUNCTION__ << ";;; vrSourceTexture=" << vrSourceTexture; | |
| 441 | |
| 442 bool skip_this_frame = false; | |
| 443 GLint err; | |
| 444 | |
| 445 if ((err = gl->GetError()) != GL_NO_ERROR) { | |
| 446 VLOG(1) << __FUNCTION__ << ";;; Got GL error: " << err; | |
| 447 skip_this_frame = true; | |
| 448 } | |
| 449 if (webvr_frames_in_surface_queue_) { | |
| 450 // We've consumed the texture, but we can't draw it to the surface, the | |
| 451 // previous one hasn't been consumed yet. Swapping twice loses frames. | |
| 452 // This should be rare, it's a waste of resources and can suppress useful | |
| 453 // frames. | |
| 454 VLOG(1) << __FUNCTION__ << ";;; Dropping frame, got one queued already."; | |
| 455 skip_this_frame = true; | |
| 456 } | |
| 457 | |
| 458 copyRenderer->DrawQuad(gl, vrSourceTexture); | |
| 459 if ((err = gl->GetError()) != GL_NO_ERROR) { | |
| 460 VLOG(1) << __FUNCTION__ << ";;; Got GL error: " << err; | |
| 461 skip_this_frame = true; | |
| 462 } | |
| 463 | |
| 464 if (skip_this_frame) { | |
| 465 PostToGlThreadWhenReady( | |
| 466 base::Bind(&VrShellGl::DropWebVRFrame, | |
| 467 gl_thread_->GetVrShellGl(), frame_index)); | |
| 468 return; | |
| 469 } | |
| 470 | |
| 471 // If we get here, we're committed to drawing and swapBuffers. | |
| 472 // Continue after errors. | |
| 473 PostToGlThreadWhenReady(base::Bind(&VrShellGl::ScheduleWebVRFrame, | |
| 474 gl_thread_->GetVrShellGl(), frame_index)); | |
| 475 | |
| 476 // This is a load-bearing glFlush(). Removing it breaks rendering. WTF. | |
| 477 // FIXME: check if this is still true. | |
| 478 gl->Flush(); | |
| 479 gl->SwapBuffers(); | |
| 480 VLOG(1) << __FUNCTION__ << ";;; swapped, webvr_frames_in_surface_queue " << | |
| 481 webvr_frames_in_surface_queue_ << " => " << | |
| 482 (webvr_frames_in_surface_queue_ + 1); | |
| 483 ++webvr_frames_in_surface_queue_; | |
| 484 gl->Flush(); | |
| 485 } | |
| 486 | |
| 487 void VrShell::WebVRFrameCompleted(int frame_index) { | |
| 488 VLOG(1) << __FUNCTION__ << ";;; frame_index=" << frame_index << | |
| 489 ", webvr_frames_in_surface_queue " << | |
| 490 webvr_frames_in_surface_queue_ << " => " << | |
| 491 (webvr_frames_in_surface_queue_ - 1); | |
| 492 --webvr_frames_in_surface_queue_; | |
| 493 } | |
| 328 | 494 |
| 329 void VrShell::UpdateWebVRTextureBounds(int16_t frame_index, | 495 void VrShell::UpdateWebVRTextureBounds(int16_t frame_index, |
| 330 const gvr::Rectf& left_bounds, | 496 const gvr::Rectf& left_bounds, |
| 331 const gvr::Rectf& right_bounds) { | 497 const gvr::Rectf& right_bounds) { |
| 332 PostToGlThreadWhenReady(base::Bind(&VrShellGl::UpdateWebVRTextureBounds, | 498 PostToGlThreadWhenReady(base::Bind(&VrShellGl::UpdateWebVRTextureBounds, |
| 333 gl_thread_->GetVrShellGl(), frame_index, | 499 gl_thread_->GetVrShellGl(), frame_index, |
| 334 left_bounds, right_bounds)); | 500 left_bounds, right_bounds)); |
| 335 } | 501 } |
| 336 | 502 |
| 337 bool VrShell::SupportsPresentation() { | 503 bool VrShell::SupportsPresentation() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 ui_compositor_->SurfaceChanged(surface); | 536 ui_compositor_->SurfaceChanged(surface); |
| 371 } | 537 } |
| 372 | 538 |
| 373 void VrShell::ContentSurfaceChanged(jobject surface) { | 539 void VrShell::ContentSurfaceChanged(jobject surface) { |
| 374 content_surface_ = surface; | 540 content_surface_ = surface; |
| 375 content_compositor_->SurfaceChanged(surface); | 541 content_compositor_->SurfaceChanged(surface); |
| 376 JNIEnv* env = base::android::AttachCurrentThread(); | 542 JNIEnv* env = base::android::AttachCurrentThread(); |
| 377 Java_VrShellImpl_contentSurfaceChanged(env, j_vr_shell_.obj()); | 543 Java_VrShellImpl_contentSurfaceChanged(env, j_vr_shell_.obj()); |
| 378 } | 544 } |
| 379 | 545 |
| 546 void VrShell::WebVRSurfaceChanged(int surface_handle) { | |
| 547 VLOG(1) << __FUNCTION__ << ";;; Got WebVR surface, handle=" << surface_handle; | |
| 548 webvr_surface_handle_ = surface_handle; | |
| 549 | |
| 550 VLOG(1) << __FUNCTION__ << ";;; RequestGpuChannelHost start"; | |
| 551 ui::ContextProviderFactory::GetInstance()->RequestGpuChannelHost(base::Bind( | |
| 552 &VrShell::OnWebVrGpuChannelEstablished, weak_ptr_factory_.GetWeakPtr())); | |
| 553 VLOG(1) << __FUNCTION__ << ";;; RequestGpuChannelHost end"; | |
| 554 } | |
| 555 | |
| 556 | |
| 380 void VrShell::GvrDelegateReady() { | 557 void VrShell::GvrDelegateReady() { |
| 381 delegate_provider_->SetDelegate(this, gvr_api_); | 558 delegate_provider_->SetDelegate(this, gvr_api_); |
| 382 } | 559 } |
| 383 | 560 |
| 384 void VrShell::AppButtonPressed() { | 561 void VrShell::AppButtonPressed() { |
| 385 if (vr_shell_enabled_) | 562 if (vr_shell_enabled_) |
| 386 html_interface_->HandleAppButtonClicked(); | 563 html_interface_->HandleAppButtonClicked(); |
| 387 } | 564 } |
| 388 | 565 |
| 389 void VrShell::ContentPhysicalBoundsChanged(JNIEnv* env, | 566 void VrShell::ContentPhysicalBoundsChanged(JNIEnv* env, |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 jboolean reprojected_rendering) { | 853 jboolean reprojected_rendering) { |
| 677 return reinterpret_cast<intptr_t>(new VrShell( | 854 return reinterpret_cast<intptr_t>(new VrShell( |
| 678 env, obj, reinterpret_cast<ui::WindowAndroid*>(content_window_android), | 855 env, obj, reinterpret_cast<ui::WindowAndroid*>(content_window_android), |
| 679 content::WebContents::FromJavaWebContents(ui_web_contents), | 856 content::WebContents::FromJavaWebContents(ui_web_contents), |
| 680 reinterpret_cast<ui::WindowAndroid*>(ui_window_android), for_web_vr, | 857 reinterpret_cast<ui::WindowAndroid*>(ui_window_android), for_web_vr, |
| 681 VrShellDelegate::GetNativeVrShellDelegate(env, delegate), | 858 VrShellDelegate::GetNativeVrShellDelegate(env, delegate), |
| 682 reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering)); | 859 reinterpret_cast<gvr_context*>(gvr_api), reprojected_rendering)); |
| 683 } | 860 } |
| 684 | 861 |
| 685 } // namespace vr_shell | 862 } // namespace vr_shell |
| OLD | NEW |