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
20namespace Json {
21class Value;
22}
23
24enum ManifestFileType {
25 MANIFEST_TYPE_UNDEFINED = 0,
26 MANIFEST_TYPE_RUNTIME,
27 MANIFEST_TYPE_IMPLICIT_API_LAYER,
28 MANIFEST_TYPE_EXPLICIT_API_LAYER,
29};
30
31struct JsonVersion {
32 uint32_t major;
33 uint32_t minor;
34 uint32_t patch;
35};
36
37struct 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.
44class 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.
71class 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
83using 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.
87class 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