1 | // Copyright (c) 2017-2023, The Khronos Group Inc. |
2 | // Copyright (c) 2017 Valve Corporation |
3 | // Copyright (c) 2017 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 <openxr/openxr.h> |
13 | |
14 | #include <memory> |
15 | #include <string> |
16 | #include <vector> |
17 | #include <iosfwd> |
18 | #include <unordered_map> |
19 | |
20 | namespace Json { |
21 | class Value; |
22 | } |
23 | |
24 | enum ManifestFileType { |
25 | MANIFEST_TYPE_UNDEFINED = 0, |
26 | MANIFEST_TYPE_RUNTIME, |
27 | MANIFEST_TYPE_IMPLICIT_API_LAYER, |
28 | MANIFEST_TYPE_EXPLICIT_API_LAYER, |
29 | }; |
30 | |
31 | struct JsonVersion { |
32 | uint32_t major; |
33 | uint32_t minor; |
34 | uint32_t patch; |
35 | }; |
36 | |
37 | struct ExtensionListing { |
38 | std::string name; |
39 | uint32_t extension_version; |
40 | }; |
41 | |
42 | // ManifestFile class - |
43 | // Base class responsible for finding and parsing manifest files. |
44 | class ManifestFile { |
45 | public: |
46 | // Non-copyable |
47 | ManifestFile(const ManifestFile &) = delete; |
48 | ManifestFile &operator=(const ManifestFile &) = delete; |
49 | |
50 | ManifestFileType Type() const { return _type; } |
51 | const std::string &Filename() const { return _filename; } |
52 | const std::string &LibraryPath() const { return _library_path; } |
53 | void GetInstanceExtensionProperties(std::vector<XrExtensionProperties> &props); |
54 | const std::string &GetFunctionName(const std::string &func_name) const; |
55 | |
56 | protected: |
57 | ManifestFile(ManifestFileType type, const std::string &filename, const std::string &library_path); |
58 | void ParseCommon(Json::Value const &root_node); |
59 | static bool IsValidJson(const Json::Value &root, JsonVersion &version); |
60 | |
61 | private: |
62 | std::string _filename; |
63 | ManifestFileType _type; |
64 | std::string _library_path; |
65 | std::vector<ExtensionListing> _instance_extensions; |
66 | std::unordered_map<std::string, std::string> _functions_renamed; |
67 | }; |
68 | |
69 | // RuntimeManifestFile class - |
70 | // Responsible for finding and parsing Runtime-specific manifest files. |
71 | class RuntimeManifestFile : public ManifestFile { |
72 | public: |
73 | // Factory method |
74 | static XrResult FindManifestFiles(std::vector<std::unique_ptr<RuntimeManifestFile>> &manifest_files); |
75 | |
76 | private: |
77 | RuntimeManifestFile(const std::string &filename, const std::string &library_path); |
78 | static void CreateIfValid(const std::string &filename, std::vector<std::unique_ptr<RuntimeManifestFile>> &manifest_files); |
79 | static void CreateIfValid(const Json::Value &root_node, const std::string &filename, |
80 | std::vector<std::unique_ptr<RuntimeManifestFile>> &manifest_files); |
81 | }; |
82 | |
83 | using LibraryLocator = bool (*)(const std::string &json_filename, const std::string &library_path, std::string &out_combined_path); |
84 | |
85 | // ApiLayerManifestFile class - |
86 | // Responsible for finding and parsing API Layer-specific manifest files. |
87 | class ApiLayerManifestFile : public ManifestFile { |
88 | public: |
89 | // Factory method |
90 | static XrResult FindManifestFiles(ManifestFileType type, std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files); |
91 | |
92 | const std::string &LayerName() const { return _layer_name; } |
93 | void PopulateApiLayerProperties(XrApiLayerProperties &props) const; |
94 | |
95 | private: |
96 | ApiLayerManifestFile(ManifestFileType type, const std::string &filename, const std::string &layer_name, |
97 | const std::string &description, const JsonVersion &api_version, const uint32_t &implementation_version, |
98 | const std::string &library_path); |
99 | |
100 | static void CreateIfValid(ManifestFileType type, const std::string &filename, std::istream &json_stream, |
101 | LibraryLocator locate_library, std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files); |
102 | static void CreateIfValid(ManifestFileType type, const std::string &filename, |
103 | std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files); |
104 | /// @return false if we could not find the library. |
105 | static bool LocateLibraryRelativeToJson(const std::string &json_filename, const std::string &library_path, |
106 | std::string &out_combined_path); |
107 | #ifdef XR_USE_PLATFORM_ANDROID |
108 | static bool LocateLibraryInAssets(const std::string &json_filename, const std::string &library_path, |
109 | std::string &out_combined_path); |
110 | static void AddManifestFilesAndroid(ManifestFileType type, std::vector<std::unique_ptr<ApiLayerManifestFile>> &manifest_files); |
111 | #endif |
112 | |
113 | JsonVersion _api_version; |
114 | std::string _layer_name; |
115 | std::string _description; |
116 | uint32_t _implementation_version; |
117 | }; |
118 | |