910e62b5创建于 1月15日历史提交
// 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_