blob: d721f39d44937788afeb5568c04c8ef67f8697ca [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_VR_ANDROID_XR_IMAGE_TRANSPORT_BASE_H_
#define DEVICE_VR_ANDROID_XR_IMAGE_TRANSPORT_BASE_H_
#include <memory>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/single_thread_task_runner.h"
#include "device/vr/android/local_texture.h"
#include "device/vr/android/web_xr_presentation_state.h"
#include "gpu/command_buffer/client/client_shared_image.h"
#include "ui/gfx/geometry/transform.h"
#include "ui/gl/gl_bindings.h"
namespace gfx {
class GpuFence;
} // namespace gfx
namespace gpu {
struct SyncToken;
} // namespace gpu
namespace device {
class MailboxToSurfaceBridge;
using XrFrameCallback = base::RepeatingCallback<void(const gfx::Transform&)>;
using XrInitStatusCallback = base::OnceCallback<void(bool success)>;
// 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.
// Non pure-virtual methods are only intended to be overridden for testing
// purposes.
class XrImageTransportBase {
public:
explicit XrImageTransportBase(
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge);
XrImageTransportBase(const XrImageTransportBase&) = delete;
XrImageTransportBase& operator=(const XrImageTransportBase&) = delete;
virtual ~XrImageTransportBase();
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,
XrInitStatusCallback callback,
bool webgpu_session);
// Indicates if the session uses WebGPU to produce it's frames. Does not
// have any effect on the API used for compositing/display.
bool IsWebGPUSession() { return webgpu_session_; }
// Only valid when using SharedBuffers, this ensures that the current
// animating frame is populated with texture information for a valid and
// correctly sized shared buffer backed by an EGL image. This function
// intends to return to its caller a sync token as well as
// a scoped_refptr<gpu::ClientSharedImage> pointing to this shared buffer
// suitable to transfer to another process to allow it to write to the
// shared buffer. The two values are currently returned together via
// a wrapping WebXrSharedBuffer.
// TODO(crbug.com/40286368): Change the return type to
// scoped_refptr<gpu::ClientSharedImage> once the sync token is
// incorporated into ClientSharedImage.
virtual WebXrSharedBuffer* TransferFrame(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 WaitSyncToken(const gpu::SyncToken& sync_token);
void ServerWaitForGpuFence(std::unique_ptr<gfx::GpuFence> gpu_fence);
protected:
bool IsOnGlThread() const;
virtual 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);
// This method provides an abstraction to the caller about whether the system
// is running in SharedBuffer mode or not, and returns the texture that the
// renderer has most recently populated and submitted back to the device for
// rendering. There must be a texture in the `RenderingFrame` state of the
// `WebXrPresentationState` machine for this to properly return data.
LocalTexture GetRenderingTexture(WebXrPresentationState* webxr);
// Runs before the rest of the initialization for the XrImageTransport to
// allow for any specialized gl context setup or other setup that may be
// needed by the particular runtime that's in use.
virtual void DoRuntimeInitialization() = 0;
std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge_;
private:
void OnMailboxBridgeReady(XrInitStatusCallback callback);
scoped_refptr<base::SingleThreadTaskRunner> gl_thread_task_runner_;
bool webgpu_session_ = false;
// Must be last.
base::WeakPtrFactory<XrImageTransportBase> weak_ptr_factory_{this};
};
} // namespace device
#endif // DEVICE_VR_ANDROID_XR_IMAGE_TRANSPORT_BASE_H_