// Copyright 2020 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_EXTENSION_HELPER_H_
#define DEVICE_VR_OPENXR_OPENXR_EXTENSION_HELPER_H_
#include <memory>
#include <vector>
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "build/buildflag.h"
#include "device/vr/openxr/openxr_anchor_manager.h"
#include "device/vr/openxr/openxr_depth_sensor.h"
#include "device/vr/openxr/openxr_hand_tracker.h"
#include "device/vr/openxr/openxr_light_estimator.h"
#include "device/vr/openxr/openxr_platform.h"
#include "device/vr/openxr/openxr_scene_understanding_manager.h"
#include "device/vr/openxr/openxr_stage_bounds_provider.h"
#include "device/vr/openxr/openxr_unbounded_space_provider.h"
#include "device/vr/public/mojom/xr_session.mojom-forward.h"
#include "third_party/openxr/src/include/openxr/openxr.h"
#if BUILDFLAG(IS_ANDROID)
#include "third_party/openxr/dev/xr_android.h"
#endif
namespace device {
// Helper macro to facilitate declaring the method names of functions that will
// be loaded from the OpenXR Runtime.
// Expands to e.g.
// PFN_xrCreateHandTrackerEXT xrCreateHandTrackerEXT{nullptr};
#define OPENXR_DECLARE_FN(name) PFN_##name name = nullptr
struct OpenXrExtensionMethods {
OpenXrExtensionMethods();
~OpenXrExtensionMethods();
// Hand Tracking
OPENXR_DECLARE_FN(xrCreateHandTrackerEXT);
OPENXR_DECLARE_FN(xrDestroyHandTrackerEXT);
OPENXR_DECLARE_FN(xrLocateHandJointsEXT);
// Anchors
OPENXR_DECLARE_FN(xrCreateSpatialAnchorMSFT);
OPENXR_DECLARE_FN(xrDestroySpatialAnchorMSFT);
OPENXR_DECLARE_FN(xrCreateSpatialAnchorSpaceMSFT);
// Scene Understanding
OPENXR_DECLARE_FN(xrEnumerateSceneComputeFeaturesMSFT);
OPENXR_DECLARE_FN(xrCreateSceneObserverMSFT);
OPENXR_DECLARE_FN(xrDestroySceneObserverMSFT);
OPENXR_DECLARE_FN(xrCreateSceneMSFT);
OPENXR_DECLARE_FN(xrDestroySceneMSFT);
OPENXR_DECLARE_FN(xrComputeNewSceneMSFT);
OPENXR_DECLARE_FN(xrGetSceneComputeStateMSFT);
OPENXR_DECLARE_FN(xrGetSceneComponentsMSFT);
OPENXR_DECLARE_FN(xrLocateSceneComponentsMSFT);
OPENXR_DECLARE_FN(xrGetSceneMeshBuffersMSFT);
#if BUILDFLAG(IS_WIN)
// Time
OPENXR_DECLARE_FN(xrConvertWin32PerformanceCounterToTimeKHR);
#endif
// While these extensions don't need to be gated to a particular platform,
// since the API is still under development we'll try to limit the scope for
// the time being.
#if BUILDFLAG(IS_ANDROID)
OPENXR_DECLARE_FN(xrGetReferenceSpaceBoundsPolygonANDROID);
// Trackables and Raycasting.
OPENXR_DECLARE_FN(xrCreateTrackableTrackerANDROID);
OPENXR_DECLARE_FN(xrDestroyTrackableTrackerANDROID);
OPENXR_DECLARE_FN(xrRaycastANDROID);
OPENXR_DECLARE_FN(xrCreateAnchorSpaceANDROID);
OPENXR_DECLARE_FN(xrCreateLightEstimatorANDROID);
OPENXR_DECLARE_FN(xrDestroyLightEstimatorANDROID);
OPENXR_DECLARE_FN(xrGetLightEstimateANDROID);
OPENXR_DECLARE_FN(xrCreateDepthSwapchainANDROID);
OPENXR_DECLARE_FN(xrDestroyDepthSwapchainANDROID);
OPENXR_DECLARE_FN(xrEnumerateDepthSwapchainImagesANDROID);
OPENXR_DECLARE_FN(xrEnumerateDepthResolutionsANDROID);
OPENXR_DECLARE_FN(xrAcquireDepthSwapchainImagesANDROID);
#endif
};
// Ensure that we don't export our helper macro.
#undef OPENXR_DECLARE_FN
class OpenXrExtensionEnumeration {
public:
OpenXrExtensionEnumeration();
~OpenXrExtensionEnumeration();
bool ExtensionSupported(const char* extension_name) const;
private:
std::vector<XrExtensionProperties> extension_properties_;
};
class OpenXrExtensionHelper {
public:
OpenXrExtensionHelper(
XrInstance instance,
const OpenXrExtensionEnumeration* const extension_enumeration);
~OpenXrExtensionHelper();
const OpenXrExtensionEnumeration* ExtensionEnumeration() const {
return extension_enumeration_;
}
const OpenXrExtensionMethods& ExtensionMethods() const {
return extension_methods_;
}
// Returns whether or not we can support a given feature. If a given feature
// is determined to be supported solely by the core spec, we will simply
// return true for that feature as we assume the entire core spec is
// supported.
bool IsFeatureSupported(device::mojom::XRSessionFeature feature) const;
// Feature Implementation Helpers ---------------------------------------
//
// There may be multiple extensions that can support a given WebXR feature,
// though each device will likely only implement one of them. The following
// methods help provide managers for the various WebXR features that can
// abstract the *actual* extension that we need to use, since different
// extensions will be looking for different methods.
std::unique_ptr<OpenXrAnchorManager> CreateAnchorManager(
XrSession session,
XrSpace base_space) const;
std::unique_ptr<OpenXrDepthSensor> CreateDepthSensor(
XrSession session,
XrSpace base_space,
const mojom::XRDepthOptions& depth_options) const;
std::unique_ptr<OpenXrHandTracker> CreateHandTracker(
XrSession session,
OpenXrHandednessType handedness) const;
std::unique_ptr<OpenXrLightEstimator> CreateLightEstimator(
XrSession session,
XrSpace base_space) const;
std::unique_ptr<OpenXRSceneUnderstandingManager>
CreateSceneUnderstandingManager(XrSession session, XrSpace base_space) const;
std::unique_ptr<OpenXrStageBoundsProvider> CreateStageBoundsProvider(
XrSession session) const;
std::unique_ptr<OpenXrUnboundedSpaceProvider> CreateUnboundedSpaceProvider()
const;
private:
// Small helper method to check if a given extension is enabled.
bool IsExtensionSupported(const char* extension_name) const;
const OpenXrExtensionMethods extension_methods_;
const raw_ptr<const OpenXrExtensionEnumeration> extension_enumeration_;
};
} // namespace device
#endif // DEVICE_VR_OPENXR_OPENXR_EXTENSION_HELPER_H_