blob: bf6b14991a45ffcbe1781a556b4169939efb01a7 [file]
// Copyright 2018 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.
#ifndef DEVICE_VR_ANDROID_ARCORE_AR_IMAGE_TRANSPORT_H_
#define DEVICE_VR_ANDROID_ARCORE_AR_IMAGE_TRANSPORT_H_
#include <memory>
#include "base/component_export.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "device/vr/android/arcore/ar_renderer.h"
#include "ui/gfx/geometry/size_f.h"
#include "ui/gfx/geometry/transform.h"
namespace gl {
class SurfaceTexture;
} // namespace gl
namespace gfx {
class GpuFence;
} // namespace gfx
namespace gpu {
struct MailboxHolder;
struct SyncToken;
} // namespace gpu
namespace device {
class MailboxToSurfaceBridge;
class WebXrPresentationState;
struct WebXrSharedBuffer;
using XrFrameCallback = base::RepeatingCallback<void(const gfx::Transform&)>;
// This class handles transporting WebGL rendered output from the GPU process's
// command buffer GL context to the local GL context, and compositing WebGL
// output onto the camera image using the local GL context.
class COMPONENT_EXPORT(VR_ARCORE) ArImageTransport {
public:
// If true, use shared buffer transport aka DRAW_INTO_TEXTURE_MAILBOX.
// If false, use Surface transport aka SUBMIT_AS_MAILBOX_HOLDER.
static bool UseSharedBuffer();
explicit ArImageTransport(
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge);
ArImageTransport(const ArImageTransport&) = delete;
ArImageTransport& operator=(const ArImageTransport&) = delete;
virtual ~ArImageTransport();
virtual void DestroySharedBuffers(WebXrPresentationState* webxr);
// All methods must be called on a valid GL thread. Initialization
// must happen after the local GL context is ready for use. That
// starts the asynchronous setup for the GPU process command buffer
// GL context via MailboxToSurfaceBridge, and the callback is called
// once that's complete.
virtual void Initialize(WebXrPresentationState* webxr,
base::OnceClosure callback);
virtual GLuint GetCameraTextureId();
// This creates a shared buffer if one doesn't already exist, and populates it
// with the current animating frame's buffer data. It returns a
// gpu::Mailboxholder with this shared buffer data.
virtual gpu::MailboxHolder TransferFrame(WebXrPresentationState* webxr,
const gfx::Size& frame_size,
const gfx::Transform& uv_transform);
// This transfers whatever the contents of the texture specified
// by GetCameraTextureId() is at the time it is called and returns
// a gpu::MailboxHolder with that texture copied to a shared buffer.
virtual gpu::MailboxHolder TransferCameraImageFrame(
WebXrPresentationState* webxr,
const gfx::Size& frame_size,
const gfx::Transform& uv_transform);
virtual void CreateGpuFenceForSyncToken(
const gpu::SyncToken& sync_token,
base::OnceCallback<void(std::unique_ptr<gfx::GpuFence>)>);
virtual void CopyCameraImageToFramebuffer(const gfx::Size& frame_size,
const gfx::Transform& uv_transform);
virtual void CopyDrawnImageToFramebuffer(WebXrPresentationState* webxr,
const gfx::Size& frame_size,
const gfx::Transform& uv_transform);
virtual void CopyTextureToFramebuffer(GLuint texture,
const gfx::Size& frame_size,
const gfx::Transform& uv_transform);
virtual void WaitSyncToken(const gpu::SyncToken& sync_token);
virtual void CopyMailboxToSurfaceAndSwap(const gfx::Size& frame_size,
const gpu::MailboxHolder& mailbox,
const gfx::Transform& uv_transform);
void SetFrameAvailableCallback(XrFrameCallback on_frame_available);
void ServerWaitForGpuFence(std::unique_ptr<gfx::GpuFence> gpu_fence);
private:
std::unique_ptr<WebXrSharedBuffer> CreateBuffer();
// Returns true if the buffer was resized and its sync token updated.
bool ResizeSharedBuffer(WebXrPresentationState* webxr,
const gfx::Size& size,
WebXrSharedBuffer* buffer);
void ResizeSurface(const gfx::Size& size);
bool IsOnGlThread() const;
void OnMailboxBridgeReady(base::OnceClosure callback);
void OnFrameAvailable();
std::unique_ptr<ArRenderer> ar_renderer_;
// samplerExternalOES texture for the camera image.
GLuint camera_texture_id_arcore_ = 0;
GLuint camera_fbo_ = 0;
GLuint camera_image_fbo_ = 0;
scoped_refptr<base::SingleThreadTaskRunner> gl_thread_task_runner_;
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge_;
// Used to limit framebuffer complete check to occurring once, due to it being
// expensive.
bool framebuffer_complete_checked_for_camera_buffer_ = false;
// Used for Surface transport (Android N)
//
// samplerExternalOES texture data for WebXR content image.
GLuint transport_texture_id_ = 0;
gfx::Size surface_size_;
scoped_refptr<gl::SurfaceTexture> transport_surface_texture_;
gfx::Transform transport_surface_texture_uv_transform_;
float transport_surface_texture_uv_matrix_[16];
XrFrameCallback on_transport_frame_available_;
// Must be last.
base::WeakPtrFactory<ArImageTransport> weak_ptr_factory_{this};
};
class COMPONENT_EXPORT(VR_ARCORE) ArImageTransportFactory {
public:
virtual ~ArImageTransportFactory() = default;
virtual std::unique_ptr<ArImageTransport> Create(
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge);
};
} // namespace device
#endif // DEVICE_VR_ANDROID_ARCORE_AR_IMAGE_TRANSPORT_H_