blob: c87b1bd33ef92db2ec96292b03d4af1f7a5145ed [file] [log] [blame]
// Copyright 2025 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_OPENXR_OPENXR_COMPOSITION_LAYER_H_
#define DEVICE_VR_OPENXR_OPENXR_COMPOSITION_LAYER_H_
#include "base/memory/raw_ptr.h"
#include "components/viz/common/gpu/context_provider.h"
#include "device/vr/openxr/openxr_swapchain_info.h"
#include "device/vr/public/mojom/vr_service.mojom.h"
#include "third_party/openxr/src/include/openxr/openxr.h"
namespace device {
class OpenXrGraphicsBinding;
class OpenXrCompositionLayer {
public:
// See https://www.w3.org/TR/webxrlayers-1/#xrlayertypes
enum class Type {
kProjection = 0,
kQuad = 1,
kCylinder = 2,
kEquirect = 3,
};
// Base class for graphics binding specific layer data.
struct GraphicsBindingData {
enum GraphicsBindingDataType {
kInvalid,
kOpenGLES,
kD3D,
};
virtual ~GraphicsBindingData() = default;
GraphicsBindingDataType type = kInvalid;
};
static Type GetTypeFromMojomData(const mojom::XRLayerSpecificData&);
OpenXrCompositionLayer(
XrSpace space,
mojom::XRCompositionLayerDataPtr layer_data,
OpenXrGraphicsBinding* graphics_binding,
std::unique_ptr<GraphicsBindingData> graphics_binding_data);
~OpenXrCompositionLayer();
// Returns the previously set swapchain image size, or 0,0 if one is not set.
gfx::Size GetSwapchainImageSize();
// Gets the size of the texture that is shared between our process and the
// renderer process.
gfx::Size GetTransferSize();
// Sets the size of the texture being used between the renderer process and
// our process. This is largely driven by the page and any framebuffer scaling
// it may apply. When rendering to the SwapchainImage scaling will be
// performed as necessary.
void SetTransferSize(const gfx::Size& transfer_size);
// Sets the size of the swapchain images being used by the system. Does *not*
// cause a corresponding re-creation of the Swapchain or Shared Images; which
// should be driven by the caller. If a transfer size has not been specified
// yet, will also set the transfer size as well.
void SetSwapchainImageSize(const gfx::Size& swapchain_image_size);
// Called by graphics binding to set the swapchain images.
void SetSwapchainImages(std::vector<OpenXrSwapchainInfo>);
// Updates the active swapchain image size if the transfer size has changed.
// No-ops if there is currently no active swapchain image.
void UpdateActiveSwapchainImageSize(gpu::SharedImageInterface* sii);
base::span<OpenXrSwapchainInfo> GetSwapchainImages();
base::span<const OpenXrSwapchainInfo> GetSwapchainImages() const;
// Create the XrSwapchain and swapchain images.
XrResult CreateSwapchain(XrSession session, uint32_t sample_count);
// Clears the list of images allocated during `CreateSwapchain` and
// if a context_provider is provided and the Swapchain entries have had
// corresponding SharedImages created via `CreateSharedImages` will also clean
// up those SharedImages.
void DestroySwapchain(gpu::SharedImageInterface* sii);
// Acquire and activate a Swapchain image from the OpenXr system. This is the
// swapchain image that will be in use for the next render.
XrResult ActivateSwapchainImage(gpu::SharedImageInterface* sii);
// Release the active swapchain image from the OpenXr system. This is called
// before calling EndFrame and will enable acquiring a new swapchain image for
// the next frame.
XrResult ReleaseActiveSwapchainImage();
// Get the currently active swapchain image.
OpenXrSwapchainInfo* GetActiveSwapchainImage();
// Return if the XrSwapchain is available.
bool HasColorSwapchain() const { return color_swapchain_ != XR_NULL_HANDLE; }
// Returns whether or not the current Swapchain is actually using SharedImages
// or not.
bool IsUsingSharedImages() const;
// Update the layer's size and transform.
void UpdateMutableLayerData(XrSpace space, mojom::XRLayerMutableDataPtr);
// Mark the layer rendered.
void SetIsRendered() { is_rendered_ = true; }
LayerId GetLayerId() const;
// A group of simple getters.
XrSwapchain color_swapchain() const { return color_swapchain_; }
bool has_active_swapchain_image() const {
return has_active_swapchain_image_;
}
GraphicsBindingData* graphics_binding_data() {
return graphics_binding_data_.get();
}
Type type() const { return type_; }
XrSpace space() const { return space_; }
bool is_rendered() const { return is_rendered_; }
const mojom::XRLayerReadOnlyData& read_only_data() const {
DCHECK(creation_data_);
return *creation_data_->read_only_data;
}
const mojom::XRLayerMutableData& mutable_data() const {
DCHECK(creation_data_);
return *creation_data_->mutable_data;
}
private:
Type type_ = Type::kProjection;
XrSpace space_ = XR_NULL_HANDLE;
raw_ptr<OpenXrGraphicsBinding> graphics_binding_;
std::vector<OpenXrSwapchainInfo> color_swapchain_images_;
gfx::Size swapchain_image_size_{0, 0};
gfx::Size transfer_size_{0, 0};
// Used to access the active swapchain index as returned by the system. This
// class does not attempt to use the index in conjunction with
// `GetSwapchainImages` as the children may do their own mapping. However,
// this corresponds to the position of the corresponding texture in the array
// as was returned by the OpenXr system when querying for the swapchain info.
uint32_t active_swapchain_index_ = 0;
// Indicates whether or not we actually have an active swapchain image (e.g.
// ActivateSwapchainImage has been called, but ReleaseSwapchainImage has not).
bool has_active_swapchain_image_ = false;
// Indicates whether the layer has been rendered at least once, in other
// words, if it contains some contents.
bool is_rendered_ = false;
// The swapchain is initializd when a session begins and is re-created when
// the state of a secondary view configuration changes.
XrSwapchain color_swapchain_ = XR_NULL_HANDLE;
// Store graphics binding specific data.
std::unique_ptr<GraphicsBindingData> graphics_binding_data_;
// Data used to create the layer.
mojom::XRCompositionLayerDataPtr creation_data_;
}; // OpenXrCompositionLayer
} // namespace device
#endif // DEVICE_VR_OPENXR_OPENXR_COMPOSITION_LAYER_H_