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

Unified 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, 10 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/vr_shell/vr_shell.cc
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index ba595ae5bf5dd9ef7d0c95cf17f634cc532c5eb2..901af313520bfbe15d0a613558c8c2ea1a188b50 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -25,6 +25,7 @@
#include "chrome/browser/android/vr_shell/vr_input_manager.h"
#include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
#include "chrome/browser/android/vr_shell/vr_shell_gl.h"
+#include "chrome/browser/android/vr_shell/vr_shell_gpu_renderer.h"
#include "chrome/browser/android/vr_shell/vr_usage_monitor.h"
#include "chrome/browser/android/vr_shell/vr_web_contents_observer.h"
#include "content/public/browser/navigation_controller.h"
@@ -46,6 +47,12 @@
#include "ui/gfx/transform.h"
#include "ui/gfx/transform_util.h"
+#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
+#include "content/browser/renderer_host/context_provider_factory_impl_android.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+//#include "cc/output/output_surface.h"
+#include "gpu/command_buffer/common/mailbox.h"
+
using base::android::JavaParamRef;
using base::android::JavaRef;
@@ -103,6 +110,81 @@ VrShell::VrShell(JNIEnv* env,
for_web_vr ? UiInterface::Mode::WEB_VR : UiInterface::Mode::STANDARD);
}
+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.
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host,
+ ui::ContextProviderFactory::GpuChannelHostResult result) {
+
+ VLOG(1) << __FUNCTION__ << ";;;";
+ switch (result) {
+ // Don't retry if we are shutting down.
+ case ui::ContextProviderFactory::GpuChannelHostResult::
+ FAILURE_FACTORY_SHUTDOWN:
+ break;
+ case ui::ContextProviderFactory::GpuChannelHostResult::
+ FAILURE_GPU_PROCESS_INITIALIZATION_FAILED:
+ //HandlePendingCompositorFrameSinkRequest();
+ break;
+ case ui::ContextProviderFactory::GpuChannelHostResult::SUCCESS:
+ VLOG(1) << __FUNCTION__ << ";;; Success!";
+
+ const size_t full_screen_texture_size_in_bytes = 4000 * 3000 * 4;
+ gpu::SharedMemoryLimits limits;
+ limits.command_buffer_size = 64 * 1024;
+ limits.start_transfer_buffer_size = 64 * 1024;
+ limits.min_transfer_buffer_size = 64 * 1024;
+ limits.max_transfer_buffer_size = full_screen_texture_size_in_bytes;
+ limits.mapped_memory_reclaim_limit = full_screen_texture_size_in_bytes;
+
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = 0;
+ attributes.stencil_size = 0;
+ attributes.depth_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+
+ scoped_refptr<cc::ContextProvider> context_provider =
+ content::ContextProviderFactoryImpl::GetInstance()
+ ->CreateDisplayContextProvider(
+ webvr_surface_handle_, limits,
+ attributes,
+ false /*support_locking*/, false /*automatic_flushes*/,
+ std::move(gpu_channel_host));
+
+ webvr_context_provider_command_buffer_ =
+ static_cast<ui::ContextProviderCommandBuffer*>(
+ context_provider.get());
+
+ VLOG(1) << __FUNCTION__ << ";;; webvr_context_provider_command_buffer=" <<
+ webvr_context_provider_command_buffer_;
+ if (!webvr_context_provider_command_buffer_->BindToCurrentThread()) {
+ LOG(ERROR) << __FUNCTION__ << ": failed to init ContextProvider";
+ break;
+ }
+ VLOG(1) << __FUNCTION__ << ";;; bind succeeded";
+
+#if 0
+ auto display_output_surface = base::MakeUnique<AndroidOutputSurface>(
+ std::move(context_provider_command_buffer));
+ InitializeDisplay(std::move(display_output_surface), nullptr,
+ std::move(context_provider));
+#endif
+
+ webvr_surface_gl_ = webvr_context_provider_command_buffer_->ContextGL();
+ VLOG(1) << __FUNCTION__ << ";;; webvr_surface_gl_=" << webvr_surface_gl_;
+
+#if 0
+ auto gl = webvr_surface_gl_;
+ VLOG(1) << __FUNCTION__ << ";;; drawing some stuff";
+ gl->ClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+ gl->Clear(GL_COLOR_BUFFER_BIT);
+ //gl->ResizeCHROMIUM(1888, 888, 1.0f, true);
+ VLOG(1) << __FUNCTION__ << ";;; drawing done";
+#endif
+ break;
+ }
+}
+
void VrShell::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
delete this;
}
@@ -324,7 +406,91 @@ void VrShell::SetWebVRSecureOrigin(bool secure_origin) {
html_interface_->SetWebVRSecureOrigin(secure_origin);
}
-void VrShell::SubmitWebVRFrame() {}
+void VrShell::SubmitWebVRFrame(int frame_index, const gpu::Mailbox& mailbox) {
+ auto gl = webvr_surface_gl_;
+ if (!gl) {
+ VLOG(1) << __FUNCTION__ << ";;; drop, no GL context";
+ return;
+ }
+ VLOG(1) << __FUNCTION__ << ";;; frame=" << frame_index << " gl=" << gl;
+
+ // Default viewport size seems ok, don't set one here and leave it
+ //alone elsewhere.
+ //gl->Viewport(0, 0, 2560, 1440); // FIXME!
+
+ static GpuRenderer* copyRenderer = nullptr;
+ if (!copyRenderer) {
+ copyRenderer = new GpuRenderer(gl);
+ }
+
+#if 0
+ gl->ClearColor((frame_index & 255) / 255.0f,
+ ((frame_index >> 16) & 255) / 255.0f, 1.0f, 1.0f);
+ gl->Clear(GL_COLOR_BUFFER_BIT);
+#endif
+
+ //if (mailbox.HasSyncToken())
+ // gl->WaitSyncTokenCHROMIUM(mailbox.GetSyncTokenData());
+ //gpu::SyncToken sync_token;
+ //cc::TextureMailbox texture_mailbox(mailbox, sync_token, GL_TEXTURE_2D);
+ VLOG(1) << __FUNCTION__ << ";;; got mailbox, name=" <<
+ (int)mailbox.name[0] << "," << (int)mailbox.name[1] << "...";
+ GLuint vrSourceTexture = gl->CreateAndConsumeTextureCHROMIUM(
+ GL_TEXTURE_2D, mailbox.name);
+ VLOG(1) << __FUNCTION__ << ";;; vrSourceTexture=" << vrSourceTexture;
+
+ bool skip_this_frame = false;
+ GLint err;
+
+ if ((err = gl->GetError()) != GL_NO_ERROR) {
+ VLOG(1) << __FUNCTION__ << ";;; Got GL error: " << err;
+ skip_this_frame = true;
+ }
+ if (webvr_frames_in_surface_queue_) {
+ // We've consumed the texture, but we can't draw it to the surface, the
+ // previous one hasn't been consumed yet. Swapping twice loses frames.
+ // This should be rare, it's a waste of resources and can suppress useful
+ // frames.
+ VLOG(1) << __FUNCTION__ << ";;; Dropping frame, got one queued already.";
+ skip_this_frame = true;
+ }
+
+ copyRenderer->DrawQuad(gl, vrSourceTexture);
+ if ((err = gl->GetError()) != GL_NO_ERROR) {
+ VLOG(1) << __FUNCTION__ << ";;; Got GL error: " << err;
+ skip_this_frame = true;
+ }
+
+ if (skip_this_frame) {
+ PostToGlThreadWhenReady(
+ base::Bind(&VrShellGl::DropWebVRFrame,
+ gl_thread_->GetVrShellGl(), frame_index));
+ return;
+ }
+
+ // If we get here, we're committed to drawing and swapBuffers.
+ // Continue after errors.
+ PostToGlThreadWhenReady(base::Bind(&VrShellGl::ScheduleWebVRFrame,
+ gl_thread_->GetVrShellGl(), frame_index));
+
+ // This is a load-bearing glFlush(). Removing it breaks rendering. WTF.
+ // FIXME: check if this is still true.
+ gl->Flush();
+ gl->SwapBuffers();
+ VLOG(1) << __FUNCTION__ << ";;; swapped, webvr_frames_in_surface_queue " <<
+ webvr_frames_in_surface_queue_ << " => " <<
+ (webvr_frames_in_surface_queue_ + 1);
+ ++webvr_frames_in_surface_queue_;
+ gl->Flush();
+}
+
+void VrShell::WebVRFrameCompleted(int frame_index) {
+ VLOG(1) << __FUNCTION__ << ";;; frame_index=" << frame_index <<
+ ", webvr_frames_in_surface_queue " <<
+ webvr_frames_in_surface_queue_ << " => " <<
+ (webvr_frames_in_surface_queue_ - 1);
+ --webvr_frames_in_surface_queue_;
+}
void VrShell::UpdateWebVRTextureBounds(int16_t frame_index,
const gvr::Rectf& left_bounds,
@@ -377,6 +543,17 @@ void VrShell::ContentSurfaceChanged(jobject surface) {
Java_VrShellImpl_contentSurfaceChanged(env, j_vr_shell_.obj());
}
+void VrShell::WebVRSurfaceChanged(int surface_handle) {
+ VLOG(1) << __FUNCTION__ << ";;; Got WebVR surface, handle=" << surface_handle;
+ webvr_surface_handle_ = surface_handle;
+
+ VLOG(1) << __FUNCTION__ << ";;; RequestGpuChannelHost start";
+ ui::ContextProviderFactory::GetInstance()->RequestGpuChannelHost(base::Bind(
+ &VrShell::OnWebVrGpuChannelEstablished, weak_ptr_factory_.GetWeakPtr()));
+ VLOG(1) << __FUNCTION__ << ";;; RequestGpuChannelHost end";
+}
+
+
void VrShell::GvrDelegateReady() {
delegate_provider_->SetDelegate(this, gvr_api_);
}

Powered by Google App Engine
This is Rietveld 408576698