1// Copyright (c) 2017-2023, The Khronos Group Inc.
2// Copyright (c) 2017-2019 Valve Corporation
3// Copyright (c) 2017-2019 LunarG, Inc.
4//
5// SPDX-License-Identifier: Apache-2.0 OR MIT
6//
7// Initial Author: Mark Young <marky@lunarg.com>
8//
9
10#pragma once
11
12#include "extra_algorithms.h"
13#include "loader_interfaces.h"
14
15#include <openxr/openxr.h>
16
17#include <array>
18#include <cmath>
19#include <memory>
20#include <mutex>
21#include <string>
22#include <unordered_map>
23#include <vector>
24
25class ApiLayerInterface;
26struct XrGeneratedDispatchTable;
27class LoaderInstance;
28
29// Manage the single loader instance that is available.
30namespace ActiveLoaderInstance {
31// Set the active loader instance. This will fail if there is already an active loader instance.
32XrResult Set(std::unique_ptr<LoaderInstance> loader_instance, const char* log_function_name);
33
34// Returns true if there is an active loader instance.
35bool IsAvailable();
36
37// Get the active LoaderInstance.
38XrResult Get(LoaderInstance** loader_instance, const char* log_function_name);
39
40// Destroy the currently active LoaderInstance if there is one. This will make the loader able to create a new XrInstance if needed.
41void Remove();
42}; // namespace ActiveLoaderInstance
43
44// Manages information needed by the loader for an XrInstance, such as what extensions are available and the dispatch table.
45class LoaderInstance {
46 public:
47 // Factory method
48 static XrResult CreateInstance(PFN_xrGetInstanceProcAddr get_instance_proc_addr_term, PFN_xrCreateInstance create_instance_term,
49 PFN_xrCreateApiLayerInstance create_api_layer_instance_term,
50 std::vector<std::unique_ptr<ApiLayerInterface>> layer_interfaces,
51 const XrInstanceCreateInfo* createInfo, std::unique_ptr<LoaderInstance>* loader_instance);
52 static const std::array<XrExtensionProperties, 1>& LoaderSpecificExtensions();
53
54 virtual ~LoaderInstance();
55
56 XrInstance GetInstanceHandle() { return _runtime_instance; }
57 const std::unique_ptr<XrGeneratedDispatchTable>& DispatchTable() { return _dispatch_table; }
58 std::vector<std::unique_ptr<ApiLayerInterface>>& LayerInterfaces() { return _api_layer_interfaces; }
59 bool ExtensionIsEnabled(const std::string& extension);
60 XrDebugUtilsMessengerEXT DefaultDebugUtilsMessenger() { return _messenger; }
61 void SetDefaultDebugUtilsMessenger(XrDebugUtilsMessengerEXT messenger) { _messenger = messenger; }
62 XrResult GetInstanceProcAddr(const char* name, PFN_xrVoidFunction* function);
63
64 private:
65 LoaderInstance(XrInstance instance, const XrInstanceCreateInfo* createInfo, PFN_xrGetInstanceProcAddr topmost_gipa,
66 std::vector<std::unique_ptr<ApiLayerInterface>> api_layer_interfaces);
67
68 private:
69 XrInstance _runtime_instance{XR_NULL_HANDLE};
70 PFN_xrGetInstanceProcAddr _topmost_gipa{nullptr};
71 std::vector<std::string> _enabled_extensions;
72 std::vector<std::unique_ptr<ApiLayerInterface>> _api_layer_interfaces;
73
74 std::unique_ptr<XrGeneratedDispatchTable> _dispatch_table;
75 // Internal debug messenger created during xrCreateInstance
76 XrDebugUtilsMessengerEXT _messenger{XR_NULL_HANDLE};
77};
78