| 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
|
|
|