summaryrefslogtreecommitdiff
path: root/chromium/device/vr/openxr/openxr_util.cc
blob: 31d8eb569640f46a411fe3eee44bf0dd97b48b19 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "device/vr/openxr/openxr_util.h"
#include "device/vr/openxr/openxr_defs.h"

#include <d3d11.h>
#include <string>
#include <vector>

#include "base/check_op.h"
#include "base/stl_util.h"
#include "base/version.h"
#include "base/win/scoped_handle.h"
#include "build/build_config.h"
#include "components/version_info/version_info.h"
#include "third_party/openxr/src/include/openxr/openxr_platform.h"

namespace device {

XrPosef PoseIdentity() {
  XrPosef pose{};
  pose.orientation.w = 1;
  return pose;
}

XrResult GetSystem(XrInstance instance, XrSystemId* system) {
  XrSystemGetInfo system_info = {XR_TYPE_SYSTEM_GET_INFO};
  system_info.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
  return xrGetSystem(instance, &system_info, system);
}

#if defined(OS_WIN)
bool IsRunningInWin32AppContainer() {
  base::win::ScopedHandle scopedProcessToken;
  HANDLE processToken;
  if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &processToken)) {
    return false;
  }

  scopedProcessToken.Set(processToken);

  BOOL isAppContainer;
  DWORD dwSize = sizeof(BOOL);
  if (!GetTokenInformation(scopedProcessToken.Get(), TokenIsAppContainer,
                           &isAppContainer, dwSize, &dwSize)) {
    return false;
  }

  return isAppContainer;
}
#else
bool IsRunningInWin32AppContainer() {
  return false;
}
#endif

XrResult CreateInstance(XrInstance* instance,
                        OpenXRInstanceMetadata* metadata) {
  XrInstanceCreateInfo instance_create_info = {XR_TYPE_INSTANCE_CREATE_INFO};

  std::string application_name = version_info::GetProductName() + " " +
                                 version_info::GetMajorVersionNumber();
  errno_t error =
      strcpy_s(instance_create_info.applicationInfo.applicationName,
               base::size(instance_create_info.applicationInfo.applicationName),
               application_name.c_str());
  DCHECK_EQ(error, 0);

  base::Version version = version_info::GetVersion();
  DCHECK_EQ(version.components().size(), 4uLL);
  uint32_t build = version.components()[2];

  // application version will be the build number of each vendor
  instance_create_info.applicationInfo.applicationVersion = build;

  error = strcpy_s(instance_create_info.applicationInfo.engineName,
                   base::size(instance_create_info.applicationInfo.engineName),
                   "Chromium");
  DCHECK_EQ(error, 0);

  // engine version should be the build number of chromium
  instance_create_info.applicationInfo.engineVersion = build;

  instance_create_info.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;

  uint32_t extensionCount;
  RETURN_IF_XR_FAILED(xrEnumerateInstanceExtensionProperties(
      nullptr, 0, &extensionCount, nullptr));
  std::vector<XrExtensionProperties> extensionProperties(
      extensionCount, {XR_TYPE_EXTENSION_PROPERTIES});
  RETURN_IF_XR_FAILED(xrEnumerateInstanceExtensionProperties(
      nullptr, extensionCount, &extensionCount, extensionProperties.data()));

  // xrCreateInstance validates the list of extensions and returns
  // XR_ERROR_EXTENSION_NOT_PRESENT if an extension is not supported,
  // so we don't need to call xrEnumerateInstanceExtensionProperties
  // to validate these extensions.
  // Since the OpenXR backend only knows how to draw with D3D11 at the moment,
  // the XR_KHR_D3D11_ENABLE_EXTENSION_NAME is required.
  std::vector<const char*> extensions{XR_KHR_D3D11_ENABLE_EXTENSION_NAME};

  // If we are in an app container, we must require the app container extension
  // to ensure robust execution of the OpenXR runtime
  if (IsRunningInWin32AppContainer()) {
    // Add the win32 app container compatible extension to our list of
    // extensions. If this runtime does not support execution in an app
    // container environment, one of xrCreateInstance or xrGetSystem will fail.
    extensions.push_back(kWin32AppcontainerCompatibleExtensionName);
  }

  // XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME, is required for optional
  // functionality (unbounded reference spaces) and thus only requested if it is
  // available.
  auto extensionSupported = [&extensionProperties](const char* extensionName) {
    return std::find_if(
               extensionProperties.begin(), extensionProperties.end(),
               [&extensionName](const XrExtensionProperties& properties) {
                 return strcmp(properties.extensionName, extensionName) == 0;
               }) != extensionProperties.end();
  };

  const bool unboundedSpaceExtensionSupported =
      extensionSupported(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
  if (unboundedSpaceExtensionSupported) {
    extensions.push_back(XR_MSFT_UNBOUNDED_REFERENCE_SPACE_EXTENSION_NAME);
  }

  if (metadata != nullptr) {
    metadata->unboundedReferenceSpaceSupported =
        unboundedSpaceExtensionSupported;
  }

  instance_create_info.enabledExtensionCount =
      static_cast<uint32_t>(extensions.size());
  instance_create_info.enabledExtensionNames = extensions.data();

  return xrCreateInstance(&instance_create_info, instance);
}

}  // namespace device