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 |