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

Unified Diff: chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.cc

Issue 2738683002: WebVR compositor bypass via BrowserMain context + mailbox (Closed)
Patch Set: Less hacked up version 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.cc
diff --git a/chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.cc b/chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.cc
new file mode 100644
index 0000000000000000000000000000000000000000..6884641f39df00b82f3b106384ab5ddbc9f9f841
--- /dev/null
+++ b/chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.cc
@@ -0,0 +1,141 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.h"
+
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/android/vr_shell/vr_shell_gpu_renderer.h"
+#include "content/public/browser/android/compositor.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/mailbox_holder.h"
+#include "gpu/command_buffer/common/sync_token.h"
+#include "gpu/ipc/client/gpu_channel_host.h"
+#include "gpu/ipc/common/gpu_surface_tracker.h"
+#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h"
+#include "ui/gl/android/surface_texture.h"
+
+#include <android/native_window_jni.h>
+
+namespace vr_shell {
+
+VrShellCommandBufferGl::VrShellCommandBufferGl() : weak_ptr_factory_(this) {}
+
+VrShellCommandBufferGl::~VrShellCommandBufferGl() {
+ if (surface_handle_) {
+ // Unregister from the surface tracker to avoid a resource leak.
+ gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get();
+ tracker->UnregisterViewSurface(surface_handle_);
+ }
+}
+
+void VrShellCommandBufferGl::OnGpuChannelEstablished(
+ scoped_refptr<gpu::GpuChannelHost> gpu_channel_host) {
+ // Our attributes must be compatible with the shared offscreen
+ // surface used by virtualized contexts, otherwise mailbox
+ // synchronization doesn't work properly - it assumes a shared
+ // underlying GL context. TODO(klausw): is there a more official
+ // way to get default-compatible settings?
+ gpu::gles2::ContextCreationAttribHelper attributes;
+ attributes.alpha_size = -1;
+ attributes.red_size = 8;
+ attributes.green_size = 8;
+ attributes.blue_size = 8;
+ attributes.stencil_size = 0;
+ attributes.depth_size = 0;
+ attributes.samples = 0;
+ attributes.sample_buffers = 0;
+ attributes.bind_generates_resource = false;
+
+ bool automatic_flushes = false;
+ bool support_locking = false;
+ constexpr ui::ContextProviderCommandBuffer* shared_context_provider = nullptr;
+ context_provider_command_buffer_ =
+ make_scoped_refptr(new ui::ContextProviderCommandBuffer(
+ std::move(gpu_channel_host), gpu::GPU_STREAM_DEFAULT,
+ gpu::GpuStreamPriority::NORMAL, surface_handle_,
+ GURL("chrome://gpu/WebVRContextFactory"), automatic_flushes,
+ support_locking, gpu::SharedMemoryLimits::ForMailboxContext(),
+ attributes, shared_context_provider,
+ ui::command_buffer_metrics::CONTEXT_TYPE_UNKNOWN));
+
+ if (!context_provider_command_buffer_->BindToCurrentThread()) {
+ LOG(ERROR) << __FUNCTION__ << ";;; failed to init ContextProvider";
+ return;
+ }
+
+ gl_ = context_provider_command_buffer_->ContextGL();
+
+ copy_renderer_ = base::MakeUnique<GpuRenderer>(gl_);
+}
+
+std::unique_ptr<gl::ScopedJavaSurface> VrShellCommandBufferGl::CreateSurface(
+ scoped_refptr<gl::SurfaceTexture> surface_texture) {
+ ANativeWindow* window = surface_texture->CreateSurface();
+ gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get();
+ ANativeWindow_acquire(window);
+ // Skip ANativeWindow_setBuffersGeometry, the default size appears to work.
+ surface_handle_ = tracker->AddSurfaceForNativeWidget(window);
+
+ auto surface = base::MakeUnique<gl::ScopedJavaSurface>(surface_texture.get());
+ tracker->RegisterViewSurface(surface_handle_, surface->j_surface().obj());
+ // Unregistering happens in the destructor.
+ ANativeWindow_release(window);
+
+ gpu::GpuChannelEstablishFactory* factory =
+ content::Compositor::GetGpuChannelFactory();
+
+ factory->EstablishGpuChannel(
+ base::Bind(&VrShellCommandBufferGl::OnGpuChannelEstablished,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ return surface;
+}
+
+void VrShellCommandBufferGl::ResizeSurface(int width, int height) {
+ if (!gl_) {
+ LOG(ERROR) << "Cannot resize, not initialized";
+ return;
+ }
+ gl_->ResizeCHROMIUM(width, height, 1.f, false);
+ gl_->Viewport(0, 0, width, height);
+}
+
+bool VrShellCommandBufferGl::CopyFrameToSurface(
+ int frame_index,
+ const gpu::MailboxHolder& mailbox,
+ bool discard) {
+ TRACE_EVENT1("gpu", "VrShellCommandBufferGl::CopyFrameToSurface", "frame",
+ frame_index);
+ if (!gl_) {
+ // We may not have a context yet, i.e. due to surface initialization
+ // being incomplete. This is not an error, but we obviously can't draw
+ // yet.
+ return false;
+ }
+
+ {
+ TRACE_EVENT0("gpu", "VrShellCommandBufferGl::WaitSyncToken");
+ gl_->WaitSyncTokenCHROMIUM(mailbox.sync_token.GetConstData());
+ }
+
+ GLuint vrSourceTexture =
+ gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.mailbox.name);
+
+ if (discard) {
+ // We've consumed the texture, but the caller requested that we
+ // don't draw it because the previous one hasn't been consumed
+ // yet. (Swapping twice on a Surfacewithout consuming one in
+ // between from the SurfaceTexture can lose frames.) This should
+ // be rare, it's a waste of resources and can cause jerky
+ // animation due to the lost frames.
+ return false;
+ } else {
+ copy_renderer_->DrawQuad(gl_, vrSourceTexture);
+ gl_->SwapBuffers();
+ return true;
+ }
+}
+
+} // namespace vr_shell
« no previous file with comments | « chrome/browser/android/vr_shell/vr_shell_command_buffer_gl.h ('k') | chrome/browser/android/vr_shell/vr_shell_gl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698