Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: chrome/browser/android/vr_shell/vr_shell.cc

Issue 2729523002: Re-land^2 WebVR compositor bypass via BrowserMain context + mailbox (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698