├── .gitignore ├── LICENSE.txt ├── OPENXR_SDK_THIRD_PARTY_NOTICES.txt ├── OpenXR ├── Include │ └── openxr │ │ ├── openxr.h │ │ ├── openxr_pico.h │ │ ├── openxr_platform.h │ │ ├── openxr_platform_defines.h │ │ └── openxr_reflection.h ├── Libs │ └── Android │ │ ├── arm64-v8a │ │ └── libopenxr_loader.so │ │ └── armeabi-v7a │ │ └── libopenxr_loader.so ├── Projects │ └── AndroidPrebuilt │ │ ├── AndroidManifest.xml │ │ └── jni │ │ └── Android.mk └── Sample │ └── VideoPlayer │ ├── .gitignore │ ├── CMakeLists.txt │ ├── app │ ├── AndroidManifest.xml │ ├── CMakeLists.txt │ ├── check.h │ ├── common.h │ ├── d3d_common.cpp │ ├── d3d_common.h │ ├── geometry.h │ ├── graphicsapi.h │ ├── graphicsplugin.h │ ├── graphicsplugin_d3d11.cpp │ ├── graphicsplugin_d3d12.cpp │ ├── graphicsplugin_factory.cpp │ ├── graphicsplugin_opengl.cpp │ ├── graphicsplugin_opengles.cpp │ ├── graphicsplugin_vulkan.cpp │ ├── hello_xr.1 │ ├── java │ │ └── com │ │ │ └── khronos │ │ │ └── hello_xr │ │ │ └── MainActivity.java │ ├── logger.cpp │ ├── logger.h │ ├── main.cpp │ ├── openxr_program.cpp │ ├── openxr_program.h │ ├── options.h │ ├── pch.cpp │ ├── pch.h │ ├── platformdata.h │ ├── platformplugin.h │ ├── platformplugin_android.cpp │ ├── platformplugin_factory.cpp │ ├── platformplugin_win32.cpp │ ├── platformplugin_xlib.cpp │ ├── player.cpp │ ├── player.h │ └── vulkan_shaders │ │ ├── frag.spv │ │ ├── generate spv command.txt │ │ ├── shader.frag │ │ ├── shader.vert │ │ └── vert.spv │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── libs │ └── oboe-1.6.0.aar │ ├── openxr_loader │ ├── arm64-v8a │ │ ├── liboboe.so │ │ └── libopenxr_loader.so │ ├── armeabi-v7a │ │ ├── liboboe.so │ │ └── libopenxr_loader.so │ └── include │ │ ├── GL │ │ ├── gl_format.h │ │ ├── glext.h │ │ └── wglext.h │ │ ├── common │ │ ├── extra_algorithms.h │ │ ├── filesystem_utils.cpp │ │ ├── filesystem_utils.hpp │ │ ├── gfxwrapper_opengl.c │ │ ├── gfxwrapper_opengl.h │ │ ├── hex_and_handles.h │ │ ├── loader_interfaces.h │ │ ├── object_info.cpp │ │ ├── object_info.h │ │ ├── platform_utils.hpp │ │ ├── xr_dependencies.h │ │ └── xr_linear.h │ │ ├── openxr │ │ ├── openxr.h │ │ ├── openxr_pico.h │ │ ├── openxr_platform.h │ │ ├── openxr_platform_defines.h │ │ └── openxr_reflection.h │ │ └── utils │ │ ├── algebra.h │ │ ├── nanoseconds.h │ │ ├── sysinfo.h │ │ └── threading.h │ └── settings.gradle └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | */.idea 3 | *.iml 4 | .gradle 5 | /local.properties 6 | /.idea/caches 7 | /.idea/libraries 8 | /.idea/modules.xml 9 | /.idea/workspace.xml 10 | /.idea/navEditor.xml 11 | /.idea/assetWizardSettings.xml 12 | /.idea 13 | .DS_Store 14 | /build 15 | /captures 16 | .externalNativeBuild 17 | .cxx 18 | local.properties 19 | 20 | # Created by .ignore support plugin (hsz.mobi) 21 | ### Android template 22 | # Built application files 23 | *.apk 24 | # *.aar 25 | *.ap_ 26 | *.aab 27 | 28 | # Files for the ART/Dalvik VM 29 | *.dex 30 | 31 | # Java class files 32 | *.class 33 | 34 | # Generated files 35 | bin/ 36 | gen/ 37 | out/ 38 | # Uncomment the following line in case you need and you don't have the release build type files in your app 39 | # release/ 40 | 41 | # Gradle files 42 | .gradle/ 43 | build/ 44 | 45 | # Local configuration file (sdk path, etc) 46 | local.properties 47 | 48 | # Proguard folder generated by Eclipse 49 | proguard/ 50 | 51 | # Log Files 52 | *.log 53 | 54 | # Android Studio Navigation editor temp files 55 | .navigation/ 56 | 57 | # Android Studio captures folder 58 | captures/ 59 | 60 | # IntelliJ 61 | *.iml 62 | .idea/workspace.xml 63 | .idea/tasks.xml 64 | .idea/gradle.xml 65 | .idea/assetWizardSettings.xml 66 | .idea/dictionaries 67 | .idea/libraries 68 | # Android Studio 3 in .gitignore file. 69 | .idea/caches 70 | .idea/modules.xml 71 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 72 | .idea/navEditor.xml 73 | 74 | # Keystore files 75 | # Uncomment the following lines if you do not want to check your keystore files in. 76 | #*.jks 77 | #*.keystore 78 | 79 | # External native build folder generated in Android Studio 2.2 and later 80 | .externalNativeBuild 81 | .cxx/ 82 | 83 | # Google Services (e.g. APIs or Firebase) 84 | # google-services.json 85 | 86 | # Freeline 87 | freeline.py 88 | freeline/ 89 | freeline_project_description.json 90 | 91 | # fastlane 92 | fastlane/report.xml 93 | fastlane/Preview.html 94 | fastlane/screenshots 95 | fastlane/test_output 96 | fastlane/readme.md 97 | 98 | # Version control 99 | vcs.xml 100 | 101 | # lint 102 | lint/intermediates/ 103 | lint/generated/ 104 | lint/outputs/ 105 | lint/tmp/ 106 | # lint/reports/ 107 | 108 | .idea/.gitignore 109 | .idea/caches/ 110 | .idea/compiler.xml 111 | .idea/inspectionProfiles/ 112 | .idea/misc.xml 113 | .idea/modules/ 114 | .idea/vcs.xml 115 | .idea/jarRepositories.xml 116 | 117 | app/.cxx/ 118 | .gitattributes 119 | .idea/checkstyle-idea.xml 120 | .idea/checkstyleidea.tmp/ 121 | .idea/runConfigurations.xml 122 | 123 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C), 2015-2021, PicoVR. Co., Ltd. 2 | 3 | Your use of this SDK or tool is subject to the Pico SDK License Agreement, available at https://developer.pico-interactive.com/sdk -------------------------------------------------------------------------------- /OPENXR_SDK_THIRD_PARTY_NOTICES.txt: -------------------------------------------------------------------------------- 1 | THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF THIS SDK. 2 | 3 | Khronos-OpenXR 4 | 5 | // Copyright (c) 2017-2019 The Khronos Group Inc. 6 | // Copyright (c) 2017-2019 Valve Corporation 7 | // Copyright (c) 2017-2019 LunarG, Inc. 8 | // 9 | // Licensed under the Apache License, Version 2.0 (the "License"); 10 | // you may not use this file except in compliance with the License. 11 | // You may obtain a copy of the License at 12 | // 13 | // http://www.apache.org/licenses/LICENSE-2.0 14 | // 15 | // Unless required by applicable law or agreed to in writing, software 16 | // distributed under the License is distributed on an "AS IS" BASIS, 17 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | // See the License for the specific language governing permissions and 19 | // limitations under the License. 20 | // 21 | // Author: Mark Young 22 | 23 | Vulkan_1.1.100.0 24 | 25 | ** Copyright (c) 2015-2019 The Khronos Group Inc. 26 | ** 27 | ** Licensed under the Apache License, Version 2.0 (the "License"); 28 | ** you may not use this file except in compliance with the License. 29 | ** You may obtain a copy of the License at 30 | ** 31 | ** http://www.apache.org/licenses/LICENSE-2.0 32 | ** 33 | ** Unless required by applicable law or agreed to in writing, software 34 | ** distributed under the License is distributed on an "AS IS" BASIS, 35 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | ** See the License for the specific language governing permissions and 37 | ** limitations under the License. -------------------------------------------------------------------------------- /OpenXR/Include/openxr/openxr_platform_defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2017-2021, The Khronos Group Inc. 3 | ** 4 | ** SPDX-License-Identifier: Apache-2.0 OR MIT 5 | */ 6 | 7 | #ifndef OPENXR_PLATFORM_DEFINES_H_ 8 | #define OPENXR_PLATFORM_DEFINES_H_ 1 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* Platform-specific calling convention macros. 15 | * 16 | * Platforms should define these so that OpenXR clients call OpenXR functions 17 | * with the same calling conventions that the OpenXR implementation expects. 18 | * 19 | * XRAPI_ATTR - Placed before the return type in function declarations. 20 | * Useful for C++11 and GCC/Clang-style function attribute syntax. 21 | * XRAPI_CALL - Placed after the return type in function declarations. 22 | * Useful for MSVC-style calling convention syntax. 23 | * XRAPI_PTR - Placed between the '(' and '*' in function pointer types. 24 | * 25 | * Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void); 26 | * Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void); 27 | */ 28 | #if defined(_WIN32) 29 | #define XRAPI_ATTR 30 | // On Windows, functions use the stdcall convention 31 | #define XRAPI_CALL __stdcall 32 | #define XRAPI_PTR XRAPI_CALL 33 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 34 | #error "API not supported for the 'armeabi' NDK ABI" 35 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) 36 | // On Android 32-bit ARM targets, functions use the "hardfloat" 37 | // calling convention, i.e. float parameters are passed in registers. This 38 | // is true even if the rest of the application passes floats on the stack, 39 | // as it does by default when compiling for the armeabi-v7a NDK ABI. 40 | #define XRAPI_ATTR __attribute__((pcs("aapcs-vfp"))) 41 | #define XRAPI_CALL 42 | #define XRAPI_PTR XRAPI_ATTR 43 | #else 44 | // On other platforms, use the default calling convention 45 | #define XRAPI_ATTR 46 | #define XRAPI_CALL 47 | #define XRAPI_PTR 48 | #endif 49 | 50 | #include 51 | 52 | #if !defined(XR_NO_STDINT_H) 53 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 54 | typedef signed __int8 int8_t; 55 | typedef unsigned __int8 uint8_t; 56 | typedef signed __int16 int16_t; 57 | typedef unsigned __int16 uint16_t; 58 | typedef signed __int32 int32_t; 59 | typedef unsigned __int32 uint32_t; 60 | typedef signed __int64 int64_t; 61 | typedef unsigned __int64 uint64_t; 62 | #else 63 | #include 64 | #endif 65 | #endif // !defined( XR_NO_STDINT_H ) 66 | 67 | // XR_PTR_SIZE (in bytes) 68 | #if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)) 69 | #define XR_PTR_SIZE 8 70 | #else 71 | #define XR_PTR_SIZE 4 72 | #endif 73 | 74 | // Needed so we can use clang __has_feature portably. 75 | #if !defined(XR_COMPILER_HAS_FEATURE) 76 | #if defined(__clang__) 77 | #define XR_COMPILER_HAS_FEATURE(x) __has_feature(x) 78 | #else 79 | #define XR_COMPILER_HAS_FEATURE(x) 0 80 | #endif 81 | #endif 82 | 83 | // Identifies if the current compiler has C++11 support enabled. 84 | // Does not by itself identify if any given C++11 feature is present. 85 | #if !defined(XR_CPP11_ENABLED) && defined(__cplusplus) 86 | #if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) 87 | #define XR_CPP11_ENABLED 1 88 | #elif defined(_MSC_VER) && (_MSC_VER >= 1600) 89 | #define XR_CPP11_ENABLED 1 90 | #elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. 91 | #define XR_CPP11_ENABLED 1 92 | #endif 93 | #endif 94 | 95 | // Identifies if the current compiler supports C++11 nullptr. 96 | #if !defined(XR_CPP_NULLPTR_SUPPORTED) 97 | #if defined(XR_CPP11_ENABLED) && \ 98 | ((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \ 99 | (defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \ 100 | (defined(_MSC_VER) && (_MSC_VER >= 1600)) || \ 101 | (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) 102 | #define XR_CPP_NULLPTR_SUPPORTED 1 103 | #endif 104 | #endif 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /OpenXR/Libs/Android/arm64-v8a/libopenxr_loader.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Libs/Android/arm64-v8a/libopenxr_loader.so -------------------------------------------------------------------------------- /OpenXR/Libs/Android/armeabi-v7a/libopenxr_loader.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Libs/Android/armeabi-v7a/libopenxr_loader.so -------------------------------------------------------------------------------- /OpenXR/Projects/AndroidPrebuilt/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /OpenXR/Projects/AndroidPrebuilt/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | 4 | #-------------------------------------------------------- 5 | # libopenxr_loader.so 6 | # 7 | # OpenXR Loader 8 | #-------------------------------------------------------- 9 | include $(CLEAR_VARS) 10 | 11 | LOCAL_MODULE := openxr_loader 12 | 13 | LOCAL_SRC_FILES := ../../../Libs/Android/$(TARGET_ARCH_ABI)/lib$(LOCAL_MODULE).so 14 | 15 | # only export public headers 16 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../Include 17 | 18 | # NOTE: This check is added to prevent the following error when running a "make clean" where 19 | # the prebuilt lib may have been deleted: "LOCAL_SRC_FILES points to a missing file" 20 | ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_SRC_FILES))) 21 | include $(PREBUILT_SHARED_LIBRARY) 22 | endif 23 | 24 | include $(CLEAR_VARS) 25 | LOCAL_MODULE := Oboe 26 | LOCAL_SRC_FILES := ../../../Sample/HelloXR/build/Oboe/prefab/modules/oboe/libs/android.$(TARGET_ARCH_ABI)/liboboe.so 27 | include $(PREBUILT_SHARED_LIBRARY) 28 | 29 | APP_STL := c++_shared -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | .idea -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about using CMake with Android Studio, read the 2 | # documentation: https://d.android.com/studio/projects/add-native-code.html 3 | 4 | # Sets the minimum version of CMake required to build the native library. 5 | 6 | cmake_minimum_required(VERSION 3.4.1) 7 | 8 | # build native_app_glue as a static lib 9 | set(APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue) 10 | include_directories(${APP_GLUE_DIR}) 11 | add_library( app-glue STATIC ${APP_GLUE_DIR}/android_native_app_glue.c) 12 | 13 | 14 | add_definitions(-DXR_USE_PLATFORM_ANDROID) 15 | add_definitions(-DXR_USE_GRAPHICS_API_OPENGL_ES) 16 | add_definitions(-DXR_USE_GRAPHICS_API_VULKAN) 17 | set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate") 18 | 19 | 20 | file(GLOB LOCAL_HEADERS "app/*.h") 21 | file(GLOB LOCAL_SOURCE "app/*.cpp") 22 | file(GLOB VULKAN_SHADERS "app/vulkan_shaders/*.glsl") 23 | 24 | LINK_DIRECTORIES(openxr_loader/${ANDROID_ABI}) 25 | include_directories(openxr_loader/include) 26 | LINK_DIRECTORIES(build/Oboe/prefab/modules/oboe/libs/android.${ANDROID_ABI}) 27 | include_directories(build/Oboe/prefab/modules/oboe/include) 28 | 29 | add_library( # Sets the name of the library. 30 | player 31 | SHARED 32 | ${LOCAL_SOURCE} 33 | ${LOCAL_HEADERS} 34 | ${VULKAN_SHADERS} 35 | openxr_loader/include/common/gfxwrapper_opengl.c 36 | ) 37 | 38 | source_group("Headers" FILES ${LOCAL_HEADERS}) 39 | source_group("Shaders" FILES ${VULKAN_SHADERS}) 40 | 41 | 42 | if(VulkanHeaders_INCLUDE_DIRS) 43 | target_include_directories(player 44 | PRIVATE 45 | ${VulkanHeaders_INCLUDE_DIRS} 46 | ) 47 | endif() 48 | 49 | if(Vulkan_LIBRARY) 50 | target_link_libraries(player ${Vulkan_LIBRARY}) 51 | endif() 52 | 53 | # Specifies libraries CMake should link to your target library. You 54 | # can link multiple libraries, such as libraries you define in this 55 | # build script, prebuilt third-party libraries, or system libraries. 56 | 57 | target_link_libraries( # Specifies the target library. 58 | player 59 | oboe 60 | openxr_loader 61 | android 62 | mediandk 63 | vulkan 64 | EGL 65 | GLESv3 66 | app-glue 67 | log 68 | ) -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 The Khronos Group Inc. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # Author: 18 | # 19 | 20 | file(GLOB LOCAL_HEADERS "*.h" ) 21 | file(GLOB LOCAL_SOURCE "*.cpp" ) 22 | file(GLOB VULKAN_SHADERS "vulkan_shaders/*.glsl") 23 | 24 | # For including compiled shaders 25 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 26 | 27 | if(ANDROID) 28 | add_library(player MODULE 29 | ${LOCAL_SOURCE} 30 | ${LOCAL_HEADERS} 31 | ${VULKAN_SHADERS} 32 | $) 33 | target_link_libraries(player ${ANDROID_LIBRARY} ${ANDROID_LOG_LIBRARY}) 34 | else() 35 | add_executable(player 36 | ${LOCAL_SOURCE} 37 | ${LOCAL_HEADERS} 38 | ${VULKAN_SHADERS}) 39 | endif() 40 | set_target_properties(player PROPERTIES FOLDER ${SAMPLES_FOLDER}) 41 | 42 | source_group("Headers" FILES ${LOCAL_HEADERS}) 43 | source_group("Shaders" FILES ${VULKAN_SHADERS}) 44 | 45 | compile_glsl(run_hello_xr_glsl_compiles ${VULKAN_SHADERS}) 46 | 47 | add_dependencies(player 48 | generate_openxr_header 49 | run_hello_xr_glsl_compiles 50 | ) 51 | 52 | target_include_directories(player 53 | PRIVATE 54 | ${PROJECT_SOURCE_DIR}/src 55 | ${PROJECT_SOURCE_DIR}/src/common 56 | 57 | # for OpenXR headers 58 | ${PROJECT_SOURCE_DIR}/include 59 | ${PROJECT_BINARY_DIR}/include 60 | 61 | # for helper headers 62 | ${PROJECT_SOURCE_DIR}/external/include 63 | ) 64 | 65 | if(GLSLANG_VALIDATOR AND NOT GLSLC_COMMAND) 66 | target_compile_definitions(player PRIVATE USE_GLSLANGVALIDATOR) 67 | endif() 68 | 69 | if(Vulkan_FOUND) 70 | target_include_directories(player 71 | PRIVATE 72 | ${Vulkan_INCLUDE_DIRS} 73 | ) 74 | endif() 75 | 76 | target_link_libraries(player openxr_loader oboe) 77 | if(TARGET openxr-gfxwrapper) 78 | target_link_libraries(player openxr-gfxwrapper) 79 | endif() 80 | if(WIN32) 81 | if(MSVC) 82 | target_compile_definitions(player PRIVATE _CRT_SECURE_NO_WARNINGS) 83 | target_compile_options(player PRIVATE /Zc:wchar_t /Zc:forScope /W4 /WX) 84 | endif() 85 | target_link_libraries(player ole32) 86 | if(MSVC) 87 | # Right now can't build this on MinGW because of directxcolors, etc. 88 | target_link_libraries(player d3d11 d3d12 d3dcompiler dxgi) 89 | else() 90 | target_compile_definitions(player PRIVATE MISSING_DIRECTX_COLORS) 91 | endif() 92 | endif() 93 | 94 | if(Vulkan_LIBRARY) 95 | target_link_libraries(player ${Vulkan_LIBRARY}) 96 | endif() 97 | 98 | if(NOT ANDROID) 99 | install(TARGETS player 100 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 101 | if(NOT WIN32) 102 | install(FILES player.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/ COMPONENT ManPages) 103 | endif() 104 | endif() 105 | 106 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/check.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #include "common.h" 8 | 9 | #define CHK_STRINGIFY(x) #x 10 | #define TOSTRING(x) CHK_STRINGIFY(x) 11 | #define FILE_AND_LINE __FILE__ ":" TOSTRING(__LINE__) 12 | 13 | [[noreturn]] inline void Throw(std::string failureMessage, const char* originator = nullptr, const char* sourceLocation = nullptr) { 14 | if (originator != nullptr) { 15 | failureMessage += Fmt("\n Origin: %s", originator); 16 | } 17 | if (sourceLocation != nullptr) { 18 | failureMessage += Fmt("\n Source: %s", sourceLocation); 19 | } 20 | 21 | throw std::logic_error(failureMessage); 22 | } 23 | 24 | #define THROW(msg) Throw(msg, nullptr, FILE_AND_LINE); 25 | #define CHECK(exp) \ 26 | { \ 27 | if (!(exp)) { \ 28 | Throw("Check failed", #exp, FILE_AND_LINE); \ 29 | } \ 30 | } 31 | #define CHECK_MSG(exp, msg) \ 32 | { \ 33 | if (!(exp)) { \ 34 | Throw(msg, #exp, FILE_AND_LINE); \ 35 | } \ 36 | } 37 | 38 | [[noreturn]] inline void ThrowXrResult(XrResult res, const char* originator = nullptr, const char* sourceLocation = nullptr) { 39 | Throw(Fmt("XrResult failure [%s]", to_string(res)), originator, sourceLocation); 40 | } 41 | 42 | inline XrResult CheckXrResult(XrResult res, const char* originator = nullptr, const char* sourceLocation = nullptr) { 43 | if (XR_FAILED(res)) { 44 | ThrowXrResult(res, originator, sourceLocation); 45 | } 46 | 47 | return res; 48 | } 49 | 50 | #define THROW_XR(xr, cmd) ThrowXrResult(xr, #cmd, FILE_AND_LINE); 51 | #define CHECK_XRCMD(cmd) CheckXrResult(cmd, #cmd, FILE_AND_LINE); 52 | #define CHECK_XRRESULT(res, cmdStr) CheckXrResult(res, cmdStr, FILE_AND_LINE); 53 | 54 | #ifdef XR_USE_PLATFORM_WIN32 55 | 56 | [[noreturn]] inline void ThrowHResult(HRESULT hr, const char* originator = nullptr, const char* sourceLocation = nullptr) { 57 | Throw(Fmt("HRESULT failure [%x]", hr), originator, sourceLocation); 58 | } 59 | 60 | inline HRESULT CheckHResult(HRESULT hr, const char* originator = nullptr, const char* sourceLocation = nullptr) { 61 | if (FAILED(hr)) { 62 | ThrowHResult(hr, originator, sourceLocation); 63 | } 64 | 65 | return hr; 66 | } 67 | 68 | #define THROW_HR(hr, cmd) ThrowHResult(hr, #cmd, FILE_AND_LINE); 69 | #define CHECK_HRCMD(cmd) CheckHResult(cmd, #cmd, FILE_AND_LINE); 70 | #define CHECK_HRESULT(res, cmdStr) CheckHResult(res, cmdStr, FILE_AND_LINE); 71 | 72 | #endif -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // Macro to generate stringify functions for OpenXR enumerations based data provided in openxr_reflection.h 14 | // clang-format off 15 | #define ENUM_CASE_STR(name, val) case name: return #name; 16 | #define MAKE_TO_STRING_FUNC(enumType) \ 17 | inline const char* to_string(enumType e) { \ 18 | switch (e) { \ 19 | XR_LIST_ENUM_##enumType(ENUM_CASE_STR) \ 20 | default: return "Unknown " #enumType; \ 21 | } \ 22 | } 23 | // clang-format on 24 | 25 | MAKE_TO_STRING_FUNC(XrReferenceSpaceType); 26 | MAKE_TO_STRING_FUNC(XrViewConfigurationType); 27 | MAKE_TO_STRING_FUNC(XrEnvironmentBlendMode); 28 | MAKE_TO_STRING_FUNC(XrSessionState); 29 | MAKE_TO_STRING_FUNC(XrResult); 30 | MAKE_TO_STRING_FUNC(XrFormFactor); 31 | 32 | inline bool EqualsIgnoreCase(const std::string& s1, const std::string& s2, const std::locale& loc = std::locale()) { 33 | const std::ctype& ctype = std::use_facet>(loc); 34 | const auto compareCharLower = [&](char c1, char c2) { return ctype.tolower(c1) == ctype.tolower(c2); }; 35 | return s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), s2.begin(), compareCharLower); 36 | } 37 | 38 | struct IgnoreCaseStringLess { 39 | bool operator()(const std::string& a, const std::string& b, const std::locale& loc = std::locale()) const noexcept { 40 | const std::ctype& ctype = std::use_facet>(loc); 41 | const auto ignoreCaseCharLess = [&](char c1, char c2) { return ctype.tolower(c1) < ctype.tolower(c2); }; 42 | return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end(), ignoreCaseCharLess); 43 | } 44 | }; 45 | 46 | template 47 | struct ScopeGuard { 48 | // Needs C++17: static_assert(std::is_invocable_v, "Type must be invocable function."); 49 | 50 | ScopeGuard(T&& guard) noexcept : m_guard(std::move(guard)) {} 51 | 52 | ScopeGuard(ScopeGuard&&) noexcept = default; 53 | ScopeGuard& operator=(ScopeGuard&&) noexcept = default; 54 | 55 | ScopeGuard(ScopeGuard&) = delete; 56 | ScopeGuard& operator=(ScopeGuard&) = delete; 57 | 58 | ~ScopeGuard() { m_guard(); } 59 | 60 | private: 61 | T m_guard; 62 | }; 63 | 64 | // Usage: auto guard = MakeScopeGuard([&] { foobar; }); 65 | template 66 | ScopeGuard MakeScopeGuard(T&& guard) { 67 | return ScopeGuard(std::forward(guard)); 68 | } 69 | 70 | inline std::string Fmt(const char* fmt, ...) { 71 | va_list vl; 72 | va_start(vl, fmt); 73 | int size = std::vsnprintf(nullptr, 0, fmt, vl); 74 | va_end(vl); 75 | 76 | if (size != -1) { 77 | std::unique_ptr buffer(new char[size + 1]); 78 | 79 | va_start(vl, fmt); 80 | size = std::vsnprintf(buffer.get(), size + 1, fmt, vl); 81 | va_end(vl); 82 | if (size != -1) { 83 | return std::string(buffer.get(), size); 84 | } 85 | } 86 | 87 | throw std::runtime_error("Unexpected vsnprintf failure"); 88 | } 89 | 90 | // The equivalent of C++17 std::size. A helper to get the dimension for an array. 91 | template 92 | constexpr size_t ArraySize(const T (&/*unused*/)[Size]) noexcept { 93 | return Size; 94 | } 95 | 96 | #include "logger.h" 97 | #include "check.h" 98 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/d3d_common.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | 8 | #if (defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12)) && !defined(MISSING_DIRECTX_COLORS) 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "d3d_common.h" 15 | 16 | using namespace Microsoft::WRL; 17 | using namespace DirectX; 18 | 19 | XMMATRIX XM_CALLCONV LoadXrPose(const XrPosef& pose) { 20 | return XMMatrixAffineTransformation(DirectX::g_XMOne, DirectX::g_XMZero, 21 | XMLoadFloat4(reinterpret_cast(&pose.orientation)), 22 | XMLoadFloat3(reinterpret_cast(&pose.position))); 23 | } 24 | 25 | XMMATRIX XM_CALLCONV LoadXrMatrix(const XrMatrix4x4f& matrix) { 26 | // XrMatrix4x4f has same memory layout as DirectX Math (Row-major,post-multiplied = column-major,pre-multiplied) 27 | return XMLoadFloat4x4(reinterpret_cast(&matrix)); 28 | } 29 | 30 | ComPtr CompileShader(const char* hlsl, const char* entrypoint, const char* shaderTarget) { 31 | ComPtr compiled; 32 | ComPtr errMsgs; 33 | DWORD flags = D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS; 34 | 35 | #if !defined(NDEBUG) 36 | flags |= D3DCOMPILE_SKIP_OPTIMIZATION | D3DCOMPILE_DEBUG; 37 | #else 38 | flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; 39 | #endif 40 | 41 | HRESULT hr = D3DCompile(hlsl, strlen(hlsl), nullptr, nullptr, nullptr, entrypoint, shaderTarget, flags, 0, 42 | compiled.GetAddressOf(), errMsgs.GetAddressOf()); 43 | if (FAILED(hr)) { 44 | std::string errMsg((const char*)errMsgs->GetBufferPointer(), errMsgs->GetBufferSize()); 45 | Log::Write(Log::Level::Error, Fmt("D3DCompile failed %X: %s", hr, errMsg.c_str())); 46 | THROW_HR(hr, "D3DCompile"); 47 | } 48 | 49 | return compiled; 50 | } 51 | 52 | ComPtr GetAdapter(LUID adapterId) { 53 | // Create the DXGI factory. 54 | ComPtr dxgiFactory; 55 | CHECK_HRCMD(CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast(dxgiFactory.ReleaseAndGetAddressOf()))); 56 | 57 | for (UINT adapterIndex = 0;; adapterIndex++) { 58 | // EnumAdapters1 will fail with DXGI_ERROR_NOT_FOUND when there are no more adapters to enumerate. 59 | ComPtr dxgiAdapter; 60 | CHECK_HRCMD(dxgiFactory->EnumAdapters1(adapterIndex, dxgiAdapter.ReleaseAndGetAddressOf())); 61 | 62 | DXGI_ADAPTER_DESC1 adapterDesc; 63 | CHECK_HRCMD(dxgiAdapter->GetDesc1(&adapterDesc)); 64 | if (memcmp(&adapterDesc.AdapterLuid, &adapterId, sizeof(adapterId)) == 0) { 65 | Log::Write(Log::Level::Verbose, Fmt("Using graphics adapter %ws", adapterDesc.Description)); 66 | return dxgiAdapter; 67 | } 68 | } 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/d3d_common.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #if defined(XR_USE_GRAPHICS_API_D3D11) || defined(XR_USE_GRAPHICS_API_D3D12) 8 | 9 | #include 10 | 11 | struct ModelConstantBuffer { 12 | DirectX::XMFLOAT4X4 Model; 13 | }; 14 | struct ViewProjectionConstantBuffer { 15 | DirectX::XMFLOAT4X4 ViewProjection; 16 | }; 17 | 18 | // Separate entrypoints for the vertex and pixel shader functions. 19 | constexpr char ShaderHlsl[] = R"_( 20 | struct PSVertex { 21 | float4 Pos : SV_POSITION; 22 | float3 Color : COLOR0; 23 | }; 24 | struct Vertex { 25 | float3 Pos : POSITION; 26 | float3 Color : COLOR0; 27 | }; 28 | cbuffer ModelConstantBuffer : register(b0) { 29 | float4x4 Model; 30 | }; 31 | cbuffer ViewProjectionConstantBuffer : register(b1) { 32 | float4x4 ViewProjection; 33 | }; 34 | 35 | PSVertex MainVS(Vertex input) { 36 | PSVertex output; 37 | output.Pos = mul(mul(float4(input.Pos, 1), Model), ViewProjection); 38 | output.Color = input.Color; 39 | return output; 40 | } 41 | 42 | float4 MainPS(PSVertex input) : SV_TARGET { 43 | return float4(input.Color, 1); 44 | } 45 | )_"; 46 | 47 | DirectX::XMMATRIX XM_CALLCONV LoadXrPose(const XrPosef& pose); 48 | DirectX::XMMATRIX XM_CALLCONV LoadXrMatrix(const XrMatrix4x4f& matrix); 49 | 50 | Microsoft::WRL::ComPtr CompileShader(const char* hlsl, const char* entrypoint, const char* shaderTarget); 51 | Microsoft::WRL::ComPtr GetAdapter(LUID adapterId); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/geometry.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | namespace Geometry { 8 | 9 | struct Vertex { 10 | XrVector3f Position; 11 | XrVector3f Color; 12 | }; 13 | 14 | constexpr XrVector3f Red{1, 0, 0}; 15 | constexpr XrVector3f DarkRed{0.25f, 0, 0}; 16 | constexpr XrVector3f Green{0, 1, 0}; 17 | constexpr XrVector3f DarkGreen{0, 0.25f, 0}; 18 | constexpr XrVector3f Blue{0, 0, 1}; 19 | constexpr XrVector3f DarkBlue{0, 0, 0.25f}; 20 | 21 | // Vertices for a 1x1x1 meter cube. (Left/Right, Top/Bottom, Front/Back) 22 | constexpr XrVector3f LBB{-0.5f, -0.5f, -0.5f}; 23 | constexpr XrVector3f LBF{-0.5f, -0.5f, 0.5f}; 24 | constexpr XrVector3f LTB{-0.5f, 0.5f, -0.5f}; 25 | constexpr XrVector3f LTF{-0.5f, 0.5f, 0.5f}; 26 | constexpr XrVector3f RBB{0.5f, -0.5f, -0.5f}; 27 | constexpr XrVector3f RBF{0.5f, -0.5f, 0.5f}; 28 | constexpr XrVector3f RTB{0.5f, 0.5f, -0.5f}; 29 | constexpr XrVector3f RTF{0.5f, 0.5f, 0.5f}; 30 | 31 | #define CUBE_SIDE(V1, V2, V3, V4, V5, V6, COLOR) {V1, COLOR}, {V2, COLOR}, {V3, COLOR}, {V4, COLOR}, {V5, COLOR}, {V6, COLOR}, 32 | 33 | constexpr Vertex c_cubeVertices[] = { 34 | CUBE_SIDE(LTB, LBF, LBB, LTB, LTF, LBF, DarkRed) // -X 35 | CUBE_SIDE(RTB, RBB, RBF, RTB, RBF, RTF, Red) // +X 36 | CUBE_SIDE(LBB, LBF, RBF, LBB, RBF, RBB, DarkGreen) // -Y 37 | CUBE_SIDE(LTB, RTB, RTF, LTB, RTF, LTF, Green) // +Y 38 | CUBE_SIDE(LBB, RBB, RTB, LBB, RTB, LTB, DarkBlue) // -Z 39 | CUBE_SIDE(LBF, LTF, RTF, LBF, RTF, RBF, Blue) // +Z 40 | }; 41 | 42 | // Winding order is clockwise. Each side uses a different color. 43 | constexpr unsigned short c_cubeIndices[] = { 44 | 0, 1, 2, 3, 4, 5, // -X 45 | 6, 7, 8, 9, 10, 11, // +X 46 | 12, 13, 14, 15, 16, 17, // -Y 47 | 18, 19, 20, 21, 22, 23, // +Y 48 | 24, 25, 26, 27, 28, 29, // -Z 49 | 30, 31, 32, 33, 34, 35, // +Z 50 | }; 51 | 52 | } // namespace Geometry -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/graphicsapi.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | struct IGraphicsAdapter { 8 | virtual ~IGraphicsAdapter() = default; 9 | 10 | virtual std::vector GetInstanceExtensions() const = 0; 11 | 12 | virtual const XrBaseInStructure* GetGraphicsBinding() const = 0; 13 | }; 14 | 15 | struct IGraphicsApi { 16 | virtual ~IGraphicsApi() = default; 17 | 18 | virtual std::shared_ptr CreateAdapter(XrInstance instance, XrSystemId systemId) = 0; 19 | 20 | // OpenXR extensions required by this graphics API. 21 | virtual std::vector GetInstanceExtensions() const = 0; 22 | }; 23 | 24 | std::shared_ptr CreateGraphicsAPI(const std::shared_ptr& options, 25 | std::shared_ptr platformAdapter); 26 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/graphicsplugin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #include "player.h" 8 | 9 | struct Cube { 10 | XrPosef Pose; 11 | XrVector3f Scale; 12 | }; 13 | 14 | // Wraps a graphics API so the main openxr program can be graphics API-independent. 15 | struct IGraphicsPlugin { 16 | virtual ~IGraphicsPlugin() = default; 17 | 18 | // OpenXR extensions required by this graphics API. 19 | virtual std::vector GetInstanceExtensions() const = 0; 20 | 21 | // Create an instance of this graphics api for the provided instance and systemId. 22 | virtual void InitializeDevice(XrInstance instance, XrSystemId systemId) = 0; 23 | 24 | // Select the preferred swapchain format from the list of available formats. 25 | virtual int64_t SelectColorSwapchainFormat(const std::vector& runtimeFormats) const = 0; 26 | 27 | // Get the graphics binding header for session creation. 28 | virtual const XrBaseInStructure* GetGraphicsBinding() const = 0; 29 | 30 | // Allocate space for the swapchain image structures. These are different for each graphics API. The returned 31 | // pointers are valid for the lifetime of the graphics plugin. 32 | virtual std::vector AllocateSwapchainImageStructs( 33 | uint32_t capacity, const XrSwapchainCreateInfo& swapchainCreateInfo) = 0; 34 | 35 | // Render to a swapchain image for a projection view. 36 | virtual void RenderView(const XrCompositionLayerProjectionView& layerView, const XrSwapchainImageBaseHeader* swapchainImage, 37 | int64_t swapchainFormat, const std::vector& cubes) = 0; 38 | 39 | virtual void RenderView(const XrCompositionLayerProjectionView& layerView, const XrSwapchainImageBaseHeader* swapchainImage, 40 | int64_t swapchainFormat, const std::shared_ptr& frame, const int32_t eye) {}; 41 | 42 | virtual void SetVideoWidthHeight(int32_t videoWidth, int32_t videoHeight) {}; 43 | 44 | struct controllerInputAction { 45 | float x; 46 | float y; 47 | }; 48 | virtual void SetInputAction(int hand /*0-left, 1-right*/, controllerInputAction &input) {}; 49 | 50 | // Get recommended number of sub-data element samples in view (recommendedSwapchainSampleCount) 51 | // if supported by the graphics plugin. A supported value otherwise. 52 | virtual uint32_t GetSupportedSwapchainSampleCount(const XrViewConfigurationView& view) { 53 | return view.recommendedSwapchainSampleCount; 54 | } 55 | }; 56 | 57 | // Create a graphics plugin for the graphics API specified in the options. 58 | std::shared_ptr CreateGraphicsPlugin(const std::shared_ptr& options, 59 | std::shared_ptr platformPlugin); 60 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/graphicsplugin_d3d11.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | #include "geometry.h" 8 | #include "graphicsplugin.h" 9 | 10 | #if defined(XR_USE_GRAPHICS_API_D3D11) && !defined(MISSING_DIRECTX_COLORS) 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "d3d_common.h" 17 | 18 | using namespace Microsoft::WRL; 19 | using namespace DirectX; 20 | 21 | namespace { 22 | void InitializeD3D11DeviceForAdapter(IDXGIAdapter1* adapter, const std::vector& featureLevels, 23 | ID3D11Device** device, ID3D11DeviceContext** deviceContext) { 24 | UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; 25 | 26 | #if !defined(NDEBUG) 27 | creationFlags |= D3D11_CREATE_DEVICE_DEBUG; 28 | #endif 29 | 30 | // Create the Direct3D 11 API device object and a corresponding context. 31 | D3D_DRIVER_TYPE driverType = ((adapter == nullptr) ? D3D_DRIVER_TYPE_HARDWARE : D3D_DRIVER_TYPE_UNKNOWN); 32 | 33 | TryAgain: 34 | HRESULT hr = D3D11CreateDevice(adapter, driverType, 0, creationFlags, featureLevels.data(), (UINT)featureLevels.size(), 35 | D3D11_SDK_VERSION, device, nullptr, deviceContext); 36 | if (FAILED(hr)) { 37 | // If initialization failed, it may be because device debugging isn't supported, so retry without that. 38 | if ((creationFlags & D3D11_CREATE_DEVICE_DEBUG) && (hr == DXGI_ERROR_SDK_COMPONENT_MISSING)) { 39 | creationFlags &= ~D3D11_CREATE_DEVICE_DEBUG; 40 | goto TryAgain; 41 | } 42 | 43 | // If the initialization still fails, fall back to the WARP device. 44 | // For more information on WARP, see: http://go.microsoft.com/fwlink/?LinkId=286690 45 | if (driverType != D3D_DRIVER_TYPE_WARP) { 46 | driverType = D3D_DRIVER_TYPE_WARP; 47 | goto TryAgain; 48 | } 49 | } 50 | } 51 | 52 | struct D3D11GraphicsPlugin : public IGraphicsPlugin { 53 | D3D11GraphicsPlugin(const std::shared_ptr&, std::shared_ptr){}; 54 | 55 | std::vector GetInstanceExtensions() const override { return {XR_KHR_D3D11_ENABLE_EXTENSION_NAME}; } 56 | 57 | void InitializeDevice(XrInstance instance, XrSystemId systemId) override { 58 | PFN_xrGetD3D11GraphicsRequirementsKHR pfnGetD3D11GraphicsRequirementsKHR = nullptr; 59 | CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrGetD3D11GraphicsRequirementsKHR", 60 | reinterpret_cast(&pfnGetD3D11GraphicsRequirementsKHR))); 61 | 62 | // Create the D3D11 device for the adapter associated with the system. 63 | XrGraphicsRequirementsD3D11KHR graphicsRequirements{XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR}; 64 | CHECK_XRCMD(pfnGetD3D11GraphicsRequirementsKHR(instance, systemId, &graphicsRequirements)); 65 | const ComPtr adapter = GetAdapter(graphicsRequirements.adapterLuid); 66 | 67 | // Create a list of feature levels which are both supported by the OpenXR runtime and this application. 68 | std::vector featureLevels = {D3D_FEATURE_LEVEL_12_1, D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_1, 69 | D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0}; 70 | featureLevels.erase(std::remove_if(featureLevels.begin(), featureLevels.end(), 71 | [&](D3D_FEATURE_LEVEL fl) { return fl < graphicsRequirements.minFeatureLevel; }), 72 | featureLevels.end()); 73 | CHECK_MSG(featureLevels.size() != 0, "Unsupported minimum feature level!"); 74 | 75 | InitializeD3D11DeviceForAdapter(adapter.Get(), featureLevels, m_device.ReleaseAndGetAddressOf(), 76 | m_deviceContext.ReleaseAndGetAddressOf()); 77 | 78 | InitializeResources(); 79 | 80 | m_graphicsBinding.device = m_device.Get(); 81 | } 82 | 83 | void InitializeResources() { 84 | const ComPtr vertexShaderBytes = CompileShader(ShaderHlsl, "MainVS", "vs_5_0"); 85 | CHECK_HRCMD(m_device->CreateVertexShader(vertexShaderBytes->GetBufferPointer(), vertexShaderBytes->GetBufferSize(), nullptr, 86 | m_vertexShader.ReleaseAndGetAddressOf())); 87 | 88 | const ComPtr pixelShaderBytes = CompileShader(ShaderHlsl, "MainPS", "ps_5_0"); 89 | CHECK_HRCMD(m_device->CreatePixelShader(pixelShaderBytes->GetBufferPointer(), pixelShaderBytes->GetBufferSize(), nullptr, 90 | m_pixelShader.ReleaseAndGetAddressOf())); 91 | 92 | const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = { 93 | {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, 94 | {"COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, 95 | }; 96 | 97 | CHECK_HRCMD(m_device->CreateInputLayout(vertexDesc, (UINT)ArraySize(vertexDesc), vertexShaderBytes->GetBufferPointer(), 98 | vertexShaderBytes->GetBufferSize(), &m_inputLayout)); 99 | 100 | const CD3D11_BUFFER_DESC modelConstantBufferDesc(sizeof(ModelConstantBuffer), D3D11_BIND_CONSTANT_BUFFER); 101 | CHECK_HRCMD(m_device->CreateBuffer(&modelConstantBufferDesc, nullptr, m_modelCBuffer.ReleaseAndGetAddressOf())); 102 | 103 | const CD3D11_BUFFER_DESC viewProjectionConstantBufferDesc(sizeof(ViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER); 104 | CHECK_HRCMD( 105 | m_device->CreateBuffer(&viewProjectionConstantBufferDesc, nullptr, m_viewProjectionCBuffer.ReleaseAndGetAddressOf())); 106 | 107 | const D3D11_SUBRESOURCE_DATA vertexBufferData{Geometry::c_cubeVertices}; 108 | const CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(Geometry::c_cubeVertices), D3D11_BIND_VERTEX_BUFFER); 109 | CHECK_HRCMD(m_device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, m_cubeVertexBuffer.ReleaseAndGetAddressOf())); 110 | 111 | const D3D11_SUBRESOURCE_DATA indexBufferData{Geometry::c_cubeIndices}; 112 | const CD3D11_BUFFER_DESC indexBufferDesc(sizeof(Geometry::c_cubeIndices), D3D11_BIND_INDEX_BUFFER); 113 | CHECK_HRCMD(m_device->CreateBuffer(&indexBufferDesc, &indexBufferData, m_cubeIndexBuffer.ReleaseAndGetAddressOf())); 114 | } 115 | 116 | int64_t SelectColorSwapchainFormat(const std::vector& runtimeFormats) const override { 117 | // List of supported color swapchain formats. 118 | constexpr DXGI_FORMAT SupportedColorSwapchainFormats[] = { 119 | DXGI_FORMAT_R8G8B8A8_UNORM, 120 | DXGI_FORMAT_B8G8R8A8_UNORM, 121 | DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 122 | DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, 123 | }; 124 | 125 | auto swapchainFormatIt = 126 | std::find_first_of(runtimeFormats.begin(), runtimeFormats.end(), std::begin(SupportedColorSwapchainFormats), 127 | std::end(SupportedColorSwapchainFormats)); 128 | if (swapchainFormatIt == runtimeFormats.end()) { 129 | THROW("No runtime swapchain format supported for color swapchain"); 130 | } 131 | 132 | return *swapchainFormatIt; 133 | } 134 | 135 | const XrBaseInStructure* GetGraphicsBinding() const override { 136 | return reinterpret_cast(&m_graphicsBinding); 137 | } 138 | 139 | std::vector AllocateSwapchainImageStructs( 140 | uint32_t capacity, const XrSwapchainCreateInfo& /*swapchainCreateInfo*/) override { 141 | // Allocate and initialize the buffer of image structs (must be sequential in memory for xrEnumerateSwapchainImages). 142 | // Return back an array of pointers to each swapchain image struct so the consumer doesn't need to know the type/size. 143 | std::vector swapchainImageBuffer(capacity); 144 | std::vector swapchainImageBase; 145 | for (XrSwapchainImageD3D11KHR& image : swapchainImageBuffer) { 146 | image.type = XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR; 147 | swapchainImageBase.push_back(reinterpret_cast(&image)); 148 | } 149 | 150 | // Keep the buffer alive by moving it into the list of buffers. 151 | m_swapchainImageBuffers.push_back(std::move(swapchainImageBuffer)); 152 | 153 | return swapchainImageBase; 154 | } 155 | 156 | ComPtr GetDepthStencilView(ID3D11Texture2D* colorTexture) { 157 | // If a depth-stencil view has already been created for this back-buffer, use it. 158 | auto depthBufferIt = m_colorToDepthMap.find(colorTexture); 159 | if (depthBufferIt != m_colorToDepthMap.end()) { 160 | return depthBufferIt->second; 161 | } 162 | 163 | // This back-buffer has no corresponding depth-stencil texture, so create one with matching dimensions. 164 | D3D11_TEXTURE2D_DESC colorDesc; 165 | colorTexture->GetDesc(&colorDesc); 166 | 167 | D3D11_TEXTURE2D_DESC depthDesc{}; 168 | depthDesc.Width = colorDesc.Width; 169 | depthDesc.Height = colorDesc.Height; 170 | depthDesc.ArraySize = colorDesc.ArraySize; 171 | depthDesc.MipLevels = 1; 172 | depthDesc.Format = DXGI_FORMAT_R32_TYPELESS; 173 | depthDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL; 174 | depthDesc.SampleDesc.Count = 1; 175 | ComPtr depthTexture; 176 | CHECK_HRCMD(m_device->CreateTexture2D(&depthDesc, nullptr, depthTexture.ReleaseAndGetAddressOf())); 177 | 178 | // Create and cache the depth stencil view. 179 | ComPtr depthStencilView; 180 | CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D, DXGI_FORMAT_D32_FLOAT); 181 | CHECK_HRCMD(m_device->CreateDepthStencilView(depthTexture.Get(), &depthStencilViewDesc, depthStencilView.GetAddressOf())); 182 | depthBufferIt = m_colorToDepthMap.insert(std::make_pair(colorTexture, depthStencilView)).first; 183 | 184 | return depthStencilView; 185 | } 186 | 187 | void RenderView(const XrCompositionLayerProjectionView& layerView, const XrSwapchainImageBaseHeader* swapchainImage, 188 | int64_t swapchainFormat, const std::vector& cubes) override { 189 | CHECK(layerView.subImage.imageArrayIndex == 0); // Texture arrays not supported. 190 | 191 | ID3D11Texture2D* const colorTexture = reinterpret_cast(swapchainImage)->texture; 192 | 193 | CD3D11_VIEWPORT viewport((float)layerView.subImage.imageRect.offset.x, (float)layerView.subImage.imageRect.offset.y, 194 | (float)layerView.subImage.imageRect.extent.width, 195 | (float)layerView.subImage.imageRect.extent.height); 196 | m_deviceContext->RSSetViewports(1, &viewport); 197 | 198 | // Create RenderTargetView with original swapchain format (swapchain is typeless). 199 | ComPtr renderTargetView; 200 | const CD3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc(D3D11_RTV_DIMENSION_TEXTURE2D, (DXGI_FORMAT)swapchainFormat); 201 | CHECK_HRCMD( 202 | m_device->CreateRenderTargetView(colorTexture, &renderTargetViewDesc, renderTargetView.ReleaseAndGetAddressOf())); 203 | 204 | const ComPtr depthStencilView = GetDepthStencilView(colorTexture); 205 | 206 | // Clear swapchain and depth buffer. NOTE: This will clear the entire render target view, not just the specified view. 207 | // TODO: Do not clear to a color when using a pass-through view configuration. 208 | m_deviceContext->ClearRenderTargetView(renderTargetView.Get(), DirectX::Colors::DarkSlateGray); 209 | m_deviceContext->ClearDepthStencilView(depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); 210 | 211 | ID3D11RenderTargetView* renderTargets[] = {renderTargetView.Get()}; 212 | m_deviceContext->OMSetRenderTargets((UINT)ArraySize(renderTargets), renderTargets, depthStencilView.Get()); 213 | 214 | const XMMATRIX spaceToView = XMMatrixInverse(nullptr, LoadXrPose(layerView.pose)); 215 | XrMatrix4x4f projectionMatrix; 216 | XrMatrix4x4f_CreateProjectionFov(&projectionMatrix, GRAPHICS_D3D, layerView.fov, 0.05f, 100.0f); 217 | 218 | // Set shaders and constant buffers. 219 | ViewProjectionConstantBuffer viewProjection; 220 | XMStoreFloat4x4(&viewProjection.ViewProjection, XMMatrixTranspose(spaceToView * LoadXrMatrix(projectionMatrix))); 221 | m_deviceContext->UpdateSubresource(m_viewProjectionCBuffer.Get(), 0, nullptr, &viewProjection, 0, 0); 222 | 223 | ID3D11Buffer* const constantBuffers[] = {m_modelCBuffer.Get(), m_viewProjectionCBuffer.Get()}; 224 | m_deviceContext->VSSetConstantBuffers(0, (UINT)ArraySize(constantBuffers), constantBuffers); 225 | m_deviceContext->VSSetShader(m_vertexShader.Get(), nullptr, 0); 226 | m_deviceContext->PSSetShader(m_pixelShader.Get(), nullptr, 0); 227 | 228 | // Set cube primitive data. 229 | const UINT strides[] = {sizeof(Geometry::Vertex)}; 230 | const UINT offsets[] = {0}; 231 | ID3D11Buffer* vertexBuffers[] = {m_cubeVertexBuffer.Get()}; 232 | m_deviceContext->IASetVertexBuffers(0, (UINT)ArraySize(vertexBuffers), vertexBuffers, strides, offsets); 233 | m_deviceContext->IASetIndexBuffer(m_cubeIndexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0); 234 | m_deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 235 | m_deviceContext->IASetInputLayout(m_inputLayout.Get()); 236 | 237 | // Render each cube 238 | for (const Cube& cube : cubes) { 239 | // Compute and update the model transform. 240 | ModelConstantBuffer model; 241 | XMStoreFloat4x4(&model.Model, 242 | XMMatrixTranspose(XMMatrixScaling(cube.Scale.x, cube.Scale.y, cube.Scale.z) * LoadXrPose(cube.Pose))); 243 | m_deviceContext->UpdateSubresource(m_modelCBuffer.Get(), 0, nullptr, &model, 0, 0); 244 | 245 | // Draw the cube. 246 | m_deviceContext->DrawIndexed((UINT)ArraySize(Geometry::c_cubeIndices), 0, 0); 247 | } 248 | } 249 | 250 | private: 251 | ComPtr m_device; 252 | ComPtr m_deviceContext; 253 | XrGraphicsBindingD3D11KHR m_graphicsBinding{XR_TYPE_GRAPHICS_BINDING_D3D11_KHR}; 254 | std::list> m_swapchainImageBuffers; 255 | ComPtr m_vertexShader; 256 | ComPtr m_pixelShader; 257 | ComPtr m_inputLayout; 258 | ComPtr m_modelCBuffer; 259 | ComPtr m_viewProjectionCBuffer; 260 | ComPtr m_cubeVertexBuffer; 261 | ComPtr m_cubeIndexBuffer; 262 | 263 | // Map color buffer to associated depth buffer. This map is populated on demand. 264 | std::map> m_colorToDepthMap; 265 | }; 266 | } // namespace 267 | 268 | std::shared_ptr CreateGraphicsPlugin_D3D11(const std::shared_ptr& options, 269 | std::shared_ptr platformPlugin) { 270 | return std::make_shared(options, platformPlugin); 271 | } 272 | 273 | #endif 274 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/graphicsplugin_factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include 6 | 7 | #include "pch.h" 8 | #include "common.h" 9 | #include "options.h" 10 | #include "platformdata.h" 11 | #include "graphicsplugin.h" 12 | 13 | // Graphics API factories are forward declared here. 14 | #ifdef XR_USE_GRAPHICS_API_OPENGL_ES 15 | std::shared_ptr CreateGraphicsPlugin_OpenGLES(const std::shared_ptr& options, 16 | std::shared_ptr platformPlugin); 17 | #endif 18 | #ifdef XR_USE_GRAPHICS_API_OPENGL 19 | std::shared_ptr CreateGraphicsPlugin_OpenGL(const std::shared_ptr& options, 20 | std::shared_ptr platformPlugin); 21 | #endif 22 | #ifdef XR_USE_GRAPHICS_API_VULKAN 23 | std::shared_ptr CreateGraphicsPlugin_VulkanLegacy(const std::shared_ptr& options, 24 | std::shared_ptr platformPlugin); 25 | 26 | std::shared_ptr CreateGraphicsPlugin_Vulkan(const std::shared_ptr& options, 27 | std::shared_ptr platformPlugin); 28 | #endif 29 | #if defined(XR_USE_GRAPHICS_API_D3D11) && !defined(MISSING_DIRECTX_COLORS) 30 | std::shared_ptr CreateGraphicsPlugin_D3D11(const std::shared_ptr& options, 31 | std::shared_ptr platformPlugin); 32 | #endif 33 | #if defined(XR_USE_GRAPHICS_API_D3D12) && !defined(MISSING_DIRECTX_COLORS) 34 | std::shared_ptr CreateGraphicsPlugin_D3D12(const std::shared_ptr& options, 35 | std::shared_ptr platformPlugin); 36 | #endif 37 | 38 | namespace { 39 | using GraphicsPluginFactory = std::function(const std::shared_ptr& options, 40 | std::shared_ptr platformPlugin)>; 41 | 42 | std::map graphicsPluginMap = { 43 | #ifdef XR_USE_GRAPHICS_API_OPENGL_ES 44 | {"OpenGLES", 45 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 46 | return CreateGraphicsPlugin_OpenGLES(options, std::move(platformPlugin)); 47 | }}, 48 | #endif 49 | #ifdef XR_USE_GRAPHICS_API_OPENGL 50 | {"OpenGL", 51 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 52 | return CreateGraphicsPlugin_OpenGL(options, std::move(platformPlugin)); 53 | }}, 54 | #endif 55 | #ifdef XR_USE_GRAPHICS_API_VULKAN 56 | {"Vulkan", 57 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 58 | return CreateGraphicsPlugin_VulkanLegacy(options, std::move(platformPlugin)); 59 | }}, 60 | {"Vulkan2", 61 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 62 | return CreateGraphicsPlugin_Vulkan(options, std::move(platformPlugin)); 63 | }}, 64 | #endif 65 | #if defined(XR_USE_GRAPHICS_API_D3D11) && !defined(MISSING_DIRECTX_COLORS) 66 | {"D3D11", 67 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 68 | return CreateGraphicsPlugin_D3D11(options, std::move(platformPlugin)); 69 | }}, 70 | #endif 71 | #if defined(XR_USE_GRAPHICS_API_D3D12) && !defined(MISSING_DIRECTX_COLORS) 72 | {"D3D12", 73 | [](const std::shared_ptr& options, std::shared_ptr platformPlugin) { 74 | return CreateGraphicsPlugin_D3D12(options, std::move(platformPlugin)); 75 | }}, 76 | #endif 77 | }; 78 | } // namespace 79 | 80 | std::shared_ptr CreateGraphicsPlugin(const std::shared_ptr& options, 81 | std::shared_ptr platformPlugin) { 82 | if (options->GraphicsPlugin.empty()) { 83 | throw std::invalid_argument("No graphics API specified"); 84 | } 85 | 86 | const auto apiIt = graphicsPluginMap.find(options->GraphicsPlugin); 87 | if (apiIt == graphicsPluginMap.end()) { 88 | throw std::invalid_argument(Fmt("Unsupported graphics API '%s'", options->GraphicsPlugin.c_str())); 89 | } 90 | 91 | return apiIt->second(options, std::move(platformPlugin)); 92 | } 93 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/hello_xr.1: -------------------------------------------------------------------------------- 1 | .\" Composed by Ryan Pavlik 2 | .\" Copyright 2020, Collabora, Ltd. 3 | .\" SPDX-License-Identifier: Apache-2.0 4 | .Dd March 06, 2020 5 | .Dt HELLO_XR 1 6 | .Os 7 | .Sh NAME \" Section Header - required - don't modify 8 | .Nm hello_xr 9 | .Nd A sample OpenXR application. 10 | .Sh SYNOPSIS \" Section Header - required - don't modify 11 | .Nm 12 | .Op Fl h | Fl -help 13 | .Nm 14 | .Fl g | Fl -graphics Ar graphics_api 15 | .Op Fl ff | Fl -formfactor Ar form_factor 16 | .Op Fl vc | Fl -viewconfig Ar view_config 17 | .Op Fl bm | Fl -blendmode Ar blend_mode 18 | .Op Fl s | Fl -space Ar space 19 | .Op Fl v | Fl -verbose 20 | .Sh DESCRIPTION \" Section Header - required - don't modify 21 | .Nm 22 | is a sample application written using the 23 | .Tn OpenXR 24 | API. 25 | .Pp 26 | The arguments are as follows: 27 | .Bl -tag -width -indent 28 | .It Fl h | Fl -help 29 | Show brief usage instructions. 30 | .It g | Fl -graphics Ar graphics_api 31 | .Em Required: 32 | specify the graphics API to use. 33 | (Note that not that not all graphics APIs are necessarily available on all systems.) 34 | The parameter 35 | .Ar graphics_api 36 | must be one of the following (case-insensitive): 37 | .Bl -tag 38 | .It Ql D3D11 39 | Direct3D 11 (Windows-only) 40 | .It Ql D3D12 41 | Direct3D 12 (Windows-only) 42 | .It Ql OpenGLES 43 | .It Ql OpenGL 44 | .It Ql Vulkan 45 | .El 46 | .It Fl ff | Fl -formfactor Ar form_factor 47 | Specify the form factor to use. 48 | (Note that you need a suitable XR system and a runtime supporting a given form factor for it to work.) 49 | The parameter 50 | .Ar form_factor 51 | must be one of the following (case-insensitive): 52 | .Bl -tag 53 | .It Ql Hmd 54 | Head-mounted display (default) 55 | .It Ql Handheld 56 | .El 57 | .It Fl vc | Fl -viewconfig Ar view_config 58 | Specify the view configuration to use. 59 | (Note that you need a suitable XR system and a runtime supporting a given view configuration for it to work.) 60 | The parameter 61 | .Ar view_config 62 | must be one of the following (case-insensitive): 63 | .Bl -tag 64 | .It Ql Mono 65 | .It Ql Stereo 66 | (default) 67 | .El 68 | .It Fl bm | Fl -blendmode Ar blend_mode 69 | Specify the environment blend mode to use. 70 | (Note that you need a suitable XR system and a runtime supporting a given environment blend mode for it to work.) 71 | The parameter 72 | .Ar blend_mode 73 | must be one of the following (case-insensitive): 74 | .Bl -tag 75 | .It Ql Opaque 76 | .It Ql Additive 77 | .It Ql AlphaBlend 78 | .El 79 | .It Fl s | Fl -space Ar space 80 | Specify the space to use. 81 | The parameter 82 | .Ar space 83 | must be one of the following (case-insensitive): 84 | .Bl -tag 85 | .It Ql View 86 | .It Ql Local 87 | .It Ql Stage 88 | .El 89 | .It Fl v | Fl -verbose 90 | Enable verbose logging output from the 91 | .Nm 92 | application itself. 93 | .El 94 | .Sh EXIT STATUS 95 | .Ex -std 96 | .Sh SEE ALSO 97 | .Xr openxr_runtime_list 1 , 98 | https://www.khronos.org/registry/OpenXR/ , 99 | https://github.com/KhronosGroup/OpenXR-SDK-Source/tree/master/src/tests/hello_xr 100 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/java/com/khronos/hello_xr/MainActivity.java: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | package com.khronos.player; 5 | 6 | public class MainActivity extends android.app.NativeActivity { 7 | static { 8 | // Note: Must handle loading of dependent shared libraries manually before 9 | // the shared library that depends on them is loaded, since there is not 10 | // currently a way to specify a shared library dependency for NativeActivity 11 | // via the manifest meta-data. 12 | System.loadLibrary("openxr_loader"); 13 | System.loadLibrary("player"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/logger.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "logger.h" 7 | 8 | #include 9 | 10 | #if defined(ANDROID) 11 | #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, "player", __VA_ARGS__) 12 | #define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "player", __VA_ARGS__) 13 | #endif 14 | 15 | namespace { 16 | Log::Level g_minSeverity{Log::Level::Info}; 17 | std::mutex g_logLock; 18 | } // namespace 19 | 20 | namespace Log { 21 | void SetLevel(Level minSeverity) { g_minSeverity = minSeverity; } 22 | 23 | void Write(Level severity, const std::string& msg) { 24 | if (severity < g_minSeverity) { 25 | return; 26 | } 27 | 28 | const auto now = std::chrono::system_clock::now(); 29 | const time_t now_time = std::chrono::system_clock::to_time_t(now); 30 | tm now_tm; 31 | #ifdef _WIN32 32 | localtime_s(&now_tm, &now_time); 33 | #else 34 | localtime_r(&now_time, &now_tm); 35 | #endif 36 | // time_t only has second precision. Use the rounding error to get sub-second precision. 37 | const auto secondRemainder = now - std::chrono::system_clock::from_time_t(now_time); 38 | const int64_t milliseconds = std::chrono::duration_cast(secondRemainder).count(); 39 | 40 | static std::map severityName = { 41 | {Level::Verbose, "Verbose"}, {Level::Info, "Info "}, {Level::Warning, "Warning"}, {Level::Error, "Error "}}; 42 | 43 | std::ostringstream out; 44 | out.fill('0'); 45 | out << "[" << std::setw(2) << now_tm.tm_hour << ":" << std::setw(2) << now_tm.tm_min << ":" << std::setw(2) << now_tm.tm_sec 46 | << "." << std::setw(3) << milliseconds << "]" 47 | << "[" << severityName[severity] << "] " << msg << std::endl; 48 | 49 | std::lock_guard lock(g_logLock); // Ensure output is serialized 50 | ((severity == Level::Error) ? std::clog : std::cout) << out.str(); 51 | #if defined(_WIN32) 52 | OutputDebugStringA(out.str().c_str()); 53 | #endif 54 | #if defined(ANDROID) 55 | if (severity == Level::Error) 56 | ALOGE("%s", out.str().c_str()); 57 | else 58 | ALOGV("%s", out.str().c_str()); 59 | #endif 60 | } 61 | } // namespace Log 62 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/logger.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | namespace Log { 8 | enum class Level { Verbose, Info, Warning, Error }; 9 | 10 | void SetLevel(Level minSeverity); 11 | void Write(Level severity, const std::string& msg); 12 | } // namespace Log 13 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022, The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | #include "options.h" 8 | #include "platformdata.h" 9 | #include "platformplugin.h" 10 | #include "graphicsplugin.h" 11 | #include "openxr_program.h" 12 | 13 | void ShowHelp() { 14 | Log::Write(Log::Level::Info, "adb shell setprop debug.xr.graphicsPlugin OpenGLES|Vulkan"); 15 | Log::Write(Log::Level::Info, "adb shell setprop debug.xr.formFactor Hmd|Handheld"); 16 | Log::Write(Log::Level::Info, "adb shell setprop debug.xr.viewConfiguration Stereo|Mono"); 17 | Log::Write(Log::Level::Info, "adb shell setprop debug.xr.blendMode Opaque|Additive|AlphaBlend"); 18 | } 19 | 20 | bool UpdateOptionsFromSystemProperties(Options& options) { 21 | char value[PROP_VALUE_MAX] = {}; 22 | if (__system_property_get("debug.xr.graphicsPlugin", value) != 0) { 23 | options.GraphicsPlugin = value; 24 | } 25 | // Check for required parameters. 26 | if (options.GraphicsPlugin.empty()) { 27 | Log::Write(Log::Level::Warning, "GraphicsPlugin Default OpenGLES"); 28 | options.GraphicsPlugin = "OpenGLES"; 29 | } 30 | return true; 31 | } 32 | 33 | struct AndroidAppState { 34 | ANativeWindow* NativeWindow = nullptr; 35 | bool Resumed = false; 36 | }; 37 | 38 | /** 39 | * Process the next main command. 40 | */ 41 | static void app_handle_cmd(struct android_app* app, int32_t cmd) { 42 | AndroidAppState* appState = (AndroidAppState*)app->userData; 43 | switch (cmd) { 44 | // There is no APP_CMD_CREATE. The ANativeActivity creates the 45 | // application thread from onCreate(). The application thread 46 | // then calls android_main(). 47 | case APP_CMD_START: { 48 | Log::Write(Log::Level::Info, " APP_CMD_START"); 49 | Log::Write(Log::Level::Info, "onStart()"); 50 | break; 51 | } 52 | case APP_CMD_RESUME: { 53 | Log::Write(Log::Level::Info, "onResume()"); 54 | Log::Write(Log::Level::Info, " APP_CMD_RESUME"); 55 | appState->Resumed = true; 56 | break; 57 | } 58 | case APP_CMD_PAUSE: { 59 | Log::Write(Log::Level::Info, "onPause()"); 60 | Log::Write(Log::Level::Info, " APP_CMD_PAUSE"); 61 | appState->Resumed = false; 62 | break; 63 | } 64 | case APP_CMD_STOP: { 65 | Log::Write(Log::Level::Info, "onStop()"); 66 | Log::Write(Log::Level::Info, " APP_CMD_STOP"); 67 | break; 68 | } 69 | case APP_CMD_DESTROY: { 70 | Log::Write(Log::Level::Info, "onDestroy()"); 71 | Log::Write(Log::Level::Info, " APP_CMD_DESTROY"); 72 | appState->NativeWindow = NULL; 73 | break; 74 | } 75 | case APP_CMD_INIT_WINDOW: { 76 | Log::Write(Log::Level::Info, "surfaceCreated()"); 77 | Log::Write(Log::Level::Info, " APP_CMD_INIT_WINDOW"); 78 | appState->NativeWindow = app->window; 79 | break; 80 | } 81 | case APP_CMD_TERM_WINDOW: { 82 | Log::Write(Log::Level::Info, "surfaceDestroyed()"); 83 | Log::Write(Log::Level::Info, " APP_CMD_TERM_WINDOW"); 84 | appState->NativeWindow = NULL; 85 | break; 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * This is the main entry point of a native application that is using 92 | * android_native_app_glue. It runs in its own thread, with its own 93 | * event loop for receiving input events and doing other things. 94 | */ 95 | void android_main(struct android_app* app) { 96 | try { 97 | JNIEnv* Env; 98 | app->activity->vm->AttachCurrentThread(&Env, nullptr); 99 | 100 | AndroidAppState appState = {}; 101 | 102 | app->userData = &appState; 103 | app->onAppCmd = app_handle_cmd; 104 | 105 | std::shared_ptr options = std::make_shared(); 106 | if (!UpdateOptionsFromSystemProperties(*options)) { 107 | return; 108 | } 109 | 110 | std::shared_ptr data = std::make_shared(); 111 | data->applicationVM = app->activity->vm; 112 | data->applicationActivity = app->activity->clazz; 113 | 114 | bool requestRestart = false; 115 | bool exitRenderLoop = false; 116 | 117 | // Create platform-specific implementation. 118 | std::shared_ptr platformPlugin = CreatePlatformPlugin(options, data); 119 | // Create graphics API implementation. 120 | std::shared_ptr graphicsPlugin = CreateGraphicsPlugin(options, platformPlugin); 121 | 122 | // Initialize the OpenXR program. 123 | std::shared_ptr program = CreateOpenXrProgram(options, platformPlugin, graphicsPlugin); 124 | 125 | // Initialize the loader for this platform 126 | PFN_xrInitializeLoaderKHR initializeLoader = nullptr; 127 | if (XR_SUCCEEDED(xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)(&initializeLoader)))) { 128 | XrLoaderInitInfoAndroidKHR loaderInitInfoAndroid; 129 | memset(&loaderInitInfoAndroid, 0, sizeof(loaderInitInfoAndroid)); 130 | loaderInitInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR; 131 | loaderInitInfoAndroid.next = NULL; 132 | loaderInitInfoAndroid.applicationVM = app->activity->vm; 133 | loaderInitInfoAndroid.applicationContext = app->activity->clazz; 134 | initializeLoader((const XrLoaderInitInfoBaseHeaderKHR*)&loaderInitInfoAndroid); 135 | } 136 | 137 | program->StartPlayer(); 138 | program->CreateInstance(); 139 | program->InitializeSystem(); 140 | program->InitializeSession(); 141 | program->CreateSwapchains(); 142 | 143 | while (app->destroyRequested == 0) { 144 | // Read all pending events. 145 | for (;;) { 146 | int events; 147 | struct android_poll_source* source; 148 | // If the timeout is zero, returns immediately without blocking. 149 | // If the timeout is negative, waits indefinitely until an event appears. 150 | const int timeoutMilliseconds = (!appState.Resumed && !program->IsSessionRunning() && app->destroyRequested == 0) ? -1 : 0; 151 | if (ALooper_pollAll(timeoutMilliseconds, nullptr, &events, (void**)&source) < 0) { 152 | break; 153 | } 154 | 155 | // Process this event. 156 | if (source != nullptr) { 157 | source->process(app, source); 158 | } 159 | } 160 | 161 | program->PollEvents(&exitRenderLoop, &requestRestart); 162 | 163 | if (exitRenderLoop && !requestRestart) { 164 | ANativeActivity_finish(app->activity); 165 | } 166 | 167 | if (!program->IsSessionRunning()) { 168 | // Throttle loop since xrWaitFrame won't be called. 169 | std::this_thread::sleep_for(std::chrono::milliseconds(250)); 170 | continue; 171 | } 172 | 173 | program->PollActions(); 174 | program->RenderFrame(); 175 | } 176 | app->activity->vm->DetachCurrentThread(); 177 | } 178 | catch (const std::exception &ex) 179 | { 180 | Log::Write(Log::Level::Error, ex.what()); 181 | } 182 | catch (...) 183 | { 184 | Log::Write(Log::Level::Error, "Unknown Error"); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/openxr_program.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022, The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | struct IOpenXrProgram { 8 | virtual ~IOpenXrProgram() = default; 9 | 10 | // Create an Instance and other basic instance-level initialization. 11 | virtual void CreateInstance() = 0; 12 | 13 | // Select a System for the view configuration specified in the Options and initialize the graphics device for the selected 14 | // system. 15 | virtual void InitializeSystem() = 0; 16 | 17 | // Create a Session and other basic session-level initialization. 18 | virtual void InitializeSession() = 0; 19 | 20 | // Create a Swapchain which requires coordinating with the graphics plugin to select the format, getting the system graphics 21 | // properties, getting the view configuration and grabbing the resulting swapchain images. 22 | virtual void CreateSwapchains() = 0; 23 | 24 | // Process any events in the event queue. 25 | virtual void PollEvents(bool* exitRenderLoop, bool* requestRestart) = 0; 26 | 27 | // Manage session lifecycle to track if RenderFrame should be called. 28 | virtual bool IsSessionRunning() const = 0; 29 | 30 | // Manage session state to track if input should be processed. 31 | virtual bool IsSessionFocused() const = 0; 32 | 33 | // Sample input actions and generate haptic feedback. 34 | virtual void PollActions() = 0; 35 | 36 | // Create and submit a frame. 37 | virtual void RenderFrame() = 0; 38 | 39 | virtual bool StartPlayer() = 0; 40 | }; 41 | 42 | struct Swapchain { 43 | XrSwapchain handle; 44 | int32_t width; 45 | int32_t height; 46 | }; 47 | 48 | std::shared_ptr CreateOpenXrProgram(const std::shared_ptr& options, 49 | const std::shared_ptr& platformPlugin, 50 | const std::shared_ptr& graphicsPlugin); 51 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/options.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2022 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | struct Options { 8 | std::string GraphicsPlugin{"OpenGLES"}; //configurable: Vulkan2, OpenGLES 9 | 10 | std::string FormFactor{"Hmd"}; 11 | 12 | std::string ViewConfiguration{"Stereo"}; 13 | 14 | std::string EnvironmentBlendMode{"Opaque"}; 15 | 16 | std::string AppSpace{"Local"}; 17 | 18 | std::string VideoMode{"3D-SBS"}; //Configurable: 2D, 3D-SBS, 3D-OU, 360 19 | 20 | std::string VideoFileName{"/sdcard/test3d.mp4"}; 21 | 22 | struct { 23 | XrFormFactor FormFactor{XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY}; 24 | 25 | XrViewConfigurationType ViewConfigType{XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO}; 26 | 27 | XrEnvironmentBlendMode EnvironmentBlendMode{XR_ENVIRONMENT_BLEND_MODE_OPAQUE}; 28 | } Parsed; 29 | }; 30 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/pch.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/pch.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | // 32 | // Platform Headers 33 | // 34 | #ifdef XR_USE_PLATFORM_WIN32 35 | #ifndef WIN32_LEAN_AND_MEAN 36 | #define WIN32_LEAN_AND_MEAN 37 | #endif // !WIN32_LEAN_AND_MEAN 38 | 39 | #ifndef NOMINMAX 40 | #define NOMINMAX 41 | #endif // !NOMINMAX 42 | 43 | #include 44 | #include // For Microsoft::WRL::ComPtr 45 | #endif 46 | 47 | #ifdef XR_USE_PLATFORM_ANDROID 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #endif 54 | 55 | #ifdef XR_USE_PLATFORM_WAYLAND 56 | #include "wayland-client.h" 57 | #endif 58 | 59 | #ifdef XR_USE_PLATFORM_XLIB 60 | #include 61 | #include 62 | #endif 63 | 64 | #ifdef XR_USE_PLATFORM_XCB 65 | #include 66 | #endif 67 | 68 | // 69 | // Graphics Headers 70 | // 71 | #ifdef XR_USE_GRAPHICS_API_D3D11 72 | #include 73 | #endif 74 | 75 | #ifdef XR_USE_GRAPHICS_API_D3D12 76 | #include 77 | #endif 78 | 79 | #ifdef XR_USE_GRAPHICS_API_OPENGL 80 | #if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) 81 | #include 82 | #endif 83 | #ifdef XR_USE_PLATFORM_XCB 84 | #include 85 | #endif 86 | #ifdef XR_USE_PLATFORM_WIN32 87 | #include // For HGLRC 88 | #include 89 | #endif 90 | #endif 91 | 92 | #ifdef XR_USE_GRAPHICS_API_OPENGL_ES 93 | #include 94 | #endif 95 | 96 | #ifdef XR_USE_GRAPHICS_API_VULKAN 97 | #ifdef XR_USE_PLATFORM_WIN32 98 | #define VK_USE_PLATFORM_WIN32_KHR 99 | #endif 100 | #ifdef XR_USE_PLATFORM_ANDROID 101 | #define VK_USE_PLATFORM_ANDROID_KHR 102 | #endif 103 | #include 104 | #endif 105 | 106 | // 107 | // OpenXR Headers 108 | // 109 | #include 110 | #include 111 | #include 112 | #include -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformdata.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | struct PlatformData { 8 | #ifdef XR_USE_PLATFORM_ANDROID 9 | void* applicationVM; 10 | void* applicationActivity; 11 | #endif 12 | }; 13 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformplugin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #pragma once 6 | 7 | // Wraps platform-specific implementation so the main openxr program can be platform-independent. 8 | struct IPlatformPlugin { 9 | virtual ~IPlatformPlugin() = default; 10 | 11 | // Provide extension to XrInstanceCreateInfo for xrCreateInstance. 12 | virtual XrBaseInStructure* GetInstanceCreateExtension() const = 0; 13 | 14 | // OpenXR instance-level extensions required by this platform. 15 | virtual std::vector GetInstanceExtensions() const = 0; 16 | }; 17 | 18 | // Create a platform plugin for the platform specified at compile time. 19 | std::shared_ptr CreatePlatformPlugin(const std::shared_ptr& options, 20 | const std::shared_ptr& data); 21 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformplugin_android.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | #include "platformdata.h" 8 | #include "platformplugin.h" 9 | 10 | #ifdef XR_USE_PLATFORM_ANDROID 11 | 12 | namespace { 13 | struct AndroidPlatformPlugin : public IPlatformPlugin { 14 | AndroidPlatformPlugin(const std::shared_ptr& /*unused*/, const std::shared_ptr& data) { 15 | instanceCreateInfoAndroid = {XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR}; 16 | instanceCreateInfoAndroid.applicationVM = data->applicationVM; 17 | instanceCreateInfoAndroid.applicationActivity = data->applicationActivity; 18 | 19 | PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR; 20 | xrGetInstanceProcAddr(XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&xrInitializeLoaderKHR); 21 | if (xrInitializeLoaderKHR != NULL) { 22 | XrLoaderInitInfoAndroidKHR loaderInitializeInfoAndroid; 23 | memset(&loaderInitializeInfoAndroid, 0, sizeof(loaderInitializeInfoAndroid)); 24 | loaderInitializeInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR; 25 | loaderInitializeInfoAndroid.next = nullptr; 26 | loaderInitializeInfoAndroid.applicationVM = data->applicationVM; 27 | loaderInitializeInfoAndroid.applicationContext = data->applicationActivity; 28 | xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loaderInitializeInfoAndroid); 29 | } 30 | } 31 | 32 | std::vector GetInstanceExtensions() const override { return {XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME}; } 33 | 34 | XrBaseInStructure* GetInstanceCreateExtension() const override { return (XrBaseInStructure*)&instanceCreateInfoAndroid; } 35 | 36 | XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid; 37 | }; 38 | } // namespace 39 | 40 | std::shared_ptr CreatePlatformPlugin_Android(const std::shared_ptr& options, 41 | const std::shared_ptr& data) { 42 | return std::make_shared(options, data); 43 | } 44 | #endif 45 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformplugin_factory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "platformplugin.h" 7 | 8 | #define UNUSED_PARM(x) \ 9 | { (void)(x); } 10 | 11 | // Implementation in platformplugin_win32.cpp 12 | std::shared_ptr CreatePlatformPlugin_Win32(const std::shared_ptr& options); 13 | 14 | std::shared_ptr CreatePlatformPlugin_Wayland(const std::shared_ptr& /*unused*/) { 15 | // TODO: Implementation should go in its own cpp. Perhaps can share implementation with other 16 | // window managers? 17 | throw std::runtime_error("Wayland Platform Adapter Not Implemented"); 18 | } 19 | 20 | std::shared_ptr CreatePlatformPlugin_Xlib(const std::shared_ptr&); 21 | 22 | std::shared_ptr CreatePlatformPlugin_Xcb(const std::shared_ptr& /*unused*/) { 23 | // TODO: Implementation should go in its own cpp. Perhaps can share implementation with other 24 | // window managers? 25 | throw std::runtime_error("Xcb Platform Adapter Not Implemented"); 26 | } 27 | 28 | std::shared_ptr CreatePlatformPlugin_Android(const std::shared_ptr& /*unused*/, 29 | const std::shared_ptr& /*unused*/); 30 | 31 | std::shared_ptr CreatePlatformPlugin(const std::shared_ptr& options, 32 | const std::shared_ptr& data) { 33 | #if !defined(XR_USE_PLATFORM_ANDROID) 34 | UNUSED_PARM(data); 35 | #endif 36 | 37 | #if defined(XR_USE_PLATFORM_WIN32) 38 | return CreatePlatformPlugin_Win32(options); 39 | #elif defined(XR_USE_PLATFORM_ANDROID) 40 | return CreatePlatformPlugin_Android(options, data); 41 | #elif defined(XR_USE_PLATFORM_XLIB) 42 | return CreatePlatformPlugin_Xlib(options); 43 | #elif defined(XR_USE_PLATFORM_XCB) 44 | return CreatePlatformPlugin_Xcb(options); 45 | #elif defined(XR_USE_PLATFORM_WAYLAND) 46 | return CreatePlatformPlugin_Wayland(options); 47 | #else 48 | #error Unsupported platform or no XR platform defined! 49 | #endif 50 | } 51 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformplugin_win32.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | #include "platformplugin.h" 8 | 9 | #ifdef XR_USE_PLATFORM_WIN32 10 | namespace { 11 | struct Win32PlatformPlugin : public IPlatformPlugin { 12 | Win32PlatformPlugin(const std::shared_ptr&) { CHECK_HRCMD(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); } 13 | 14 | virtual ~Win32PlatformPlugin() { CoUninitialize(); } 15 | 16 | std::vector GetInstanceExtensions() const override { return {}; } 17 | 18 | XrBaseInStructure* GetInstanceCreateExtension() const override { return nullptr; } 19 | }; 20 | } // namespace 21 | 22 | std::shared_ptr CreatePlatformPlugin_Win32(const std::shared_ptr& options) { 23 | return std::make_shared(options); 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/platformplugin_xlib.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | 5 | #include "pch.h" 6 | #include "common.h" 7 | #include "platformplugin.h" 8 | 9 | #ifdef XR_USE_PLATFORM_XLIB 10 | namespace { 11 | struct XlibPlatformPlugin : public IPlatformPlugin { 12 | XlibPlatformPlugin(const std::shared_ptr& /*unused*/) {} 13 | 14 | std::vector GetInstanceExtensions() const override { return {}; } 15 | 16 | XrBaseInStructure* GetInstanceCreateExtension() const override { return nullptr; } 17 | }; 18 | } // namespace 19 | 20 | std::shared_ptr CreatePlatformPlugin_Xlib(const std::shared_ptr& options) { 21 | return std::make_shared(options); 22 | } 23 | #endif 24 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/player.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (2021-2023) Bytedance Ltd. and/or its affiliates, All rights reserved. 2 | // 3 | // This file provides an example of 3D decoding and play. 4 | // 5 | // Created by shunxiang at 2022/09/22 6 | 7 | #include "player.h" 8 | #include "pch.h" 9 | #include "common.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | CPlayer::CPlayer() : mExtractor(nullptr), mVideoCodec(nullptr), mFd(-1), mStarted(false) { 18 | } 19 | 20 | CPlayer::~CPlayer() { 21 | if (mExtractor) { 22 | AMediaExtractor_delete(mExtractor); 23 | mExtractor = nullptr; 24 | } 25 | if (mFd > 0) { 26 | close(mFd); 27 | mFd = -1; 28 | } 29 | } 30 | 31 | bool CPlayer::setDataSource(const char* source, int32_t& videoWidth, int32_t& videoHeight) { 32 | if (mExtractor == nullptr) { 33 | mExtractor = AMediaExtractor_new(); 34 | if (mExtractor == nullptr) { 35 | Log::Write(Log::Level::Error, "AMediaExtractor_new error"); 36 | return false; 37 | } 38 | } 39 | 40 | struct stat statbuff; 41 | int32_t fileLen = -1; 42 | if (stat(source, &statbuff) < 0) { 43 | Log::Write(Log::Level::Error, Fmt("setDataSource error, open file %s error", source)); 44 | return false; 45 | } else { 46 | fileLen = statbuff.st_size; 47 | } 48 | 49 | if (mFd) { 50 | close(mFd); 51 | mFd = -1; 52 | } 53 | mFd = open(source, O_RDONLY); 54 | if (mFd < 0) { 55 | Log::Write(Log::Level::Error, Fmt("setDataSource error, open file %s error, ret=%d", source, mFd)); 56 | return false; 57 | } 58 | 59 | media_status_t status = AMediaExtractor_setDataSourceFd(mExtractor, mFd, 0, fileLen); 60 | if (status != AMEDIA_OK) { 61 | Log::Write(Log::Level::Error, Fmt("setDataSource error, ret = %d", status)); 62 | return false; 63 | } 64 | 65 | size_t track = AMediaExtractor_getTrackCount(mExtractor); 66 | Log::Write(Log::Level::Error, Fmt("setDataSource success, file size %d track = %d", fileLen, track)); 67 | for (auto i = 0; i < track; i++) { 68 | const char *mime = nullptr; 69 | AMediaFormat *format = AMediaExtractor_getTrackFormat(mExtractor, i); 70 | AMediaFormat_getString(format, "mime", &mime); 71 | if (strstr(mime, "video")) { 72 | AMediaFormat_getInt32(format, "width", &videoWidth); 73 | AMediaFormat_getInt32(format, "height", &videoHeight); 74 | getAlignment(videoWidth, videoHeight, mAlignment); 75 | Log::Write(Log::Level::Error, Fmt("setDataSource video width:%d height:%d", videoWidth, videoHeight)); 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | bool CPlayer::start() { 82 | if (mExtractor == nullptr) { 83 | return false; 84 | } 85 | if (mStarted) { 86 | return true; 87 | } 88 | 89 | std::thread ([=](){ 90 | 91 | int32_t videoTrackIndex = -1; 92 | int32_t audioTrackIndex = -1; 93 | AMediaCodec *videoCodec = nullptr; 94 | AMediaCodec *audioCodec = nullptr; 95 | int32_t audioChannelCount = 0; 96 | int32_t audioSampleRate = 0; 97 | int32_t videoWidth = 0; 98 | int32_t videoHeight = 0; 99 | int64_t videoDurationUs = 0; 100 | 101 | int count = 0; 102 | std::shared_ptr audioStreamPlay; 103 | 104 | size_t track = AMediaExtractor_getTrackCount(mExtractor); 105 | for (auto i = 0; i < track; i++) { 106 | const char *mime = nullptr; 107 | AMediaFormat *format = AMediaExtractor_getTrackFormat(mExtractor, i); 108 | Log::Write(Log::Level::Error, Fmt("track %d format %s", i, AMediaFormat_toString(format))); 109 | AMediaFormat_getString(format, "mime", &mime); 110 | if (strstr(mime, "video")) { 111 | videoTrackIndex = i; 112 | AMediaFormat_getInt32(format, "width", &videoWidth); 113 | AMediaFormat_getInt32(format, "height", &videoHeight); 114 | AMediaFormat_getInt64(format, "durationUs", &videoDurationUs); 115 | getAlignment(videoWidth, videoHeight, mAlignment); 116 | videoCodec = AMediaCodec_createDecoderByType(mime); 117 | if (videoCodec == nullptr) { 118 | Log::Write(Log::Level::Error, Fmt("create mediacodec %s error", mime)); 119 | } 120 | this->mVideoCodec = videoCodec; 121 | media_status_t status = AMediaCodec_configure(videoCodec, format, nullptr, nullptr, 0); 122 | if (status != AMEDIA_OK) { 123 | Log::Write(Log::Level::Error, Fmt("AMediaCodec_configure error, status = %d", status)); 124 | } else { 125 | Log::Write(Log::Level::Info, Fmt("video AMediaCodec_configure successfuly")); 126 | } 127 | } else if (strstr(mime, "audio")) { 128 | audioTrackIndex = i; 129 | AMediaFormat_getInt32(format, "channel-count", &audioChannelCount); 130 | AMediaFormat_getInt32(format, "sample-rate", &audioSampleRate); 131 | audioCodec = AMediaCodec_createDecoderByType(mime); 132 | if (audioCodec == nullptr) { 133 | Log::Write(Log::Level::Error, Fmt("create mediacodec %s error", mime)); 134 | } 135 | media_status_t status = AMediaCodec_configure(audioCodec, format, nullptr, nullptr, 0); 136 | if (status != AMEDIA_OK) { 137 | Log::Write(Log::Level::Error, Fmt("AMediaCodec_configure error, status = %d", status)); 138 | } else { 139 | Log::Write(Log::Level::Info, Fmt("audio AMediaCodec_configure successfuly")); 140 | } 141 | 142 | //init audio output 143 | oboe::AudioStreamBuilder playStreamBuilder; 144 | playStreamBuilder.setDirection(oboe::Direction::Output); 145 | playStreamBuilder.setPerformanceMode(oboe::PerformanceMode::None); 146 | playStreamBuilder.setSharingMode(oboe::SharingMode::Exclusive); 147 | playStreamBuilder.setFormat(oboe::AudioFormat::I16); 148 | playStreamBuilder.setChannelCount(oboe::ChannelCount(audioChannelCount)); 149 | playStreamBuilder.setSampleRate(audioSampleRate); 150 | 151 | oboe::Result ret = playStreamBuilder.openStream(audioStreamPlay); 152 | if (ret != oboe::Result::OK) { 153 | Log::Write(Log::Level::Error, Fmt("Failed to open playback stream. Error: %s", oboe::convertToText(ret))); 154 | return false; 155 | } 156 | int32_t bufferSizeFrames = audioStreamPlay->getFramesPerBurst() * 2; 157 | ret = audioStreamPlay->setBufferSizeInFrames(bufferSizeFrames); 158 | Log::Write(Log::Level::Error, Fmt("bufferSizeFrames: %d", bufferSizeFrames)); 159 | if (ret != oboe::Result::OK) { 160 | Log::Write(Log::Level::Error, Fmt("Failed to set playback stream buffer size to: %d. Error: %s", bufferSizeFrames, oboe::convertToText(ret))); 161 | return false; 162 | } 163 | ret = audioStreamPlay->start(); 164 | if (ret != oboe::Result::OK) { 165 | Log::Write(Log::Level::Error, Fmt("Failed to start playback stream. Error: %s", oboe::convertToText(ret))); 166 | return false; 167 | } 168 | } 169 | AMediaFormat_delete(format); 170 | } 171 | 172 | if (videoCodec) { 173 | media_status_t status = AMediaCodec_start(videoCodec); 174 | if (status != AMEDIA_OK) { 175 | Log::Write(Log::Level::Error, Fmt("AMediaCodec_start error, status = %d", status)); 176 | } else { 177 | Log::Write(Log::Level::Info, "video AMediaCodec_start successfully"); 178 | } 179 | status = AMediaExtractor_selectTrack(mExtractor, videoTrackIndex); 180 | if (status != AMEDIA_OK) { 181 | Log::Write(Log::Level::Error, Fmt("video AMediaExtractor_selectTrack error, status = %d", status)); 182 | return false; 183 | } 184 | } 185 | if (audioCodec) { 186 | media_status_t status = AMediaCodec_start(audioCodec); 187 | if (status != AMEDIA_OK) { 188 | Log::Write(Log::Level::Error, Fmt("AMediaCodec_start error, status = %d", status)); 189 | } else { 190 | Log::Write(Log::Level::Info, "audio AMediaCodec_start successfully"); 191 | } 192 | status = AMediaExtractor_selectTrack(mExtractor, audioTrackIndex); 193 | if (status != AMEDIA_OK) { 194 | Log::Write(Log::Level::Error, Fmt("audio AMediaExtractor_selectTrack error, status = %d", status)); 195 | return false; 196 | } 197 | } 198 | 199 | uint64_t pts_offset = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); 200 | 201 | while (true) { 202 | std::this_thread::sleep_for(std::chrono::milliseconds(5)); 203 | 204 | int32_t index = AMediaExtractor_getSampleTrackIndex(mExtractor); 205 | int64_t pts = AMediaExtractor_getSampleTime(mExtractor); 206 | pts += pts_offset; 207 | if (index < 0) { 208 | // Play from the beginning when reach end of the file 209 | Log::Write(Log::Level::Info, Fmt("the video file is end, index:%d", index)); 210 | AMediaExtractor_seekTo(mExtractor, 0, AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC); 211 | pts_offset += videoDurationUs; 212 | } else if (index == audioTrackIndex) { 213 | //audio 214 | ssize_t bufferIdx_a = AMediaCodec_dequeueInputBuffer(audioCodec, 1); 215 | if (bufferIdx_a >= 0) { 216 | size_t bufferSize = 0; 217 | uint8_t *buffer = AMediaCodec_getInputBuffer(audioCodec, bufferIdx_a, &bufferSize); 218 | ssize_t size = AMediaExtractor_readSampleData(mExtractor, buffer, bufferSize); 219 | if (size > 0) { 220 | AMediaCodec_queueInputBuffer(audioCodec, bufferIdx_a, 0, size, pts, 0); 221 | } 222 | AMediaExtractor_advance(mExtractor); 223 | } else { 224 | Log::Write(Log::Level::Info, Fmt("audio AMediaCodec_dequeueInputBuffer bufferIdx_a:%d", bufferIdx_a)); 225 | } 226 | } else if (index == videoTrackIndex) { 227 | //video 228 | ssize_t bufferIdx = AMediaCodec_dequeueInputBuffer(videoCodec, 1); 229 | if (bufferIdx >= 0) { 230 | size_t bufferSize = 0; 231 | uint8_t *buffer = AMediaCodec_getInputBuffer(videoCodec, bufferIdx, &bufferSize); 232 | ssize_t size = AMediaExtractor_readSampleData(mExtractor, buffer, bufferSize); 233 | AMediaCodec_queueInputBuffer(videoCodec, bufferIdx, 0, size, pts, 0); 234 | AMediaExtractor_advance(mExtractor); 235 | } else { 236 | Log::Write(Log::Level::Info, Fmt("video AMediaCodec_dequeueInputBuffer bufferIdx:%d", bufferIdx)); 237 | } 238 | } 239 | 240 | //audio output buffer 241 | if (audioCodec) { 242 | AMediaCodecBufferInfo outputBufferInfo_a; 243 | ssize_t bufferIdx_a = AMediaCodec_dequeueOutputBuffer(audioCodec, &outputBufferInfo_a, 1); 244 | if (bufferIdx_a >= 0) { 245 | uint8_t *outputBuffer = AMediaCodec_getOutputBuffer(audioCodec, bufferIdx_a, nullptr); 246 | size_t outputDataSize = outputBufferInfo_a.size; 247 | const uint32_t numSamples = outputDataSize / (audioChannelCount * sizeof(int16_t)); 248 | const int64_t timeout = int64_t(numSamples * 1.0 * oboe::kNanosPerMillisecond / audioSampleRate); 249 | oboe::ResultWithValue ret = audioStreamPlay->write(outputBuffer, numSamples, timeout); 250 | if (ret.value() == numSamples) { 251 | AMediaCodec_releaseOutputBuffer(audioCodec, bufferIdx_a, true); 252 | } else { 253 | Log::Write(Log::Level::Error, Fmt("audio write ret:%d", ret)); 254 | AMediaCodec_releaseOutputBuffer(audioCodec, bufferIdx_a, true); 255 | } 256 | } 257 | } 258 | 259 | //video output buffer 260 | if (videoCodec) { 261 | AMediaCodecBufferInfo outputBufferInfo; 262 | ssize_t bufferIdx = AMediaCodec_dequeueOutputBuffer(videoCodec, &outputBufferInfo, 1); 263 | if (bufferIdx >= 0) { 264 | if (outputBufferInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { 265 | Log::Write(Log::Level::Error, Fmt("video codec end")); 266 | } 267 | uint8_t *outputBuffer = AMediaCodec_getOutputBuffer(videoCodec, bufferIdx, nullptr); 268 | if (outputBuffer) { 269 | std::shared_ptr frame = std::make_shared(); 270 | frame->type = mediaTypeVideo; 271 | frame->width = videoWidth; 272 | frame->height = videoHeight; 273 | frame->pts = outputBufferInfo.presentationTimeUs / 1000; 274 | frame->number = 0; 275 | frame->data = outputBuffer + outputBufferInfo.offset; 276 | frame->size = outputBufferInfo.size; 277 | frame->bufferIndex = bufferIdx; 278 | 279 | mMediaListMutex.lock(); 280 | mMediaList.push_back(frame); 281 | //Log::Write(Log::Level::Error, Fmt("mMediaList size:%d", mMediaList.size())); 282 | mMediaListMutex.unlock(); 283 | } 284 | } 285 | } 286 | } 287 | Log::Write(Log::Level::Error, Fmt("exit thread......")); 288 | }).detach(); 289 | 290 | return true; 291 | } 292 | 293 | bool CPlayer::stop() { 294 | return true; 295 | } 296 | 297 | std::shared_ptr CPlayer::getFrame() { 298 | std::lock_guard guard(mMediaListMutex); 299 | if (mMediaList.size()) { 300 | return mMediaList.front(); 301 | } else { 302 | return nullptr; 303 | } 304 | } 305 | 306 | bool CPlayer::releaseFrame(std::shared_ptr &frame) { 307 | if (frame.get() == nullptr) { 308 | return true; 309 | } 310 | uint64_t now = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); //in millisecond 311 | if (now < frame->pts) { 312 | return false; 313 | } 314 | std::lock_guard guard(mMediaListMutex); 315 | if (mMediaList.size() <= 1) { 316 | return true; 317 | } 318 | auto &it = mMediaList.front(); 319 | if (it.get() && it == frame) { 320 | AMediaCodec_releaseOutputBuffer(this->mVideoCodec, it->bufferIndex, true); 321 | mMediaList.pop_front(); 322 | } 323 | return true; 324 | } 325 | 326 | void CPlayer::getAlignment(int32_t &width, int32_t &height, int32_t alignment) { 327 | width = (width + alignment - 1) / alignment * alignment; 328 | height = (height + alignment - 1) / alignment * alignment; 329 | } 330 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/player.h: -------------------------------------------------------------------------------- 1 | // Copyright (2021-2023) Bytedance Ltd. and/or its affiliates, All rights reserved. 2 | // 3 | // This file provides an example of 3D decoding and play. 4 | // 5 | // Created by shunxiang at 2022/09/22 6 | 7 | #pragma once 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "oboe/Oboe.h" 15 | 16 | typedef enum { 17 | mediaTypeVideo = 0, 18 | mediaTypeAudio 19 | }mediaType; 20 | 21 | typedef struct MediaFrame_tag { 22 | MediaFrame_tag() : type(mediaTypeVideo), pts(0), number(0), data(nullptr), size(0) {}; 23 | mediaType type; 24 | uint64_t pts; 25 | int32_t width; 26 | int32_t height; 27 | uint32_t number; 28 | uint8_t* data; 29 | uint32_t size; 30 | ssize_t bufferIndex; 31 | }MediaFrame; 32 | 33 | class CPlayer { 34 | 35 | public: 36 | CPlayer(); 37 | 38 | ~CPlayer(); 39 | 40 | bool setDataSource(const char* source, int32_t& videoWidth, int32_t& videoHeight); 41 | 42 | bool start(); 43 | 44 | bool stop(); 45 | 46 | std::shared_ptr getFrame(); 47 | 48 | bool releaseFrame(std::shared_ptr &frame); 49 | 50 | private: 51 | void getAlignment(int32_t &width, int32_t &height, int32_t alignment); 52 | 53 | public: 54 | AMediaExtractor* mExtractor; 55 | AMediaCodec* mVideoCodec; 56 | int32_t mFd; 57 | bool mStarted; 58 | uint32_t mAlignment = 16; //16-byte alignment 59 | 60 | std::mutex mMediaListMutex; 61 | std::list> mMediaList; 62 | 63 | }; -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/vulkan_shaders/frag.spv: -------------------------------------------------------------------------------- 1 | // 1111.13.0 2 | 0x07230203,0x00010000,0x0008000b,0x0000006c,0x00000000,0x00020011,0x00000001,0x0006000b, 3 | 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, 4 | 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x0000003e,0x00000064,0x00030010, 5 | 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, 6 | 0x00000000,0x00080005,0x0000000b,0x42475273,0x694c6f54,0x7261656e,0x28424752,0x3b346676, 7 | 0x00000000,0x00040005,0x0000000a,0x62677273,0x00000061,0x00040005,0x0000000f,0x62677273, 8 | 0x00000000,0x00040005,0x00000012,0x65776f6c,0x00000072,0x00040005,0x00000017,0x65707075, 9 | 0x00000072,0x00030005,0x00000036,0x00767579,0x00050005,0x0000003a,0x53786574,0x6c706d61, 10 | 0x00797265,0x00060005,0x0000003e,0x67617266,0x43786554,0x64726f6f,0x00000000,0x00050005, 11 | 0x00000044,0x53786574,0x6c706d61,0x00757265,0x00050005,0x0000004d,0x53786574,0x6c706d61, 12 | 0x00767265,0x00030005,0x00000055,0x00626772,0x00050005,0x00000064,0x4374756f,0x726f6c6f, 13 | 0x00000000,0x00040005,0x0000006a,0x61726170,0x0000006d,0x00040047,0x0000003a,0x00000022, 14 | 0x00000000,0x00040047,0x0000003a,0x00000021,0x00000001,0x00040047,0x0000003e,0x0000001e, 15 | 0x00000000,0x00040047,0x00000044,0x00000022,0x00000000,0x00040047,0x00000044,0x00000021, 16 | 0x00000002,0x00040047,0x0000004d,0x00000022,0x00000000,0x00040047,0x0000004d,0x00000021, 17 | 0x00000003,0x00040047,0x00000064,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021, 18 | 0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006, 19 | 0x00000004,0x00040020,0x00000008,0x00000007,0x00000007,0x00040021,0x00000009,0x00000007, 20 | 0x00000008,0x00040017,0x0000000d,0x00000006,0x00000003,0x00040020,0x0000000e,0x00000007, 21 | 0x0000000d,0x0004002b,0x00000006,0x00000014,0x3d9e8391,0x0006002c,0x0000000d,0x00000015, 22 | 0x00000014,0x00000014,0x00000014,0x0004002b,0x00000006,0x00000019,0x3d6147ae,0x0006002c, 23 | 0x0000000d,0x0000001a,0x00000019,0x00000019,0x00000019,0x0004002b,0x00000006,0x0000001c, 24 | 0x3f72a76e,0x0006002c,0x0000000d,0x0000001d,0x0000001c,0x0000001c,0x0000001c,0x0004002b, 25 | 0x00000006,0x0000001f,0x4019999a,0x0006002c,0x0000000d,0x00000020,0x0000001f,0x0000001f, 26 | 0x0000001f,0x0004002b,0x00000006,0x00000025,0x3d25aee6,0x0006002c,0x0000000d,0x00000026, 27 | 0x00000025,0x00000025,0x00000025,0x00020014,0x00000027,0x00040017,0x00000028,0x00000027, 28 | 0x00000003,0x00040015,0x0000002b,0x00000020,0x00000000,0x0004002b,0x0000002b,0x0000002c, 29 | 0x00000003,0x00040020,0x0000002d,0x00000007,0x00000006,0x00090019,0x00000037,0x00000006, 30 | 0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b,0x00000038, 31 | 0x00000037,0x00040020,0x00000039,0x00000000,0x00000038,0x0004003b,0x00000039,0x0000003a, 32 | 0x00000000,0x00040017,0x0000003c,0x00000006,0x00000002,0x00040020,0x0000003d,0x00000001, 33 | 0x0000003c,0x0004003b,0x0000003d,0x0000003e,0x00000001,0x0004002b,0x0000002b,0x00000041, 34 | 0x00000000,0x0004003b,0x00000039,0x00000044,0x00000000,0x0004002b,0x00000006,0x00000049, 35 | 0x3f000000,0x0004002b,0x0000002b,0x0000004b,0x00000001,0x0004003b,0x00000039,0x0000004d, 36 | 0x00000000,0x0004002b,0x0000002b,0x00000053,0x00000002,0x00040018,0x00000056,0x0000000d, 37 | 0x00000003,0x0004002b,0x00000006,0x00000057,0x3f800000,0x0006002c,0x0000000d,0x00000058, 38 | 0x00000057,0x00000057,0x00000057,0x0004002b,0x00000006,0x00000059,0x00000000,0x0004002b, 39 | 0x00000006,0x0000005a,0xbe5bf9c6,0x0004002b,0x00000006,0x0000005b,0x400830d3,0x0006002c, 40 | 0x0000000d,0x0000005c,0x00000059,0x0000005a,0x0000005b,0x0004002b,0x00000006,0x0000005d, 41 | 0x3fa3e1da,0x0004002b,0x00000006,0x0000005e,0xbec2dcb1,0x0006002c,0x0000000d,0x0000005f, 42 | 0x0000005d,0x0000005e,0x00000059,0x0006002c,0x00000056,0x00000060,0x00000058,0x0000005c, 43 | 0x0000005f,0x00040020,0x00000063,0x00000003,0x00000007,0x0004003b,0x00000063,0x00000064, 44 | 0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005, 45 | 0x0004003b,0x0000000e,0x00000036,0x00000007,0x0004003b,0x0000000e,0x00000055,0x00000007, 46 | 0x0004003b,0x00000008,0x0000006a,0x00000007,0x0004003d,0x00000038,0x0000003b,0x0000003a, 47 | 0x0004003d,0x0000003c,0x0000003f,0x0000003e,0x00050057,0x00000007,0x00000040,0x0000003b, 48 | 0x0000003f,0x00050051,0x00000006,0x00000042,0x00000040,0x00000000,0x00050041,0x0000002d, 49 | 0x00000043,0x00000036,0x00000041,0x0003003e,0x00000043,0x00000042,0x0004003d,0x00000038, 50 | 0x00000045,0x00000044,0x0004003d,0x0000003c,0x00000046,0x0000003e,0x00050057,0x00000007, 51 | 0x00000047,0x00000045,0x00000046,0x00050051,0x00000006,0x00000048,0x00000047,0x00000000, 52 | 0x00050083,0x00000006,0x0000004a,0x00000048,0x00000049,0x00050041,0x0000002d,0x0000004c, 53 | 0x00000036,0x0000004b,0x0003003e,0x0000004c,0x0000004a,0x0004003d,0x00000038,0x0000004e, 54 | 0x0000004d,0x0004003d,0x0000003c,0x0000004f,0x0000003e,0x00050057,0x00000007,0x00000050, 55 | 0x0000004e,0x0000004f,0x00050051,0x00000006,0x00000051,0x00000050,0x00000000,0x00050083, 56 | 0x00000006,0x00000052,0x00000051,0x00000049,0x00050041,0x0000002d,0x00000054,0x00000036, 57 | 0x00000053,0x0003003e,0x00000054,0x00000052,0x0004003d,0x0000000d,0x00000061,0x00000036, 58 | 0x00050091,0x0000000d,0x00000062,0x00000060,0x00000061,0x0003003e,0x00000055,0x00000062, 59 | 0x0004003d,0x0000000d,0x00000065,0x00000055,0x00050051,0x00000006,0x00000066,0x00000065, 60 | 0x00000000,0x00050051,0x00000006,0x00000067,0x00000065,0x00000001,0x00050051,0x00000006, 61 | 0x00000068,0x00000065,0x00000002,0x00070050,0x00000007,0x00000069,0x00000066,0x00000067, 62 | 0x00000068,0x00000057,0x0003003e,0x0000006a,0x00000069,0x00050039,0x00000007,0x0000006b, 63 | 0x0000000b,0x0000006a,0x0003003e,0x00000064,0x0000006b,0x000100fd,0x00010038,0x00050036, 64 | 0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,0x000200f8, 65 | 0x0000000c,0x0004003b,0x0000000e,0x0000000f,0x00000007,0x0004003b,0x0000000e,0x00000012, 66 | 0x00000007,0x0004003b,0x0000000e,0x00000017,0x00000007,0x0004003d,0x00000007,0x00000010, 67 | 0x0000000a,0x0008004f,0x0000000d,0x00000011,0x00000010,0x00000010,0x00000000,0x00000001, 68 | 0x00000002,0x0003003e,0x0000000f,0x00000011,0x0004003d,0x0000000d,0x00000013,0x0000000f, 69 | 0x00050085,0x0000000d,0x00000016,0x00000013,0x00000015,0x0003003e,0x00000012,0x00000016, 70 | 0x0004003d,0x0000000d,0x00000018,0x0000000f,0x00050081,0x0000000d,0x0000001b,0x00000018, 71 | 0x0000001a,0x00050085,0x0000000d,0x0000001e,0x0000001b,0x0000001d,0x0007000c,0x0000000d, 72 | 0x00000021,0x00000001,0x0000001a,0x0000001e,0x00000020,0x0003003e,0x00000017,0x00000021, 73 | 0x0004003d,0x0000000d,0x00000022,0x00000017,0x0004003d,0x0000000d,0x00000023,0x00000012, 74 | 0x0004003d,0x0000000d,0x00000024,0x0000000f,0x000500b8,0x00000028,0x00000029,0x00000024, 75 | 0x00000026,0x000600a9,0x0000000d,0x0000002a,0x00000029,0x00000023,0x00000022,0x00050041, 76 | 0x0000002d,0x0000002e,0x0000000a,0x0000002c,0x0004003d,0x00000006,0x0000002f,0x0000002e, 77 | 0x00050051,0x00000006,0x00000030,0x0000002a,0x00000000,0x00050051,0x00000006,0x00000031, 78 | 0x0000002a,0x00000001,0x00050051,0x00000006,0x00000032,0x0000002a,0x00000002,0x00070050, 79 | 0x00000007,0x00000033,0x00000030,0x00000031,0x00000032,0x0000002f,0x000200fe,0x00000033, 80 | 0x00010038 81 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/vulkan_shaders/generate spv command.txt: -------------------------------------------------------------------------------- 1 | generate frag.spv: 2 | C:\VulkanSDK\1.3.236.0\Bin\glslangValidator.exe -V -x shader.frag 3 | 4 | generate vert.spv: 5 | C:\VulkanSDK\1.3.236.0\Bin\glslangValidator.exe -V -x shader.vert 6 | 7 | note: 8 | After generating the spv file, you need to add '{' and '}' symbols at the front and end of the data respectively. 9 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/vulkan_shaders/shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | precision highp float; 4 | 5 | layout(binding = 1) uniform sampler2D texSamplery; 6 | layout(binding = 2) uniform sampler2D texSampleru; 7 | layout(binding = 3) uniform sampler2D texSamplerv; 8 | 9 | layout(location = 0) in vec2 fragTexCoord; 10 | layout(location = 0) out vec4 outColor; 11 | 12 | const vec3 delta3 = vec3(1.0 / 12.92); 13 | const vec3 alpha3 = vec3(1.0 / 1.055); 14 | const vec3 theta3 = vec3(0.04045); 15 | const vec3 offset3 = vec3(0.055); 16 | const vec3 gamma3 = vec3(2.4); 17 | // conversion based on: https://www.khronos.org/registry/DataFormat/specs/1.3/dataformat.1.3.html#TRANSFER_SRGB 18 | vec4 sRGBToLinearRGB(vec4 srgba) 19 | { 20 | const vec3 srgb = srgba.rgb; 21 | const vec3 lower = srgb * delta3; 22 | const vec3 upper = pow((srgb + offset3) * alpha3, gamma3); 23 | return vec4(mix(upper, lower, lessThan(srgb, theta3)), srgba.a); 24 | } 25 | 26 | void main() { 27 | vec3 yuv; 28 | vec3 rgb; 29 | yuv.r = texture(texSamplery, fragTexCoord).r; 30 | yuv.g = texture(texSampleru, fragTexCoord).r - 0.5; 31 | yuv.b = texture(texSamplerv, fragTexCoord).r - 0.5; 32 | rgb = mat3 (1.0, 1.0, 1.0, 33 | 0.0, -0.21482, 2.12798, 34 | 1.28033, -0.38059, 0.0) * yuv; 35 | 36 | outColor = sRGBToLinearRGB(vec4(rgb, 1)); 37 | } 38 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/vulkan_shaders/shader.vert: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | layout (binding = 0) uniform UniformBufferObject { 4 | mat4 mvp; 5 | } ubo; 6 | 7 | layout(location = 0) in vec3 inPosition; 8 | layout(location = 1) in vec2 inTexCoord; 9 | 10 | layout(location = 0) out vec2 fragTexCoord; 11 | 12 | void main() { 13 | gl_Position = ubo.mvp * vec4(inPosition, 1.0); 14 | fragTexCoord = inTexCoord; 15 | } 16 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/app/vulkan_shaders/vert.spv: -------------------------------------------------------------------------------- 1 | // 1111.13.0 2 | 0x07230203,0x00010000,0x0008000b,0x00000029,0x00000000,0x00020011,0x00000001,0x0006000b, 3 | 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, 4 | 0x0009000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000d,0x00000019,0x00000025, 5 | 0x00000027,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000, 6 | 0x00060005,0x0000000b,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x0000000b, 7 | 0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,0x0000000b,0x00000001,0x505f6c67, 8 | 0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000000b,0x00000002,0x435f6c67,0x4470696c, 9 | 0x61747369,0x0065636e,0x00070006,0x0000000b,0x00000003,0x435f6c67,0x446c6c75,0x61747369, 10 | 0x0065636e,0x00030005,0x0000000d,0x00000000,0x00070005,0x00000011,0x66696e55,0x426d726f, 11 | 0x65666675,0x6a624f72,0x00746365,0x00040006,0x00000011,0x00000000,0x0070766d,0x00030005, 12 | 0x00000013,0x006f6275,0x00050005,0x00000019,0x6f506e69,0x69746973,0x00006e6f,0x00060005, 13 | 0x00000025,0x67617266,0x43786554,0x64726f6f,0x00000000,0x00050005,0x00000027,0x65546e69, 14 | 0x6f6f4378,0x00006472,0x00050048,0x0000000b,0x00000000,0x0000000b,0x00000000,0x00050048, 15 | 0x0000000b,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000000b,0x00000002,0x0000000b, 16 | 0x00000003,0x00050048,0x0000000b,0x00000003,0x0000000b,0x00000004,0x00030047,0x0000000b, 17 | 0x00000002,0x00040048,0x00000011,0x00000000,0x00000005,0x00050048,0x00000011,0x00000000, 18 | 0x00000023,0x00000000,0x00050048,0x00000011,0x00000000,0x00000007,0x00000010,0x00030047, 19 | 0x00000011,0x00000002,0x00040047,0x00000013,0x00000022,0x00000000,0x00040047,0x00000013, 20 | 0x00000021,0x00000000,0x00040047,0x00000019,0x0000001e,0x00000000,0x00040047,0x00000025, 21 | 0x0000001e,0x00000000,0x00040047,0x00000027,0x0000001e,0x00000001,0x00020013,0x00000002, 22 | 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, 23 | 0x00000006,0x00000004,0x00040015,0x00000008,0x00000020,0x00000000,0x0004002b,0x00000008, 24 | 0x00000009,0x00000001,0x0004001c,0x0000000a,0x00000006,0x00000009,0x0006001e,0x0000000b, 25 | 0x00000007,0x00000006,0x0000000a,0x0000000a,0x00040020,0x0000000c,0x00000003,0x0000000b, 26 | 0x0004003b,0x0000000c,0x0000000d,0x00000003,0x00040015,0x0000000e,0x00000020,0x00000001, 27 | 0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040018,0x00000010,0x00000007,0x00000004, 28 | 0x0003001e,0x00000011,0x00000010,0x00040020,0x00000012,0x00000002,0x00000011,0x0004003b, 29 | 0x00000012,0x00000013,0x00000002,0x00040020,0x00000014,0x00000002,0x00000010,0x00040017, 30 | 0x00000017,0x00000006,0x00000003,0x00040020,0x00000018,0x00000001,0x00000017,0x0004003b, 31 | 0x00000018,0x00000019,0x00000001,0x0004002b,0x00000006,0x0000001b,0x3f800000,0x00040020, 32 | 0x00000021,0x00000003,0x00000007,0x00040017,0x00000023,0x00000006,0x00000002,0x00040020, 33 | 0x00000024,0x00000003,0x00000023,0x0004003b,0x00000024,0x00000025,0x00000003,0x00040020, 34 | 0x00000026,0x00000001,0x00000023,0x0004003b,0x00000026,0x00000027,0x00000001,0x00050036, 35 | 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,0x00000014, 36 | 0x00000015,0x00000013,0x0000000f,0x0004003d,0x00000010,0x00000016,0x00000015,0x0004003d, 37 | 0x00000017,0x0000001a,0x00000019,0x00050051,0x00000006,0x0000001c,0x0000001a,0x00000000, 38 | 0x00050051,0x00000006,0x0000001d,0x0000001a,0x00000001,0x00050051,0x00000006,0x0000001e, 39 | 0x0000001a,0x00000002,0x00070050,0x00000007,0x0000001f,0x0000001c,0x0000001d,0x0000001e, 40 | 0x0000001b,0x00050091,0x00000007,0x00000020,0x00000016,0x0000001f,0x00050041,0x00000021, 41 | 0x00000022,0x0000000d,0x0000000f,0x0003003e,0x00000022,0x00000020,0x0004003d,0x00000023, 42 | 0x00000028,0x00000027,0x0003003e,0x00000025,0x00000028,0x000100fd,0x00010038 43 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/build.gradle: -------------------------------------------------------------------------------- 1 | def OBOE_SDK_ROOT = file("${buildDir}/Oboe") 2 | 3 | buildscript { 4 | repositories { 5 | maven{ allowInsecureProtocol = true 6 | url'http://maven.aliyun.com/nexus/content/groups/public/'} 7 | google() 8 | jcenter() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:7.2.2' 13 | } 14 | } 15 | 16 | allprojects { 17 | repositories { 18 | maven{ allowInsecureProtocol = true 19 | url'http://maven.aliyun.com/nexus/content/groups/public/'} 20 | google() 21 | jcenter() 22 | } 23 | } 24 | 25 | apply plugin: 'com.android.application' 26 | 27 | android { 28 | compileSdkVersion 29 29 | 30 | defaultConfig { 31 | applicationId "com.khronos.player" 32 | minSdkVersion 26 33 | targetSdkVersion 26 34 | versionCode 201 35 | versionName "2.0.1" 36 | 37 | 38 | shaders { 39 | glslcArgs.addAll(['-c', '-g']) 40 | } 41 | externalNativeBuild { 42 | cmake { 43 | abiFilters "arm64-v8a" 44 | arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static' 45 | } 46 | } 47 | 48 | externalNativeBuild { 49 | cmake { 50 | arguments "-DANDROID_STL=c++_shared" 51 | } 52 | } 53 | 54 | } 55 | 56 | buildTypes { 57 | release { 58 | minifyEnabled false 59 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 60 | } 61 | } 62 | 63 | sourceSets { 64 | main { 65 | java.srcDirs = ['app/java'] 66 | jni.srcDirs = ['app'] 67 | jniLibs.srcDirs = ['openxr_loader'] 68 | manifest.srcFile 'app/AndroidManifest.xml' 69 | } 70 | } 71 | 72 | externalNativeBuild { 73 | cmake { 74 | path "CMakeLists.txt" 75 | version "3.10.2" 76 | } 77 | } 78 | 79 | } 80 | 81 | dependencies { 82 | implementation fileTree(dir: 'openxr_loader', include: ['*.jar','*.aar']) 83 | } 84 | 85 | // Extract the Oboe SDK 86 | task extractOboeSDK(type: Copy) { 87 | def sourceFile = file("${projectDir}/libs/oboe-1.6.0.aar") 88 | from zipTree(sourceFile) 89 | into OBOE_SDK_ROOT 90 | } 91 | 92 | preBuild.dependsOn(extractOboeSDK) -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | 21 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Apr 08 16:50:05 CST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip 7 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/libs/oboe-1.6.0.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/libs/oboe-1.6.0.aar -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/arm64-v8a/liboboe.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/openxr_loader/arm64-v8a/liboboe.so -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/arm64-v8a/libopenxr_loader.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/openxr_loader/arm64-v8a/libopenxr_loader.so -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/armeabi-v7a/liboboe.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/openxr_loader/armeabi-v7a/liboboe.so -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/armeabi-v7a/libopenxr_loader.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/picoxr/OpenXR_VideoPlayer_Demo/8831f7a5e1dc76c2765d784bc21ccef27c7980a6/OpenXR/Sample/VideoPlayer/openxr_loader/armeabi-v7a/libopenxr_loader.so -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/extra_algorithms.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // Copyright (c) 2017-2019 Valve Corporation 3 | // Copyright (c) 2017-2019 LunarG, Inc. 4 | // Copyright (c) 2019 Collabora, Ltd. 5 | // 6 | // SPDX-License-Identifier: Apache-2.0 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | // Author: Ryan Pavlik 21 | // 22 | 23 | /*! 24 | * @file 25 | * 26 | * Additional functions along the lines of the standard library algorithms. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | #include 33 | 34 | /// Like std::remove_if, except it works on associative containers and it actually removes this. 35 | /// 36 | /// The iterator stuff in here is subtle - .erase() invalidates only that iterator, but it returns a non-invalidated iterator to the 37 | /// next valid element which we can use instead of incrementing. 38 | template 39 | static inline void map_erase_if(T &container, Pred &&predicate) { 40 | for (auto it = container.begin(); it != container.end();) { 41 | if (predicate(*it)) { 42 | it = container.erase(it); 43 | } else { 44 | ++it; 45 | } 46 | } 47 | } 48 | 49 | /*! 50 | * Moves all elements matching the predicate to the end of the vector then erases them. 51 | * 52 | * Combines the two parts of the erase-remove idiom to simplify things and avoid accidentally using the wrong erase overload. 53 | */ 54 | template 55 | static inline void vector_remove_if_and_erase(std::vector &vec, Pred &&predicate) { 56 | auto b = vec.begin(); 57 | auto e = vec.end(); 58 | vec.erase(std::remove_if(b, e, std::forward(predicate)), e); 59 | } 60 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/filesystem_utils.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Khronos Group Inc. 2 | // Copyright (c) 2017 Valve Corporation 3 | // Copyright (c) 2017 LunarG, Inc. 4 | // 5 | // SPDX-License-Identifier: Apache-2.0 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | // Authors: Mark Young 20 | // Nat Brown 21 | // 22 | 23 | #include "filesystem_utils.hpp" 24 | 25 | #include "platform_utils.hpp" 26 | 27 | #include 28 | 29 | #if defined DISABLE_STD_FILESYSTEM 30 | #define USE_EXPERIMENTAL_FS 0 31 | #define USE_FINAL_FS 0 32 | 33 | #else 34 | // If the C++ macro is set to the version containing C++17, it must support 35 | // the final C++17 package 36 | #if __cplusplus >= 201703L 37 | #define USE_EXPERIMENTAL_FS 0 38 | #define USE_FINAL_FS 1 39 | 40 | #elif defined(_MSC_VER) && _MSC_VER >= 1900 41 | 42 | #if defined(_HAS_CXX17) && _HAS_CXX17 43 | // When MSC supports c++17 use package. 44 | #define USE_EXPERIMENTAL_FS 0 45 | #define USE_FINAL_FS 1 46 | #endif // !_HAS_CXX17 47 | 48 | // Right now, GCC still only supports the experimental filesystem items starting in GCC 6 49 | #elif (__GNUC__ >= 6) 50 | #define USE_EXPERIMENTAL_FS 1 51 | #define USE_FINAL_FS 0 52 | 53 | // If Clang, check for feature support 54 | #elif defined(__clang__) && (__cpp_lib_filesystem || __cpp_lib_experimental_filesystem) 55 | #if __cpp_lib_filesystem 56 | #define USE_EXPERIMENTAL_FS 0 57 | #define USE_FINAL_FS 1 58 | #else 59 | #define USE_EXPERIMENTAL_FS 1 60 | #define USE_FINAL_FS 0 61 | #endif 62 | 63 | // If all above fails, fall back to standard C++ and OS-specific items 64 | #else 65 | #define USE_EXPERIMENTAL_FS 0 66 | #define USE_FINAL_FS 0 67 | #endif 68 | #endif 69 | 70 | #if USE_FINAL_FS == 1 71 | #include 72 | #define FS_PREFIX std::filesystem 73 | #elif USE_EXPERIMENTAL_FS == 1 74 | #include 75 | #define FS_PREFIX std::experimental::filesystem 76 | #elif defined(XR_USE_PLATFORM_WIN32) 77 | // Windows fallback includes 78 | #include 79 | #include 80 | #else 81 | // Linux/Apple fallback includes 82 | #include 83 | #include 84 | #include 85 | #include 86 | #include 87 | #endif 88 | 89 | #if defined(XR_USE_PLATFORM_WIN32) 90 | #define PATH_SEPARATOR ';' 91 | #define DIRECTORY_SYMBOL '\\' 92 | #define ALTERNATE_DIRECTORY_SYMBOL '/' 93 | #else 94 | #define PATH_SEPARATOR ':' 95 | #define DIRECTORY_SYMBOL '/' 96 | #endif 97 | 98 | #if (USE_FINAL_FS == 1) || (USE_EXPERIMENTAL_FS == 1) 99 | // We can use one of the C++ filesystem packages 100 | 101 | bool FileSysUtilsIsRegularFile(const std::string& path) { return FS_PREFIX::is_regular_file(path); } 102 | 103 | bool FileSysUtilsIsDirectory(const std::string& path) { return FS_PREFIX::is_directory(path); } 104 | 105 | bool FileSysUtilsPathExists(const std::string& path) { return FS_PREFIX::exists(path); } 106 | 107 | bool FileSysUtilsIsAbsolutePath(const std::string& path) { 108 | FS_PREFIX::path file_path(path); 109 | return file_path.is_absolute(); 110 | } 111 | 112 | bool FileSysUtilsGetCurrentPath(std::string& path) { 113 | FS_PREFIX::path cur_path = FS_PREFIX::current_path(); 114 | path = cur_path.string(); 115 | return true; 116 | } 117 | 118 | bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) { 119 | FS_PREFIX::path path_var(file_path); 120 | parent_path = path_var.parent_path().string(); 121 | return true; 122 | } 123 | 124 | bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) { 125 | absolute = FS_PREFIX::absolute(path).string(); 126 | return true; 127 | } 128 | 129 | bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) { 130 | FS_PREFIX::path parent_path(parent); 131 | FS_PREFIX::path child_path(child); 132 | FS_PREFIX::path full_path = parent_path / child_path; 133 | combined = full_path.string(); 134 | return true; 135 | } 136 | 137 | bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) { 138 | std::string::size_type start = 0; 139 | std::string::size_type location = path_list.find(PATH_SEPARATOR); 140 | while (location != std::string::npos) { 141 | paths.push_back(path_list.substr(start, location)); 142 | start = location + 1; 143 | location = path_list.find(PATH_SEPARATOR, start); 144 | } 145 | paths.push_back(path_list.substr(start, location)); 146 | return true; 147 | } 148 | 149 | bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) { 150 | for (auto& dir_iter : FS_PREFIX::directory_iterator(path)) { 151 | files.push_back(dir_iter.path().filename().string()); 152 | } 153 | return true; 154 | } 155 | 156 | #elif defined(XR_OS_WINDOWS) 157 | 158 | // For pre C++17 compiler that doesn't support experimental filesystem 159 | 160 | bool FileSysUtilsIsRegularFile(const std::string& path) { 161 | const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str()); 162 | return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY); 163 | } 164 | 165 | bool FileSysUtilsIsDirectory(const std::string& path) { 166 | const DWORD attr = GetFileAttributesW(utf8_to_wide(path).c_str()); 167 | return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY); 168 | } 169 | 170 | bool FileSysUtilsPathExists(const std::string& path) { 171 | return (GetFileAttributesW(utf8_to_wide(path).c_str()) != INVALID_FILE_ATTRIBUTES); 172 | } 173 | 174 | bool FileSysUtilsIsAbsolutePath(const std::string& path) { 175 | bool pathStartsWithDir = (path.size() >= 1) && ((path[0] == DIRECTORY_SYMBOL) || (path[0] == ALTERNATE_DIRECTORY_SYMBOL)); 176 | 177 | bool pathStartsWithDrive = 178 | (path.size() >= 3) && (path[1] == ':' && (path[2] == DIRECTORY_SYMBOL || path[2] == ALTERNATE_DIRECTORY_SYMBOL)); 179 | 180 | return pathStartsWithDir || pathStartsWithDrive; 181 | } 182 | 183 | bool FileSysUtilsGetCurrentPath(std::string& path) { 184 | wchar_t tmp_path[MAX_PATH]; 185 | if (nullptr != _wgetcwd(tmp_path, MAX_PATH - 1)) { 186 | path = wide_to_utf8(tmp_path); 187 | return true; 188 | } 189 | return false; 190 | } 191 | 192 | bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) { 193 | std::string full_path; 194 | if (FileSysUtilsGetAbsolutePath(file_path, full_path)) { 195 | std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL); 196 | parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator); 197 | return true; 198 | } 199 | return false; 200 | } 201 | 202 | bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) { 203 | wchar_t tmp_path[MAX_PATH]; 204 | if (0 != GetFullPathNameW(utf8_to_wide(path).c_str(), MAX_PATH, tmp_path, NULL)) { 205 | absolute = wide_to_utf8(tmp_path); 206 | return true; 207 | } 208 | return false; 209 | } 210 | 211 | bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) { 212 | std::string::size_type parent_len = parent.length(); 213 | if (0 == parent_len || "." == parent || ".\\" == parent || "./" == parent) { 214 | combined = child; 215 | return true; 216 | } 217 | char last_char = parent[parent_len - 1]; 218 | if ((last_char == DIRECTORY_SYMBOL) || (last_char == ALTERNATE_DIRECTORY_SYMBOL)) { 219 | parent_len--; 220 | } 221 | combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child; 222 | return true; 223 | } 224 | 225 | bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) { 226 | std::string::size_type start = 0; 227 | std::string::size_type location = path_list.find(PATH_SEPARATOR); 228 | while (location != std::string::npos) { 229 | paths.push_back(path_list.substr(start, location)); 230 | start = location + 1; 231 | location = path_list.find(PATH_SEPARATOR, start); 232 | } 233 | paths.push_back(path_list.substr(start, location)); 234 | return true; 235 | } 236 | 237 | bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) { 238 | std::string searchPath; 239 | FileSysUtilsCombinePaths(path, "*", searchPath); 240 | 241 | WIN32_FIND_DATAW file_data; 242 | HANDLE file_handle = FindFirstFileW(utf8_to_wide(searchPath).c_str(), &file_data); 243 | if (file_handle != INVALID_HANDLE_VALUE) { 244 | do { 245 | if (!(file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 246 | files.push_back(wide_to_utf8(file_data.cFileName)); 247 | } 248 | } while (FindNextFileW(file_handle, &file_data)); 249 | return true; 250 | } 251 | return false; 252 | } 253 | 254 | #else // XR_OS_LINUX/XR_OS_APPLE fallback 255 | 256 | // simple POSIX-compatible implementation of the pieces used by OpenXR 257 | 258 | bool FileSysUtilsIsRegularFile(const std::string& path) { 259 | struct stat path_stat; 260 | stat(path.c_str(), &path_stat); 261 | return S_ISREG(path_stat.st_mode); 262 | } 263 | 264 | bool FileSysUtilsIsDirectory(const std::string& path) { 265 | struct stat path_stat; 266 | stat(path.c_str(), &path_stat); 267 | return S_ISDIR(path_stat.st_mode); 268 | } 269 | 270 | bool FileSysUtilsPathExists(const std::string& path) { return (access(path.c_str(), F_OK) != -1); } 271 | 272 | bool FileSysUtilsIsAbsolutePath(const std::string& path) { return (path[0] == DIRECTORY_SYMBOL); } 273 | 274 | bool FileSysUtilsGetCurrentPath(std::string& path) { 275 | char tmp_path[PATH_MAX]; 276 | if (nullptr != getcwd(tmp_path, PATH_MAX - 1)) { 277 | path = tmp_path; 278 | return true; 279 | } 280 | return false; 281 | } 282 | 283 | bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path) { 284 | std::string full_path; 285 | if (FileSysUtilsGetAbsolutePath(file_path, full_path)) { 286 | std::string::size_type lastSeparator = full_path.find_last_of(DIRECTORY_SYMBOL); 287 | parent_path = (lastSeparator == 0) ? full_path : full_path.substr(0, lastSeparator); 288 | return true; 289 | } 290 | return false; 291 | } 292 | 293 | bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute) { 294 | char buf[PATH_MAX]; 295 | if (nullptr != realpath(path.c_str(), buf)) { 296 | absolute = buf; 297 | return true; 298 | } 299 | return false; 300 | } 301 | 302 | bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined) { 303 | std::string::size_type parent_len = parent.length(); 304 | if (0 == parent_len || "." == parent || "./" == parent) { 305 | combined = child; 306 | return true; 307 | } 308 | char last_char = parent[parent_len - 1]; 309 | if (last_char == DIRECTORY_SYMBOL) { 310 | parent_len--; 311 | } 312 | combined = parent.substr(0, parent_len) + DIRECTORY_SYMBOL + child; 313 | return true; 314 | } 315 | 316 | bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths) { 317 | std::string::size_type start = 0; 318 | std::string::size_type location = path_list.find(PATH_SEPARATOR); 319 | while (location != std::string::npos) { 320 | paths.push_back(path_list.substr(start, location)); 321 | start = location + 1; 322 | location = path_list.find(PATH_SEPARATOR, start); 323 | } 324 | paths.push_back(path_list.substr(start, location)); 325 | return true; 326 | } 327 | 328 | bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files) { 329 | DIR* dir = opendir(path.c_str()); 330 | if (dir == nullptr) { 331 | return false; 332 | } 333 | struct dirent* entry; 334 | while ((entry = readdir(dir)) != nullptr) { 335 | files.emplace_back(entry->d_name); 336 | } 337 | closedir(dir); 338 | return true; 339 | } 340 | 341 | #endif 342 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/filesystem_utils.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 The Khronos Group Inc. 2 | // Copyright (c) 2017 Valve Corporation 3 | // Copyright (c) 2017 LunarG, Inc. 4 | // 5 | // SPDX-License-Identifier: Apache-2.0 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | // Author: Mark Young 20 | // 21 | 22 | #pragma once 23 | 24 | #include 25 | #include 26 | 27 | // Determine if the path indicates a regular file (not a directory or symbolic link) 28 | bool FileSysUtilsIsRegularFile(const std::string& path); 29 | 30 | // Determine if the path indicates a directory 31 | bool FileSysUtilsIsDirectory(const std::string& path); 32 | 33 | // Determine if the provided path exists on the filesystem 34 | bool FileSysUtilsPathExists(const std::string& path); 35 | 36 | // Get the current directory 37 | bool FileSysUtilsGetCurrentPath(std::string& path); 38 | 39 | // Get the parent path of a file 40 | bool FileSysUtilsGetParentPath(const std::string& file_path, std::string& parent_path); 41 | 42 | // Determine if the provided path is an absolute path 43 | bool FileSysUtilsIsAbsolutePath(const std::string& path); 44 | 45 | // Get the absolute path for a provided file 46 | bool FileSysUtilsGetAbsolutePath(const std::string& path, std::string& absolute); 47 | 48 | // Combine a parent and child directory 49 | bool FileSysUtilsCombinePaths(const std::string& parent, const std::string& child, std::string& combined); 50 | 51 | // Parse out individual paths in a path list 52 | bool FileSysUtilsParsePathList(std::string& path_list, std::vector& paths); 53 | 54 | // Record all the filenames for files found in the provided path. 55 | bool FileSysUtilsFindFilesInPath(const std::string& path, std::vector& files); 56 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/hex_and_handles.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // Copyright (c) 2017-2019 Valve Corporation 3 | // Copyright (c) 2017-2019 LunarG, Inc. 4 | // Copyright (c) 2019 Collabora, Ltd. 5 | // 6 | // SPDX-License-Identifier: Apache-2.0 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | // Author: Ryan Pavlik 21 | // 22 | 23 | /*! 24 | * @file 25 | * 26 | * Some utilities, primarily for working with OpenXR handles in a generic way. 27 | */ 28 | 29 | #pragma once 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | inline std::string to_hex(const uint8_t* const data, size_t bytes) { 37 | std::string out(2 + bytes * 2, '?'); 38 | out[0] = '0'; 39 | out[1] = 'x'; 40 | static const char* hex = "0123456789abcdef"; 41 | auto ch = out.end(); 42 | for (size_t i = 0; i < bytes; ++i) { 43 | auto b = data[i]; 44 | *--ch = hex[(b >> 0) & 0xf]; 45 | *--ch = hex[(b >> 4) & 0xf]; 46 | } 47 | return out; 48 | } 49 | 50 | template 51 | inline std::string to_hex(const T& data) { 52 | return to_hex(reinterpret_cast(&data), sizeof(data)); 53 | } 54 | 55 | #if XR_PTR_SIZE == 8 56 | /// Convert a handle into a same-sized integer. 57 | template 58 | static inline uint64_t MakeHandleGeneric(T handle) { 59 | return reinterpret_cast(handle); 60 | } 61 | 62 | /// Treat an integer as a handle 63 | template 64 | static inline T& TreatIntegerAsHandle(uint64_t& handle) { 65 | return reinterpret_cast(handle); 66 | } 67 | 68 | /// @overload 69 | template 70 | static inline T const& TreatIntegerAsHandle(uint64_t const& handle) { 71 | return reinterpret_cast(handle); 72 | } 73 | 74 | /// Does a correctly-sized integer represent a null handle? 75 | static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == reinterpret_cast(handle); } 76 | 77 | #else 78 | 79 | /// Convert a handle into a same-sized integer: no-op on 32-bit systems 80 | static inline uint64_t MakeHandleGeneric(uint64_t handle) { return handle; } 81 | 82 | /// Treat an integer as a handle: no-op on 32-bit systems 83 | template 84 | static inline T& TreatIntegerAsHandle(uint64_t& handle) { 85 | return handle; 86 | } 87 | 88 | /// @overload 89 | template 90 | static inline T const& TreatIntegerAsHandle(uint64_t const& handle) { 91 | return handle; 92 | } 93 | 94 | /// Does a correctly-sized integer represent a null handle? 95 | static inline bool IsIntegerNullHandle(uint64_t handle) { return XR_NULL_HANDLE == handle; } 96 | 97 | #endif 98 | 99 | /// Turns a uint64_t into a string formatted as hex. 100 | /// 101 | /// The core of the HandleToHexString implementation is in here. 102 | inline std::string Uint64ToHexString(uint64_t val) { return to_hex(val); } 103 | 104 | /// Turns a uint32_t into a string formatted as hex. 105 | inline std::string Uint32ToHexString(uint32_t val) { return to_hex(val); } 106 | 107 | /// Turns an OpenXR handle into a string formatted as hex. 108 | template 109 | inline std::string HandleToHexString(T handle) { 110 | return to_hex(handle); 111 | } 112 | 113 | /// Turns a pointer-sized integer into a string formatted as hex. 114 | inline std::string UintptrToHexString(uintptr_t val) { return to_hex(val); } 115 | 116 | /// Convert a pointer to a string formatted as hex. 117 | template 118 | inline std::string PointerToHexString(T const* ptr) { 119 | return to_hex(ptr); 120 | } 121 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/loader_interfaces.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // Copyright (c) 2017 Valve Corporation 3 | // Copyright (c) 2017 LunarG, Inc. 4 | // 5 | // SPDX-License-Identifier: Apache-2.0 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | // Author: Mark Young 20 | // 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | // Forward declare. 31 | typedef struct XrApiLayerCreateInfo XrApiLayerCreateInfo; 32 | 33 | // Function pointer prototype for the xrCreateApiLayerInstance function used in place of xrCreateInstance. 34 | // This function allows us to pass special API layer information to each layer during the process of creating an Instance. 35 | typedef XrResult(XRAPI_PTR *PFN_xrCreateApiLayerInstance)(const XrInstanceCreateInfo *info, 36 | const XrApiLayerCreateInfo *apiLayerInfo, XrInstance *instance); 37 | 38 | // Loader/API Layer Interface versions 39 | // 1 - First version, introduces negotiation structure and functions 40 | #define XR_CURRENT_LOADER_API_LAYER_VERSION 1 41 | 42 | // Loader/Runtime Interface versions 43 | // 1 - First version, introduces negotiation structure and functions 44 | #define XR_CURRENT_LOADER_RUNTIME_VERSION 1 45 | 46 | // Version negotiation values 47 | typedef enum XrLoaderInterfaceStructs { 48 | XR_LOADER_INTERFACE_STRUCT_UNINTIALIZED = 0, 49 | XR_LOADER_INTERFACE_STRUCT_LOADER_INFO, 50 | XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST, 51 | XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST, 52 | XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO, 53 | XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO, 54 | } XrLoaderInterfaceStructs; 55 | 56 | #define XR_LOADER_INFO_STRUCT_VERSION 1 57 | typedef struct XrNegotiateLoaderInfo { 58 | XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_LOADER_INFO 59 | uint32_t structVersion; // XR_LOADER_INFO_STRUCT_VERSION 60 | size_t structSize; // sizeof(XrNegotiateLoaderInfo) 61 | uint32_t minInterfaceVersion; 62 | uint32_t maxInterfaceVersion; 63 | XrVersion minApiVersion; 64 | XrVersion maxApiVersion; 65 | } XrNegotiateLoaderInfo; 66 | 67 | #define XR_API_LAYER_INFO_STRUCT_VERSION 1 68 | typedef struct XrNegotiateApiLayerRequest { 69 | XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_REQUEST 70 | uint32_t structVersion; // XR_API_LAYER_INFO_STRUCT_VERSION 71 | size_t structSize; // sizeof(XrNegotiateApiLayerRequest) 72 | uint32_t layerInterfaceVersion; // CURRENT_LOADER_API_LAYER_VERSION 73 | XrVersion layerApiVersion; 74 | PFN_xrGetInstanceProcAddr getInstanceProcAddr; 75 | PFN_xrCreateApiLayerInstance createApiLayerInstance; 76 | } XrNegotiateApiLayerRequest; 77 | 78 | #define XR_RUNTIME_INFO_STRUCT_VERSION 1 79 | typedef struct XrNegotiateRuntimeRequest { 80 | XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_RUNTIME_REQUEST 81 | uint32_t structVersion; // XR_RUNTIME_INFO_STRUCT_VERSION 82 | size_t structSize; // sizeof(XrNegotiateRuntimeRequest) 83 | uint32_t runtimeInterfaceVersion; // CURRENT_LOADER_RUNTIME_VERSION 84 | XrVersion runtimeApiVersion; 85 | PFN_xrGetInstanceProcAddr getInstanceProcAddr; 86 | } XrNegotiateRuntimeRequest; 87 | 88 | // Function used to negotiate an interface betewen the loader and an API layer. Each library exposing one or 89 | // more API layers needs to expose at least this function. 90 | typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderApiLayerInterface)(const XrNegotiateLoaderInfo *loaderInfo, 91 | const char *apiLayerName, 92 | XrNegotiateApiLayerRequest *apiLayerRequest); 93 | 94 | // Function used to negotiate an interface betewen the loader and a runtime. Each runtime should expose 95 | // at least this function. 96 | typedef XrResult(XRAPI_PTR *PFN_xrNegotiateLoaderRuntimeInterface)(const XrNegotiateLoaderInfo *loaderInfo, 97 | XrNegotiateRuntimeRequest *runtimeRequest); 98 | 99 | // Forward declare. 100 | typedef struct XrApiLayerNextInfo XrApiLayerNextInfo; 101 | 102 | #define XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 1 103 | struct XrApiLayerNextInfo { 104 | XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_NEXT_INFO 105 | uint32_t structVersion; // XR_API_LAYER_NEXT_INFO_STRUCT_VERSION 106 | size_t structSize; // sizeof(XrApiLayerNextInfo) 107 | char layerName[XR_MAX_API_LAYER_NAME_SIZE]; // Name of API layer which should receive this info 108 | PFN_xrGetInstanceProcAddr nextGetInstanceProcAddr; // Pointer to next API layer's xrGetInstanceProcAddr 109 | PFN_xrCreateApiLayerInstance nextCreateApiLayerInstance; // Pointer to next API layer's xrCreateApiLayerInstance 110 | XrApiLayerNextInfo *next; // Pointer to the next API layer info in the sequence 111 | }; 112 | 113 | #define XR_API_LAYER_MAX_SETTINGS_PATH_SIZE 512 114 | #define XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 1 115 | typedef struct XrApiLayerCreateInfo { 116 | XrLoaderInterfaceStructs structType; // XR_LOADER_INTERFACE_STRUCT_API_LAYER_CREATE_INFO 117 | uint32_t structVersion; // XR_API_LAYER_CREATE_INFO_STRUCT_VERSION 118 | size_t structSize; // sizeof(XrApiLayerCreateInfo) 119 | void *loaderInstance; // Pointer to the LoaderInstance class 120 | char settings_file_location[XR_API_LAYER_MAX_SETTINGS_PATH_SIZE]; // Location to the found settings file (or empty '\0') 121 | XrApiLayerNextInfo *nextInfo; // Pointer to the next API layer's Info 122 | } XrApiLayerCreateInfo; 123 | 124 | #ifdef __cplusplus 125 | } // extern "C" 126 | #endif 127 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/object_info.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // Copyright (c) 2017-2019 Valve Corporation 3 | // Copyright (c) 2017-2019 LunarG, Inc. 4 | // Copyright (c) 2019 Collabora, Ltd. 5 | // 6 | // SPDX-License-Identifier: Apache-2.0 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | // Author: Mark Young , Ryan Pavlik 21 | // Author: Dave Houlton 22 | // 23 | 24 | #include "object_info.h" 25 | 26 | #include "extra_algorithms.h" 27 | #include "hex_and_handles.h" 28 | 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "memory.h" 39 | 40 | std::string XrSdkLogObjectInfo::ToString() const { 41 | std::ostringstream oss; 42 | oss << Uint64ToHexString(handle); 43 | if (!name.empty()) { 44 | oss << " (" << name << ")"; 45 | } 46 | return oss.str(); 47 | } 48 | 49 | void ObjectInfoCollection::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) { 50 | // If name is empty, we should erase it 51 | if (object_name.empty()) { 52 | RemoveObject(object_handle, object_type); 53 | return; 54 | } 55 | 56 | // Otherwise, add it or update the name 57 | XrSdkLogObjectInfo new_obj = {object_handle, object_type}; 58 | 59 | // If it already exists, update the name 60 | auto lookup_info = LookUpStoredObjectInfo(new_obj); 61 | if (lookup_info != nullptr) { 62 | lookup_info->name = object_name; 63 | return; 64 | } 65 | 66 | // It doesn't exist, so add a new info block 67 | new_obj.name = object_name; 68 | object_info_.push_back(new_obj); 69 | } 70 | 71 | void ObjectInfoCollection::RemoveObject(uint64_t object_handle, XrObjectType object_type) { 72 | vector_remove_if_and_erase( 73 | object_info_, [=](XrSdkLogObjectInfo const& info) { return info.handle == object_handle && info.type == object_type; }); 74 | } 75 | 76 | XrSdkLogObjectInfo const* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const { 77 | auto e = object_info_.end(); 78 | auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); }); 79 | if (it != e) { 80 | return &(*it); 81 | } 82 | return nullptr; 83 | } 84 | 85 | XrSdkLogObjectInfo* ObjectInfoCollection::LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) { 86 | auto e = object_info_.end(); 87 | auto it = std::find_if(object_info_.begin(), e, [&](XrSdkLogObjectInfo const& stored) { return Equivalent(stored, info); }); 88 | if (it != e) { 89 | return &(*it); 90 | } 91 | return nullptr; 92 | } 93 | 94 | bool ObjectInfoCollection::LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const { 95 | auto info_lookup = LookUpStoredObjectInfo(info.objectHandle, info.objectType); 96 | if (info_lookup != nullptr) { 97 | info.objectName = info_lookup->name.c_str(); 98 | return true; 99 | } 100 | return false; 101 | } 102 | 103 | bool ObjectInfoCollection::LookUpObjectName(XrSdkLogObjectInfo& info) const { 104 | auto info_lookup = LookUpStoredObjectInfo(info); 105 | if (info_lookup != nullptr) { 106 | info.name = info_lookup->name; 107 | return true; 108 | } 109 | return false; 110 | } 111 | 112 | static std::vector PopulateObjectNameInfo(std::vector const& obj) { 113 | std::vector ret; 114 | ret.reserve(obj.size()); 115 | std::transform(obj.begin(), obj.end(), std::back_inserter(ret), [](XrSdkLogObjectInfo const& info) { 116 | return XrDebugUtilsObjectNameInfoEXT{XR_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, nullptr, info.type, info.handle, 117 | info.name.c_str()}; 118 | }); 119 | return ret; 120 | } 121 | 122 | NamesAndLabels::NamesAndLabels(std::vector obj, std::vector lab) 123 | : sdk_objects(std::move(obj)), objects(PopulateObjectNameInfo(sdk_objects)), labels(std::move(lab)) {} 124 | 125 | void NamesAndLabels::PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& callback_data) const { 126 | callback_data.objects = objects.empty() ? nullptr : const_cast(objects.data()); 127 | callback_data.objectCount = static_cast(objects.size()); 128 | callback_data.sessionLabels = labels.empty() ? nullptr : const_cast(labels.data()); 129 | callback_data.sessionLabelCount = static_cast(labels.size()); 130 | } 131 | 132 | void DebugUtilsData::LookUpSessionLabels(XrSession session, std::vector& labels) const { 133 | auto session_label_iterator = session_labels_.find(session); 134 | if (session_label_iterator != session_labels_.end()) { 135 | auto& XrSdkSessionLabels = *session_label_iterator->second; 136 | // Copy the debug utils labels in reverse order in the the labels vector. 137 | std::transform(XrSdkSessionLabels.rbegin(), XrSdkSessionLabels.rend(), std::back_inserter(labels), 138 | [](XrSdkSessionLabelPtr const& label) { return label->debug_utils_label; }); 139 | } 140 | } 141 | 142 | XrSdkSessionLabel::XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual) 143 | : label_name(label_info.labelName), debug_utils_label(label_info), is_individual_label(individual) { 144 | // Update the c string pointer to the one we hold. 145 | debug_utils_label.labelName = label_name.c_str(); 146 | } 147 | 148 | XrSdkSessionLabelPtr XrSdkSessionLabel::make(const XrDebugUtilsLabelEXT& label_info, bool individual) { 149 | XrSdkSessionLabelPtr ret(new XrSdkSessionLabel(label_info, individual)); 150 | return ret; 151 | } 152 | void DebugUtilsData::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) { 153 | object_info_.AddObjectName(object_handle, object_type, object_name); 154 | } 155 | 156 | // We always want to remove the old individual label before we do anything else. 157 | // So, do that in it's own method 158 | void DebugUtilsData::RemoveIndividualLabel(XrSdkSessionLabelList& label_vec) { 159 | if (!label_vec.empty() && label_vec.back()->is_individual_label) { 160 | label_vec.pop_back(); 161 | } 162 | } 163 | 164 | XrSdkSessionLabelList* DebugUtilsData::GetSessionLabelList(XrSession session) { 165 | auto session_label_iterator = session_labels_.find(session); 166 | if (session_label_iterator == session_labels_.end()) { 167 | return nullptr; 168 | } 169 | return session_label_iterator->second.get(); 170 | } 171 | 172 | XrSdkSessionLabelList& DebugUtilsData::GetOrCreateSessionLabelList(XrSession session) { 173 | XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session); 174 | if (vec_ptr == nullptr) { 175 | std::unique_ptr vec(new XrSdkSessionLabelList); 176 | vec_ptr = vec.get(); 177 | session_labels_[session] = std::move(vec); 178 | } 179 | return *vec_ptr; 180 | } 181 | 182 | void DebugUtilsData::BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info) { 183 | auto& vec = GetOrCreateSessionLabelList(session); 184 | 185 | // Individual labels do not stay around in the transition into a new label region 186 | RemoveIndividualLabel(vec); 187 | 188 | // Start the new label region 189 | vec.emplace_back(XrSdkSessionLabel::make(label_info, false)); 190 | } 191 | 192 | void DebugUtilsData::EndLabelRegion(XrSession session) { 193 | XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session); 194 | if (vec_ptr == nullptr) { 195 | return; 196 | } 197 | 198 | // Individual labels do not stay around in the transition out of label region 199 | RemoveIndividualLabel(*vec_ptr); 200 | 201 | // Remove the last label region 202 | if (!vec_ptr->empty()) { 203 | vec_ptr->pop_back(); 204 | } 205 | } 206 | 207 | void DebugUtilsData::InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info) { 208 | auto& vec = GetOrCreateSessionLabelList(session); 209 | 210 | // Remove any individual layer that might already be there 211 | RemoveIndividualLabel(vec); 212 | 213 | // Insert a new individual label 214 | vec.emplace_back(XrSdkSessionLabel::make(label_info, true)); 215 | } 216 | 217 | void DebugUtilsData::DeleteObject(uint64_t object_handle, XrObjectType object_type) { 218 | object_info_.RemoveObject(object_handle, object_type); 219 | 220 | if (object_type == XR_OBJECT_TYPE_SESSION) { 221 | auto session = TreatIntegerAsHandle(object_handle); 222 | XrSdkSessionLabelList* vec_ptr = GetSessionLabelList(session); 223 | if (vec_ptr != nullptr) { 224 | session_labels_.erase(session); 225 | } 226 | } 227 | } 228 | 229 | void DebugUtilsData::DeleteSessionLabels(XrSession session) { session_labels_.erase(session); } 230 | 231 | NamesAndLabels DebugUtilsData::PopulateNamesAndLabels(std::vector objects) const { 232 | std::vector labels; 233 | for (auto& obj : objects) { 234 | // Check for any names that have been associated with the objects and set them up here 235 | object_info_.LookUpObjectName(obj); 236 | // If this is a session, see if there are any labels associated with it for us to add 237 | // to the callback content. 238 | if (XR_OBJECT_TYPE_SESSION == obj.type) { 239 | LookUpSessionLabels(obj.GetTypedHandle(), labels); 240 | } 241 | } 242 | 243 | return {objects, labels}; 244 | } 245 | 246 | void DebugUtilsData::WrapCallbackData(AugmentedCallbackData* aug_data, 247 | const XrDebugUtilsMessengerCallbackDataEXT* callback_data) const { 248 | // If there's nothing to add, just return the original data as the augmented copy 249 | aug_data->exported_data = callback_data; 250 | if (object_info_.Empty() || callback_data->objectCount == 0) { 251 | return; 252 | } 253 | 254 | // Inspect each of the callback objects 255 | bool name_found = false; 256 | for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) { 257 | auto& current_obj = callback_data->objects[obj]; 258 | name_found |= (nullptr != object_info_.LookUpStoredObjectInfo(current_obj.objectHandle, current_obj.objectType)); 259 | 260 | // If this is a session, record any labels associated with it 261 | if (XR_OBJECT_TYPE_SESSION == current_obj.objectType) { 262 | XrSession session = TreatIntegerAsHandle(current_obj.objectHandle); 263 | LookUpSessionLabels(session, aug_data->labels); 264 | } 265 | } 266 | 267 | // If we found nothing to add, return the original data 268 | if (!name_found && aug_data->labels.empty()) { 269 | return; 270 | } 271 | 272 | // Found additional data - modify an internal copy and return that as the exported data 273 | memcpy(&aug_data->modified_data, callback_data, sizeof(XrDebugUtilsMessengerCallbackDataEXT)); 274 | aug_data->new_objects.assign(callback_data->objects, callback_data->objects + callback_data->objectCount); 275 | 276 | // Record (overwrite) the names of all incoming objects provided in our internal list 277 | for (auto& obj : aug_data->new_objects) { 278 | object_info_.LookUpObjectName(obj); 279 | } 280 | 281 | // Update local copy & point export to it 282 | aug_data->modified_data.objects = aug_data->new_objects.data(); 283 | aug_data->modified_data.sessionLabelCount = static_cast(aug_data->labels.size()); 284 | aug_data->modified_data.sessionLabels = aug_data->labels.empty() ? nullptr : aug_data->labels.data(); 285 | aug_data->exported_data = &aug_data->modified_data; 286 | return; 287 | } 288 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/object_info.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 The Khronos Group Inc. 2 | // Copyright (c) 2017-2019 Valve Corporation 3 | // Copyright (c) 2017-2019 LunarG, Inc. 4 | // Copyright (c) 2019 Collabora, Ltd. 5 | // 6 | // SPDX-License-Identifier: Apache-2.0 7 | // 8 | // Licensed under the Apache License, Version 2.0 (the "License"); 9 | // you may not use this file except in compliance with the License. 10 | // You may obtain a copy of the License at 11 | // 12 | // http://www.apache.org/licenses/LICENSE-2.0 13 | // 14 | // Unless required by applicable law or agreed to in writing, software 15 | // distributed under the License is distributed on an "AS IS" BASIS, 16 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | // See the License for the specific language governing permissions and 18 | // limitations under the License. 19 | // 20 | // Author: Mark Young , Ryan Pavlik 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | struct XrSdkGenericObject { 40 | //! Type-erased handle value 41 | uint64_t handle; 42 | 43 | //! Kind of object this handle refers to 44 | XrObjectType type; 45 | /// Un-erase the type of the handle and get it properly typed again. 46 | /// 47 | /// Note: Does not check the type before doing it! 48 | template 49 | HandleType& GetTypedHandle() { 50 | return TreatIntegerAsHandle(handle); 51 | } 52 | 53 | //! @overload 54 | template 55 | HandleType const& GetTypedHandle() const { 56 | return TreatIntegerAsHandle(handle); 57 | } 58 | 59 | //! Create from a typed handle and object type 60 | template 61 | XrSdkGenericObject(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {} 62 | 63 | //! Create from an untyped handle value (integer) and object type 64 | XrSdkGenericObject(uint64_t h, XrObjectType t) : handle(h), type(t) {} 65 | }; 66 | 67 | struct XrSdkLogObjectInfo { 68 | //! Type-erased handle value 69 | uint64_t handle; 70 | 71 | //! Kind of object this handle refers to 72 | XrObjectType type; 73 | 74 | //! To be assigned by the application - not part of this object's identity 75 | std::string name; 76 | 77 | /// Un-erase the type of the handle and get it properly typed again. 78 | /// 79 | /// Note: Does not check the type before doing it! 80 | template 81 | HandleType& GetTypedHandle() { 82 | return TreatIntegerAsHandle(handle); 83 | } 84 | 85 | //! @overload 86 | template 87 | HandleType const& GetTypedHandle() const { 88 | return TreatIntegerAsHandle(handle); 89 | } 90 | 91 | XrSdkLogObjectInfo() = default; 92 | 93 | //! Create from a typed handle and object type 94 | template 95 | XrSdkLogObjectInfo(T h, XrObjectType t) : handle(MakeHandleGeneric(h)), type(t) {} 96 | 97 | //! Create from an untyped handle value (integer) and object type 98 | XrSdkLogObjectInfo(uint64_t h, XrObjectType t) : handle(h), type(t) {} 99 | //! Create from an untyped handle value (integer), object type, and name 100 | XrSdkLogObjectInfo(uint64_t h, XrObjectType t, const char* n) : handle(h), type(t), name(n == nullptr ? "" : n) {} 101 | 102 | std::string ToString() const; 103 | }; 104 | 105 | //! True if the two object infos have the same handle value and handle type 106 | static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrSdkLogObjectInfo const& b) { 107 | return a.handle == b.handle && a.type == b.type; 108 | } 109 | 110 | //! @overload 111 | static inline bool Equivalent(XrDebugUtilsObjectNameInfoEXT const& a, XrSdkLogObjectInfo const& b) { 112 | return a.objectHandle == b.handle && a.objectType == b.type; 113 | } 114 | 115 | //! @overload 116 | static inline bool Equivalent(XrSdkLogObjectInfo const& a, XrDebugUtilsObjectNameInfoEXT const& b) { return Equivalent(b, a); } 117 | 118 | /// Object info registered with calls to xrSetDebugUtilsObjectNameEXT 119 | class ObjectInfoCollection { 120 | public: 121 | void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name); 122 | 123 | void RemoveObject(uint64_t object_handle, XrObjectType object_type); 124 | 125 | //! Find the stored object info, if any, matching handle and type. 126 | //! Return nullptr if not found. 127 | XrSdkLogObjectInfo const* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info) const; 128 | 129 | //! Find the stored object info, if any, matching handle and type. 130 | //! Return nullptr if not found. 131 | XrSdkLogObjectInfo* LookUpStoredObjectInfo(XrSdkLogObjectInfo const& info); 132 | 133 | //! Find the stored object info, if any. 134 | //! Return nullptr if not found. 135 | XrSdkLogObjectInfo const* LookUpStoredObjectInfo(uint64_t handle, XrObjectType type) const { 136 | return LookUpStoredObjectInfo({handle, type}); 137 | } 138 | 139 | //! Find the object name, if any, and update debug utils info accordingly. 140 | //! Return true if found and updated. 141 | bool LookUpObjectName(XrDebugUtilsObjectNameInfoEXT& info) const; 142 | 143 | //! Find the object name, if any, and update logging info accordingly. 144 | //! Return true if found and updated. 145 | bool LookUpObjectName(XrSdkLogObjectInfo& info) const; 146 | 147 | //! Is the collection empty? 148 | bool Empty() const { return object_info_.empty(); } 149 | 150 | private: 151 | // Object names that have been set for given objects 152 | std::vector object_info_; 153 | }; 154 | 155 | struct XrSdkSessionLabel; 156 | using XrSdkSessionLabelPtr = std::unique_ptr; 157 | using XrSdkSessionLabelList = std::vector; 158 | 159 | struct XrSdkSessionLabel { 160 | static XrSdkSessionLabelPtr make(const XrDebugUtilsLabelEXT& label_info, bool individual); 161 | 162 | std::string label_name; 163 | XrDebugUtilsLabelEXT debug_utils_label; 164 | bool is_individual_label; 165 | 166 | private: 167 | XrSdkSessionLabel(const XrDebugUtilsLabelEXT& label_info, bool individual); 168 | }; 169 | 170 | /// The metadata for a collection of objects. Must persist unmodified during the entire debug messenger call! 171 | struct NamesAndLabels { 172 | NamesAndLabels() = default; 173 | NamesAndLabels(std::vector obj, std::vector lab); 174 | /// C++ structure owning the data (strings) backing the objects vector. 175 | std::vector sdk_objects; 176 | 177 | std::vector objects; 178 | std::vector labels; 179 | 180 | /// Populate the debug utils callback data structure. 181 | void PopulateCallbackData(XrDebugUtilsMessengerCallbackDataEXT& data) const; 182 | // XrDebugUtilsMessengerCallbackDataEXT MakeCallbackData() const; 183 | }; 184 | 185 | struct AugmentedCallbackData { 186 | std::vector labels; 187 | std::vector new_objects; 188 | XrDebugUtilsMessengerCallbackDataEXT modified_data; 189 | const XrDebugUtilsMessengerCallbackDataEXT* exported_data; 190 | }; 191 | 192 | /// Tracks all the data (handle names and session labels) required to fully augment XR_EXT_debug_utils-related calls. 193 | class DebugUtilsData { 194 | public: 195 | DebugUtilsData() = default; 196 | 197 | DebugUtilsData(const DebugUtilsData&) = delete; 198 | DebugUtilsData& operator=(const DebugUtilsData&) = delete; 199 | 200 | bool Empty() const { return object_info_.Empty() && session_labels_.empty(); } 201 | 202 | //! Core of implementation for xrSetDebugUtilsObjectNameEXT 203 | void AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name); 204 | 205 | /// Core of implementation for xrSessionBeginDebugUtilsLabelRegionEXT 206 | void BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT& label_info); 207 | 208 | /// Core of implementation for xrSessionEndDebugUtilsLabelRegionEXT 209 | void EndLabelRegion(XrSession session); 210 | 211 | /// Core of implementation for xrSessionInsertDebugUtilsLabelEXT 212 | void InsertLabel(XrSession session, const XrDebugUtilsLabelEXT& label_info); 213 | 214 | /// Removes all labels associated with a session - call in xrDestroySession and xrDestroyInstance (for all child sessions) 215 | void DeleteSessionLabels(XrSession session); 216 | 217 | /// Retrieve labels for the given session, if any, and push them in reverse order on the vector. 218 | void LookUpSessionLabels(XrSession session, std::vector& labels) const; 219 | 220 | /// Removes all data related to this object - including session labels if it's a session. 221 | /// 222 | /// Does not take care of handling child objects - you must do this yourself. 223 | void DeleteObject(uint64_t object_handle, XrObjectType object_type); 224 | 225 | /// Given the collection of objects, populate their names and list of labels 226 | NamesAndLabels PopulateNamesAndLabels(std::vector objects) const; 227 | 228 | void WrapCallbackData(AugmentedCallbackData* aug_data, 229 | const XrDebugUtilsMessengerCallbackDataEXT* provided_callback_data) const; 230 | 231 | private: 232 | void RemoveIndividualLabel(XrSdkSessionLabelList& label_vec); 233 | XrSdkSessionLabelList* GetSessionLabelList(XrSession session); 234 | XrSdkSessionLabelList& GetOrCreateSessionLabelList(XrSession session); 235 | 236 | // Session labels: one vector of them per session. 237 | std::unordered_map> session_labels_; 238 | 239 | // Names for objects. 240 | ObjectInfoCollection object_info_; 241 | }; 242 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/platform_utils.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017-2020 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 6 | // 7 | // Licensed under the Apache License, Version 2.0 (the "License"); 8 | // you may not use this file except in compliance with the License. 9 | // You may obtain a copy of the License at 10 | // 11 | // http://www.apache.org/licenses/LICENSE-2.0 12 | // 13 | // Unless required by applicable law or agreed to in writing, software 14 | // distributed under the License is distributed on an "AS IS" BASIS, 15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | // See the License for the specific language governing permissions and 17 | // limitations under the License. 18 | // 19 | // Author: Mark Young 20 | // Author: Dave Houlton 21 | // 22 | 23 | #pragma once 24 | 25 | #include "xr_dependencies.h" 26 | #include 27 | #include 28 | 29 | // OpenXR paths and registry key locations 30 | #define OPENXR_RELATIVE_PATH "openxr/" 31 | #define OPENXR_IMPLICIT_API_LAYER_RELATIVE_PATH "/api_layers/implicit.d" 32 | #define OPENXR_EXPLICIT_API_LAYER_RELATIVE_PATH "/api_layers/explicit.d" 33 | #ifdef XR_OS_WINDOWS 34 | #define OPENXR_REGISTRY_LOCATION "SOFTWARE\\Khronos\\OpenXR\\" 35 | #define OPENXR_IMPLICIT_API_LAYER_REGISTRY_LOCATION "\\ApiLayers\\Implicit" 36 | #define OPENXR_EXPLICIT_API_LAYER_REGISTRY_LOCATION "\\ApiLayers\\Explicit" 37 | #endif 38 | 39 | // OpenXR Loader environment variables of interest 40 | #define OPENXR_RUNTIME_JSON_ENV_VAR "XR_RUNTIME_JSON" 41 | #define OPENXR_API_LAYER_PATH_ENV_VAR "XR_API_LAYER_PATH" 42 | 43 | // This is a CMake generated file with #defines for any functions/includes 44 | // that it found present and build-time configuration. 45 | // If you don't have this file, on non-Windows you'll need to define 46 | // one of HAVE_SECURE_GETENV or HAVE___SECURE_GETENV depending on which 47 | // of secure_getenv or __secure_getenv are present 48 | #ifdef OPENXR_HAVE_COMMON_CONFIG 49 | #include "common_config.h" 50 | #endif // OPENXR_HAVE_COMMON_CONFIG 51 | 52 | // Environment variables 53 | #if defined(XR_OS_LINUX) || defined(XR_OS_APPLE) 54 | 55 | #include 56 | #include 57 | #include 58 | 59 | namespace detail { 60 | 61 | static inline char* ImplGetEnv(const char* name) { return getenv(name); } 62 | 63 | static inline int ImplSetEnv(const char* name, const char* value, int overwrite) { return setenv(name, value, overwrite); } 64 | 65 | static inline char* ImplGetSecureEnv(const char* name) { 66 | #ifdef HAVE_SECURE_GETENV 67 | return secure_getenv(name); 68 | #elif defined(HAVE___SECURE_GETENV) 69 | return __secure_getenv(name); 70 | #else 71 | #pragma message( \ 72 | "Warning: Falling back to non-secure getenv for environmental" \ 73 | "lookups! Consider updating to a different libc.") 74 | 75 | return ImplGetEnv(name); 76 | #endif 77 | } 78 | } // namespace detail 79 | 80 | #endif // defined(XR_OS_LINUX) || defined(XR_OS_APPLE) 81 | #if defined(XR_OS_LINUX) 82 | 83 | static inline std::string PlatformUtilsGetEnv(const char* name) { 84 | auto str = detail::ImplGetEnv(name); 85 | if (str == nullptr) { 86 | return {}; 87 | } 88 | return str; 89 | } 90 | 91 | static inline std::string PlatformUtilsGetSecureEnv(const char* name) { 92 | auto str = detail::ImplGetSecureEnv(name); 93 | if (str == nullptr) { 94 | return {}; 95 | } 96 | return str; 97 | } 98 | 99 | static inline bool PlatformUtilsGetEnvSet(const char* name) { return detail::ImplGetEnv(name) != nullptr; } 100 | 101 | static inline bool PlatformUtilsSetEnv(const char* name, const char* value) { 102 | const int shouldOverwrite = 1; 103 | int result = detail::ImplSetEnv(name, value, shouldOverwrite); 104 | return (result == 0); 105 | } 106 | 107 | #elif defined(XR_OS_APPLE) 108 | 109 | static inline std::string PlatformUtilsGetEnv(const char* name) { 110 | auto str = detail::ImplGetEnv(name); 111 | if (str == nullptr) { 112 | return {}; 113 | } 114 | return str; 115 | } 116 | 117 | static inline std::string PlatformUtilsGetSecureEnv(const char* name) { 118 | auto str = detail::ImplGetSecureEnv(name); 119 | if (str == nullptr) { 120 | return {}; 121 | } 122 | return str; 123 | } 124 | 125 | static inline bool PlatformUtilsGetEnvSet(const char* name) { return detail::ImplGetEnv(name) != nullptr; } 126 | 127 | static inline bool PlatformUtilsSetEnv(const char* name, const char* value) { 128 | const int shouldOverwrite = 1; 129 | int result = detail::ImplSetEnv(name, value, shouldOverwrite); 130 | return (result == 0); 131 | } 132 | 133 | // Prefix for the Apple global runtime JSON file name 134 | static const std::string rt_dir_prefix = "/usr/local/share/openxr/"; 135 | static const std::string rt_filename = "/active_runtime.json"; 136 | 137 | static inline bool PlatformGetGlobalRuntimeFileName(uint16_t major_version, std::string& file_name) { 138 | file_name = rt_dir_prefix; 139 | file_name += std::to_string(major_version); 140 | file_name += rt_filename; 141 | return true; 142 | } 143 | 144 | #elif defined(XR_OS_WINDOWS) 145 | 146 | #if defined(_DEBUG) 147 | inline void LogError(const std::string& error) { OutputDebugStringA(error.c_str()); } 148 | #else 149 | #define LogError(x) 150 | #endif 151 | 152 | inline std::wstring utf8_to_wide(const std::string& utf8Text) { 153 | if (utf8Text.empty()) { 154 | return {}; 155 | } 156 | 157 | std::wstring wideText; 158 | const int wideLength = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), nullptr, 0); 159 | if (wideLength == 0) { 160 | LogError("utf8_to_wide get size error: " + std::to_string(::GetLastError())); 161 | return {}; 162 | } 163 | 164 | // MultiByteToWideChar returns number of chars of the input buffer, regardless of null terminitor 165 | wideText.resize(wideLength, 0); 166 | wchar_t* wideString = const_cast(wideText.data()); // mutable data() only exists in c++17 167 | const int length = ::MultiByteToWideChar(CP_UTF8, 0, utf8Text.data(), (int)utf8Text.size(), wideString, wideLength); 168 | if (length != wideLength) { 169 | LogError("utf8_to_wide convert string error: " + std::to_string(::GetLastError())); 170 | return {}; 171 | } 172 | 173 | return wideText; 174 | } 175 | 176 | inline std::string wide_to_utf8(const std::wstring& wideText) { 177 | if (wideText.empty()) { 178 | return {}; 179 | } 180 | 181 | std::string narrowText; 182 | int narrowLength = ::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), nullptr, 0, nullptr, nullptr); 183 | if (narrowLength == 0) { 184 | LogError("wide_to_utf8 get size error: " + std::to_string(::GetLastError())); 185 | return {}; 186 | } 187 | 188 | // WideCharToMultiByte returns number of chars of the input buffer, regardless of null terminitor 189 | narrowText.resize(narrowLength, 0); 190 | char* narrowString = const_cast(narrowText.data()); // mutable data() only exists in c++17 191 | const int length = 192 | ::WideCharToMultiByte(CP_UTF8, 0, wideText.data(), (int)wideText.size(), narrowString, narrowLength, nullptr, nullptr); 193 | if (length != narrowLength) { 194 | LogError("wide_to_utf8 convert string error: " + std::to_string(::GetLastError())); 195 | return {}; 196 | } 197 | 198 | return narrowText; 199 | } 200 | 201 | // Returns true if the current process has an integrity level > SECURITY_MANDATORY_MEDIUM_RID. 202 | static inline bool IsHighIntegrityLevel() { 203 | // Execute this check once and save the value as a static bool. 204 | static bool isHighIntegrityLevel = ([] { 205 | HANDLE processToken; 206 | if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &processToken)) { 207 | // Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD. 208 | uint8_t mandatoryLabelBuffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)]{}; 209 | DWORD bufferSize; 210 | if (GetTokenInformation(processToken, TokenIntegrityLevel, mandatoryLabelBuffer, sizeof(mandatoryLabelBuffer), 211 | &bufferSize) != 0) { 212 | const auto mandatoryLabel = reinterpret_cast(mandatoryLabelBuffer); 213 | if (mandatoryLabel->Label.Sid != 0) { 214 | const DWORD subAuthorityCount = *GetSidSubAuthorityCount(mandatoryLabel->Label.Sid); 215 | const DWORD integrityLevel = *GetSidSubAuthority(mandatoryLabel->Label.Sid, subAuthorityCount - 1); 216 | CloseHandle(processToken); 217 | return integrityLevel > SECURITY_MANDATORY_MEDIUM_RID; 218 | } 219 | } 220 | 221 | CloseHandle(processToken); 222 | } 223 | 224 | return false; 225 | })(); 226 | 227 | return isHighIntegrityLevel; 228 | } 229 | 230 | // Returns true if the given environment variable exists. 231 | // The name is a case-sensitive UTF8 string. 232 | static inline bool PlatformUtilsGetEnvSet(const char* name) { 233 | const std::wstring wname = utf8_to_wide(name); 234 | const DWORD valSize = ::GetEnvironmentVariableW(wname.c_str(), nullptr, 0); 235 | // GetEnvironmentVariable returns 0 when environment variable does not exist or there is an error. 236 | return 0 != valSize; 237 | } 238 | 239 | // Returns the environment variable value for the given name. 240 | // Returns an empty string if the environment variable doesn't exist or if it exists but is empty. 241 | // Use PlatformUtilsGetEnvSet to tell if it exists. 242 | // The name is a case-sensitive UTF8 string. 243 | static inline std::string PlatformUtilsGetEnv(const char* name) { 244 | const std::wstring wname = utf8_to_wide(name); 245 | const DWORD valSize = ::GetEnvironmentVariableW(wname.c_str(), nullptr, 0); 246 | // GetEnvironmentVariable returns 0 when environment variable does not exist or there is an error. 247 | // The size includes the null-terminator, so a size of 1 is means the variable was explicitly set to empty. 248 | if (valSize == 0 || valSize == 1) { 249 | return {}; 250 | } 251 | 252 | // GetEnvironmentVariable returns size including null terminator for "query size" call. 253 | std::wstring wValue(valSize, 0); 254 | wchar_t* wValueData = &wValue[0]; 255 | 256 | // GetEnvironmentVariable returns string length, excluding null terminator for "get value" 257 | // call if there was enough capacity. Else it returns the required capacity (including null terminator). 258 | const DWORD length = ::GetEnvironmentVariableW(wname.c_str(), wValueData, (DWORD)wValue.size()); 259 | if ((length == 0) || (length >= wValue.size())) { // If error or the variable increased length between calls... 260 | LogError("GetEnvironmentVariable get value error: " + std::to_string(::GetLastError())); 261 | return {}; 262 | } 263 | 264 | wValue.resize(length); // Strip the null terminator. 265 | 266 | return wide_to_utf8(wValue); 267 | } 268 | 269 | // Acts the same as PlatformUtilsGetEnv except returns an empty string if IsHighIntegrityLevel. 270 | static inline std::string PlatformUtilsGetSecureEnv(const char* name) { 271 | // Do not allow high integrity processes to act on data that can be controlled by medium integrity processes. 272 | if (IsHighIntegrityLevel()) { 273 | return {}; 274 | } 275 | 276 | // No secure version for Windows so the above integrity check is needed. 277 | return PlatformUtilsGetEnv(name); 278 | } 279 | 280 | // Sets an environment variable via UTF8 strings. 281 | // The name is case-sensitive. 282 | // Overwrites the variable if it already exists. 283 | // Returns true if it could be set. 284 | static inline bool PlatformUtilsSetEnv(const char* name, const char* value) { 285 | const std::wstring wname = utf8_to_wide(name); 286 | const std::wstring wvalue = utf8_to_wide(value); 287 | BOOL result = ::SetEnvironmentVariableW(wname.c_str(), wvalue.c_str()); 288 | return (result != 0); 289 | } 290 | 291 | #else // Not Linux, Apple, nor Windows 292 | 293 | static inline bool PlatformUtilsGetEnvSet(const char* /* name */) { 294 | // Stub func 295 | return false; 296 | } 297 | 298 | static inline std::string PlatformUtilsGetEnv(const char* /* name */) { 299 | // Stub func 300 | return {}; 301 | } 302 | 303 | static inline std::string PlatformUtilsGetSecureEnv(const char* /* name */) { 304 | // Stub func 305 | return {}; 306 | } 307 | 308 | static inline bool PlatformUtilsSetEnv(const char* /* name */, const char* /* value */) { 309 | // Stub func 310 | return false; 311 | } 312 | 313 | static inline bool PlatformGetGlobalRuntimeFileName(uint16_t /* major_version */, std::string const& /* file_name */) { 314 | // Stub func 315 | return false; 316 | } 317 | 318 | #endif 319 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/common/xr_dependencies.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020 The Khronos Group Inc. 2 | // 3 | // SPDX-License-Identifier: Apache-2.0 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | // This file includes headers with types which openxr.h depends on in order 18 | // to compile when platforms, graphics apis, and the like are enabled. 19 | 20 | #pragma once 21 | 22 | #ifdef XR_USE_PLATFORM_ANDROID 23 | #include 24 | #include 25 | #include 26 | #endif // XR_USE_PLATFORM_ANDROID 27 | 28 | #ifdef XR_USE_PLATFORM_WIN32 29 | 30 | #include 31 | #if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)) 32 | // Enable desktop partition APIs, such as RegOpenKeyEx, LoadLibraryEx, PathFileExists etc. 33 | #undef WINAPI_PARTITION_DESKTOP 34 | #define WINAPI_PARTITION_DESKTOP 1 35 | #endif 36 | 37 | #ifndef NOMINMAX 38 | #define NOMINMAX 39 | #endif // !NOMINMAX 40 | 41 | #ifndef WIN32_LEAN_AND_MEAN 42 | #define WIN32_LEAN_AND_MEAN 43 | #endif // !WIN32_LEAN_AND_MEAN 44 | 45 | #include 46 | 47 | #endif // XR_USE_PLATFORM_WIN32 48 | 49 | #ifdef XR_USE_GRAPHICS_API_D3D11 50 | #include 51 | #endif // XR_USE_GRAPHICS_API_D3D11 52 | 53 | #ifdef XR_USE_GRAPHICS_API_D3D12 54 | #include 55 | #endif // XR_USE_GRAPHICS_API_D3D12 56 | 57 | #ifdef XR_USE_PLATFORM_XLIB 58 | #include 59 | #include 60 | 61 | #ifdef Success 62 | #undef Success 63 | #endif // Success 64 | 65 | #ifdef Always 66 | #undef Always 67 | #endif // Always 68 | 69 | #ifdef None 70 | #undef None 71 | #endif // None 72 | #endif // XR_USE_PLATFORM_XLIB 73 | 74 | #ifdef XR_USE_PLATFORM_XCB 75 | #include 76 | #endif // XR_USE_PLATFORM_XCB 77 | 78 | #ifdef XR_USE_GRAPHICS_API_OPENGL 79 | #if defined(XR_USE_PLATFORM_XLIB) || defined(XR_USE_PLATFORM_XCB) 80 | #include 81 | #endif // (XR_USE_PLATFORM_XLIB || XR_USE_PLATFORM_XCB) 82 | #ifdef XR_USE_PLATFORM_XCB 83 | #include 84 | #endif // XR_USE_PLATFORM_XCB 85 | #ifdef XR_USE_PLATFORM_MACOS 86 | #include 87 | #endif // XR_USE_PLATFORM_MACOS 88 | #endif // XR_USE_GRAPHICS_API_OPENGL 89 | 90 | #ifdef XR_USE_GRAPHICS_API_OPENGL_ES 91 | #include 92 | #endif // XR_USE_GRAPHICS_API_OPENGL_ES 93 | 94 | #ifdef XR_USE_GRAPHICS_API_VULKAN 95 | #include 96 | #endif // XR_USE_GRAPHICS_API_VULKAN 97 | 98 | #ifdef XR_USE_PLATFORM_WAYLAND 99 | #include "wayland-client.h" 100 | #endif // XR_USE_PLATFORM_WAYLAND 101 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/openxr/openxr_pico.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file openxr_pico_ext.h 3 | * @brief this header lists the openxr extensions defined by Pico 4 | * which haven't join in the openxr registery yet. 5 | * @version 0.1 6 | * 7 | * @copyright Copyright (c) 2022 8 | * 9 | */ 10 | 11 | #ifndef OPENXR_PICO_H_ 12 | #define OPENXR_PICO_H_ 1 13 | 14 | #if defined(__cplusplus) 15 | extern "C" { 16 | #endif 17 | 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // OPENXR_PICO_H_ -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/openxr/openxr_platform_defines.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** Copyright (c) 2017-2022, The Khronos Group Inc. 3 | ** 4 | ** SPDX-License-Identifier: Apache-2.0 OR MIT 5 | */ 6 | 7 | #ifndef OPENXR_PLATFORM_DEFINES_H_ 8 | #define OPENXR_PLATFORM_DEFINES_H_ 1 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /* Platform-specific calling convention macros. 15 | * 16 | * Platforms should define these so that OpenXR clients call OpenXR functions 17 | * with the same calling conventions that the OpenXR implementation expects. 18 | * 19 | * XRAPI_ATTR - Placed before the return type in function declarations. 20 | * Useful for C++11 and GCC/Clang-style function attribute syntax. 21 | * XRAPI_CALL - Placed after the return type in function declarations. 22 | * Useful for MSVC-style calling convention syntax. 23 | * XRAPI_PTR - Placed between the '(' and '*' in function pointer types. 24 | * 25 | * Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void); 26 | * Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void); 27 | */ 28 | #if defined(_WIN32) 29 | #define XRAPI_ATTR 30 | // On Windows, functions use the stdcall convention 31 | #define XRAPI_CALL __stdcall 32 | #define XRAPI_PTR XRAPI_CALL 33 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7 34 | #error "API not supported for the 'armeabi' NDK ABI" 35 | #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE) 36 | // On Android 32-bit ARM targets, functions use the "hardfloat" 37 | // calling convention, i.e. float parameters are passed in registers. This 38 | // is true even if the rest of the application passes floats on the stack, 39 | // as it does by default when compiling for the armeabi-v7a NDK ABI. 40 | #define XRAPI_ATTR __attribute__((pcs("aapcs-vfp"))) 41 | #define XRAPI_CALL 42 | #define XRAPI_PTR XRAPI_ATTR 43 | #else 44 | // On other platforms, use the default calling convention 45 | #define XRAPI_ATTR 46 | #define XRAPI_CALL 47 | #define XRAPI_PTR 48 | #endif 49 | 50 | #include 51 | 52 | #if !defined(XR_NO_STDINT_H) 53 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 54 | typedef signed __int8 int8_t; 55 | typedef unsigned __int8 uint8_t; 56 | typedef signed __int16 int16_t; 57 | typedef unsigned __int16 uint16_t; 58 | typedef signed __int32 int32_t; 59 | typedef unsigned __int32 uint32_t; 60 | typedef signed __int64 int64_t; 61 | typedef unsigned __int64 uint64_t; 62 | #else 63 | #include 64 | #endif 65 | #endif // !defined( XR_NO_STDINT_H ) 66 | 67 | // XR_PTR_SIZE (in bytes) 68 | #if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)) 69 | #define XR_PTR_SIZE 8 70 | #else 71 | #define XR_PTR_SIZE 4 72 | #endif 73 | 74 | // Needed so we can use clang __has_feature portably. 75 | #if !defined(XR_COMPILER_HAS_FEATURE) 76 | #if defined(__clang__) 77 | #define XR_COMPILER_HAS_FEATURE(x) __has_feature(x) 78 | #else 79 | #define XR_COMPILER_HAS_FEATURE(x) 0 80 | #endif 81 | #endif 82 | 83 | // Identifies if the current compiler has C++11 support enabled. 84 | // Does not by itself identify if any given C++11 feature is present. 85 | #if !defined(XR_CPP11_ENABLED) && defined(__cplusplus) 86 | #if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) 87 | #define XR_CPP11_ENABLED 1 88 | #elif defined(_MSC_VER) && (_MSC_VER >= 1600) 89 | #define XR_CPP11_ENABLED 1 90 | #elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. 91 | #define XR_CPP11_ENABLED 1 92 | #endif 93 | #endif 94 | 95 | // Identifies if the current compiler supports C++11 nullptr. 96 | #if !defined(XR_CPP_NULLPTR_SUPPORTED) 97 | #if defined(XR_CPP11_ENABLED) && \ 98 | ((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \ 99 | (defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \ 100 | (defined(_MSC_VER) && (_MSC_VER >= 1600)) || \ 101 | (defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) 102 | #define XR_CPP_NULLPTR_SUPPORTED 1 103 | #endif 104 | #endif 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/utils/nanoseconds.h: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================================ 3 | 4 | Description : Time in nanoseconds. 5 | Author : J.M.P. van Waveren 6 | Date : 12/10/2016 7 | Language : C99 8 | Format : Real tabs with the tab size equal to 4 spaces. 9 | Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. 10 | 11 | 12 | LICENSE 13 | ======= 14 | 15 | Copyright (c) 2016 Oculus VR, LLC. 16 | 17 | SPDX-License-Identifier: Apache-2.0 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | 31 | ================================================================================================ 32 | */ 33 | 34 | #if !defined( KSNANOSECONDS_H ) 35 | #define KSNANOSECONDS_H 36 | 37 | #if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) 38 | #if !defined( OS_WINDOWS ) 39 | #define OS_WINDOWS 40 | #endif 41 | #elif defined( __ANDROID__ ) 42 | #if !defined( OS_ANDROID ) 43 | #define OS_ANDROID 44 | #endif 45 | #elif defined( __hexagon__ ) || defined( __qdsp6__ ) 46 | #if !defined( OS_HEXAGON ) 47 | #define OS_HEXAGON 48 | #endif 49 | #elif defined( __APPLE__ ) 50 | #if !defined( OS_APPLE ) 51 | #define OS_APPLE 52 | #endif 53 | #include 54 | #if __IPHONE_OS_VERSION_MAX_ALLOWED && !defined( OS_APPLE_IOS ) 55 | #define OS_APPLE_IOS 56 | #elif __MAC_OS_X_VERSION_MAX_ALLOWED && !defined( OS_APPLE_MACOS ) 57 | #define OS_APPLE_MACOS 58 | #endif 59 | #elif defined( __linux__ ) 60 | #if !defined( OS_LINUX ) 61 | #define OS_LINUX 62 | #endif 63 | #else 64 | #error "unknown platform" 65 | #endif 66 | 67 | #if defined( OS_WINDOWS ) 68 | #include 69 | #elif defined( OS_LINUX ) 70 | #include // for timespec 71 | #include // for gettimeofday() 72 | #elif defined( OS_APPLE ) 73 | #include 74 | #elif defined( OS_ANDROID ) 75 | #include 76 | #elif defined( OS_HEXAGON ) 77 | #include 78 | #endif 79 | 80 | #include 81 | 82 | typedef uint64_t ksNanoseconds; 83 | 84 | static ksNanoseconds GetTimeNanoseconds() 85 | { 86 | #if defined( OS_WINDOWS ) 87 | static ksNanoseconds ticksPerSecond = 0; 88 | static ksNanoseconds timeBase = 0; 89 | 90 | if ( ticksPerSecond == 0 ) 91 | { 92 | LARGE_INTEGER li; 93 | QueryPerformanceFrequency( &li ); 94 | ticksPerSecond = (ksNanoseconds) li.QuadPart; 95 | QueryPerformanceCounter( &li ); 96 | timeBase = (ksNanoseconds) li.LowPart + 0xFFFFFFFFULL * li.HighPart; 97 | } 98 | 99 | LARGE_INTEGER li; 100 | QueryPerformanceCounter( &li ); 101 | ksNanoseconds counter = (ksNanoseconds) li.LowPart + 0xFFFFFFFFULL * li.HighPart; 102 | return ( counter - timeBase ) * 1000ULL * 1000ULL * 1000ULL / ticksPerSecond; 103 | #elif defined( OS_ANDROID ) 104 | static ksNanoseconds timeBase = 0; 105 | 106 | struct timespec ts; 107 | clock_gettime( CLOCK_MONOTONIC, &ts ); 108 | 109 | if ( timeBase == 0 ) 110 | { 111 | timeBase = (ksNanoseconds) ts.tv_sec * 1000ULL * 1000ULL * 1000ULL + ts.tv_nsec; 112 | } 113 | 114 | return (ksNanoseconds) ts.tv_sec * 1000ULL * 1000ULL * 1000ULL + ts.tv_nsec - timeBase; 115 | #elif defined( OS_HEXAGON ) 116 | return QURT_TIMER_TIMETICK_TO_US( qurt_timer_get_ticks() ) * 1000; 117 | #else 118 | static ksNanoseconds timeBase = 0; 119 | 120 | struct timeval tv; 121 | gettimeofday( &tv, 0 ); 122 | 123 | if ( timeBase == 0 ) 124 | { 125 | timeBase = (ksNanoseconds) tv.tv_sec * 1000ULL * 1000ULL * 1000ULL + tv.tv_usec * 1000ULL; 126 | } 127 | 128 | return (ksNanoseconds) tv.tv_sec * 1000ULL * 1000ULL * 1000ULL + tv.tv_usec * 1000ULL - timeBase; 129 | #endif 130 | } 131 | 132 | #endif // !KSNANOSECONDS_H 133 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/openxr_loader/include/utils/sysinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ================================================================================================ 3 | 4 | Description : Basic system info. 5 | Author : J.M.P. van Waveren 6 | Date : 12/10/2016 7 | Language : C99 8 | Format : Real tabs with the tab size equal to 4 spaces. 9 | Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved. 10 | 11 | 12 | LICENSE 13 | ======= 14 | 15 | Copyright (c) 2016 Oculus VR, LLC. 16 | 17 | SPDX-License-Identifier: Apache-2.0 18 | 19 | Licensed under the Apache License, Version 2.0 (the "License"); 20 | you may not use this file except in compliance with the License. 21 | You may obtain a copy of the License at 22 | 23 | http://www.apache.org/licenses/LICENSE-2.0 24 | 25 | Unless required by applicable law or agreed to in writing, software 26 | distributed under the License is distributed on an "AS IS" BASIS, 27 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 | See the License for the specific language governing permissions and 29 | limitations under the License. 30 | 31 | ================================================================================================ 32 | */ 33 | 34 | #if !defined( KSSYSINFO_H ) 35 | #define KSSYSINFO_H 36 | 37 | #if defined( WIN32 ) || defined( _WIN32 ) || defined( WIN64 ) || defined( _WIN64 ) 38 | #if !defined( OS_WINDOWS ) 39 | #define OS_WINDOWS 40 | #endif 41 | #elif defined( __ANDROID__ ) 42 | #if !defined( OS_ANDROID ) 43 | #define OS_ANDROID 44 | #endif 45 | #elif defined( __hexagon__ ) || defined( __qdsp6__ ) 46 | #if !defined( OS_HEXAGON ) 47 | #define OS_HEXAGON 48 | #endif 49 | #elif defined( __APPLE__ ) 50 | #if !defined( OS_APPLE ) 51 | #define OS_APPLE 52 | #endif 53 | #include 54 | #if __IPHONE_OS_VERSION_MAX_ALLOWED && !defined( OS_APPLE_IOS ) 55 | #define OS_APPLE_IOS 56 | #elif __MAC_OS_X_VERSION_MAX_ALLOWED && !defined( OS_APPLE_MACOS ) 57 | #define OS_APPLE_MACOS 58 | #endif 59 | #elif defined( __linux__ ) 60 | #if !defined( OS_LINUX ) 61 | #define OS_LINUX 62 | #endif 63 | #else 64 | #error "unknown platform" 65 | #endif 66 | 67 | #if defined( OS_WINDOWS ) 68 | #include 69 | #elif defined( OS_APPLE ) 70 | #include 71 | #include 72 | #elif defined( OS_ANDROID ) 73 | #include // for dlopen 74 | #endif 75 | 76 | #include 77 | 78 | static const char * GetOSVersion() 79 | { 80 | #if defined( OS_WINDOWS ) 81 | HKEY hKey = 0; 82 | if ( RegOpenKeyA( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", &hKey ) == ERROR_SUCCESS ) 83 | { 84 | static char version[1024]; 85 | DWORD version_length = sizeof( version ); 86 | DWORD dwType = REG_SZ; 87 | DWORD dwRet = RegQueryValueExA( hKey, "ProductName", NULL, &dwType, (LPBYTE)&version, &version_length ); 88 | RegCloseKey( hKey ); 89 | if ( dwRet == ERROR_SUCCESS ) 90 | { 91 | return version; 92 | } 93 | } 94 | return "Microsoft Windows"; 95 | #elif defined( OS_LINUX ) 96 | static char buffer[1024]; 97 | 98 | FILE * os_release = fopen( "/etc/os-release", "r" ); 99 | if ( os_release != NULL ) 100 | { 101 | while ( fgets( buffer, sizeof( buffer ), os_release ) ) 102 | { 103 | if ( strncmp( buffer, "PRETTY_NAME=", 12 ) == 0 ) 104 | { 105 | char * pretty_name = buffer + 12; 106 | 107 | // remove newline and enclosing quotes 108 | while( pretty_name[0] == ' ' || 109 | pretty_name[0] == '\t' || 110 | pretty_name[0] == ':' || 111 | pretty_name[0] == '\'' || 112 | pretty_name[0] == '\"' ) 113 | { 114 | pretty_name++; 115 | } 116 | int last = strlen( pretty_name ) - 1; 117 | while( last >= 0 && ( 118 | pretty_name[last] == '\n' || 119 | pretty_name[last] == '\'' || 120 | pretty_name[last] == '\"' ) ) 121 | { 122 | pretty_name[last--] = '\0'; 123 | } 124 | return pretty_name; 125 | } 126 | } 127 | 128 | fclose( os_release ); 129 | } 130 | 131 | return "Linux"; 132 | #elif defined( OS_APPLE_MACOS ) 133 | return [NSString stringWithFormat: @"Apple macOS %@", NSProcessInfo.processInfo.operatingSystemVersionString].UTF8String; 134 | #elif defined( OS_APPLE_IOS ) 135 | return [NSString stringWithFormat: @"Apple iOS %@", NSProcessInfo.processInfo.operatingSystemVersionString].UTF8String; 136 | #elif defined( OS_ANDROID ) 137 | static char version[1024]; 138 | 139 | #define PROP_NAME_MAX 32 140 | #define PROP_VALUE_MAX 92 141 | 142 | char release[PROP_VALUE_MAX] = { 0 }; 143 | char build[PROP_VALUE_MAX] = { 0 }; 144 | 145 | void * handle = dlopen( "libc.so", RTLD_NOLOAD ); 146 | if ( handle != NULL ) 147 | { 148 | typedef int (*PFN_SYSTEM_PROP_GET)(const char *, char *); 149 | PFN_SYSTEM_PROP_GET __my_system_property_get = (PFN_SYSTEM_PROP_GET)dlsym( handle, "__system_property_get" ); 150 | if ( __my_system_property_get != NULL ) 151 | { 152 | __my_system_property_get( "ro.build.version.release", release ); 153 | __my_system_property_get( "ro.build.version.incremental", build ); 154 | } 155 | } 156 | 157 | snprintf( version, sizeof( version ), "Android %s (%s)", release, build ); 158 | 159 | return version; 160 | #endif 161 | } 162 | 163 | static const char * GetCPUVersion() 164 | { 165 | #if defined( OS_WINDOWS ) 166 | HKEY hKey = 0; 167 | if ( RegOpenKeyA( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &hKey ) == ERROR_SUCCESS ) 168 | { 169 | static char processor[1024]; 170 | DWORD processor_length = sizeof( processor ); 171 | DWORD dwType = REG_SZ; 172 | DWORD dwRet = RegQueryValueExA( hKey, "ProcessorNameString", NULL, &dwType, (LPBYTE)&processor, &processor_length ); 173 | RegCloseKey( hKey ); 174 | if ( dwRet == ERROR_SUCCESS ) 175 | { 176 | return processor; 177 | } 178 | } 179 | return "unknown"; 180 | #elif defined( OS_APPLE ) 181 | static char processor[1024]; 182 | size_t processor_length = sizeof( processor ); 183 | sysctlbyname( "machdep.cpu.brand_string", &processor, &processor_length, NULL, 0 ); 184 | return processor; 185 | #elif defined( OS_LINUX ) || defined( OS_ANDROID ) 186 | struct 187 | { 188 | const char * key; 189 | char value[1024]; 190 | } keyValues[] = 191 | { 192 | { "model name", "" }, 193 | { "Processor", "" }, 194 | { "Hardware", "" } 195 | }; 196 | static char name[1024]; 197 | 198 | FILE * cpuinfo = fopen( "/proc/cpuinfo", "r" ); 199 | if ( cpuinfo != NULL ) 200 | { 201 | char buffer[1024]; 202 | while ( fgets( buffer, sizeof( buffer ), cpuinfo ) ) 203 | { 204 | for ( int i = 0; i < (int)( sizeof( keyValues ) / sizeof( keyValues[0] ) ); i++ ) 205 | { 206 | const size_t length = strlen( keyValues[i].key ); 207 | if ( strncmp( buffer, keyValues[i].key, length ) == 0 ) 208 | { 209 | char * pretty_name = buffer + length; 210 | 211 | // remove newline and enclosing quotes 212 | while( pretty_name[0] == ' ' || 213 | pretty_name[0] == '\t' || 214 | pretty_name[0] == ':' || 215 | pretty_name[0] == '\'' || 216 | pretty_name[0] == '\"' ) 217 | { 218 | pretty_name++; 219 | } 220 | int last = strlen( pretty_name ) - 1; 221 | while( last >= 0 && ( 222 | pretty_name[last] == '\n' || 223 | pretty_name[last] == '\'' || 224 | pretty_name[last] == '\"' ) ) 225 | { 226 | pretty_name[last--] = '\0'; 227 | } 228 | 229 | strcpy( keyValues[i].value, pretty_name ); 230 | break; 231 | } 232 | } 233 | } 234 | 235 | fclose( cpuinfo ); 236 | 237 | snprintf( name, sizeof(name), "%s%s%s", keyValues[2].value, 238 | ( keyValues[2].value[0] != '\0' ) ? " - " : "", 239 | ( keyValues[0].value[0] != '\0' ) ? keyValues[0].value : keyValues[1].value ); 240 | return name; 241 | } 242 | return "unknown"; 243 | #endif 244 | } 245 | 246 | #endif // !KSSYSINFO_H 247 | -------------------------------------------------------------------------------- /OpenXR/Sample/VideoPlayer/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name='OpenXR_VideoPlayer_Demo' 2 | include ':app' 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## OpenXR_VideoPlayer_Demo 2 | - If you have any questions/comments, please visit [**Pico Developer Support Portal**](https://picodevsupport.freshdesk.com/support/home) and raise your question there. 3 | 4 | ## OpenXR SDK Version 5 | - v2.1.0 6 | 7 | ## Description 8 | - This demo shows how to implement 360, 3D-SBS, 3D-OU, 2D VR video player with Pico OpenXR SDK use OpenGLES and Vulkan. 9 | - Fully use Android NDK C++, no java code. 10 | - Use AMediaCodec to decode. 11 | - Rendering yuv-nv12 with OpenGLES and vulkan. 12 | 13 | ## Usage 14 | - Scene: 3D-side-by-side(3D-SBS) 15 | Demo of VR video player for 3D side-by-side (left-right) video format. 16 | 17 | - Scene: 3D-OverUnder(3D-OU) 18 | Demo of VR video player for 3D over under (over-under) video format. 19 | 20 | - Scene: 360 21 | Demo of VR video player for 360 video format. 22 | 23 | - Scene: 2D 24 | Demo of VR video player for 2D video format. 25 | 26 | ### How select video mode and Specify video file name 27 | In the `cpp/app/options.h` file `VideoMode` field indicates videomode and `VideoFileName` indicates the video file used to playback. GraphicsPlugin filed indicates what rendering API to use, you can specify `OpenGLES` or `Vulkan2`. 28 | 29 | ## Note 30 | For more OpenXR demos, please go here [**OpenXR demo all in one**](https://github.com/picoxr/OpenXR_Demos). 31 | --------------------------------------------------------------------------------