Path: blob/master/thirdparty/openxr/src/loader/loader_logger.cpp
20852 views
// Copyright (c) 2017-2025 The Khronos Group Inc.1// Copyright (c) 2017-2019 Valve Corporation2// Copyright (c) 2017-2019 LunarG, Inc.3//4// SPDX-License-Identifier: Apache-2.0 OR MIT5//6// Initial Author: Mark Young <[email protected]>7//89#include "loader_logger.hpp"1011#include "extra_algorithms.h"12#include "hex_and_handles.h"13#include "loader_logger_recorders.hpp"14#include "loader_properties.hpp"15#include "platform_utils.hpp"1617#include <openxr/openxr.h>1819#include <algorithm>20#include <iterator>21#include <memory>22#include <mutex>23#include <sstream>24#include <string>25#include <unordered_map>26#include <utility>27#include <vector>2829// For routing platform_utils.hpp messages into the LoaderLogger.30void LogPlatformUtilsError(const std::string& message) { LoaderLogger::LogErrorMessage("platform_utils", message); }3132bool LoaderLogRecorder::LogDebugUtilsMessage(XrDebugUtilsMessageSeverityFlagsEXT /*message_severity*/,33XrDebugUtilsMessageTypeFlagsEXT /*message_type*/,34const XrDebugUtilsMessengerCallbackDataEXT* /*callback_data*/) {35return false;36}3738// Utility functions for converting to/from XR_EXT_debug_utils values3940XrLoaderLogMessageSeverityFlags DebugUtilsSeveritiesToLoaderLogMessageSeverities(41XrDebugUtilsMessageSeverityFlagsEXT utils_severities) {42XrLoaderLogMessageSeverityFlags log_severities = 0UL;43if ((utils_severities & XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0u) {44log_severities |= XR_LOADER_LOG_MESSAGE_SEVERITY_VERBOSE_BIT;45}46if ((utils_severities & XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0u) {47log_severities |= XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT;48}49if ((utils_severities & XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0u) {50log_severities |= XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT;51}52if ((utils_severities & XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0u) {53log_severities |= XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT;54}55return log_severities;56}5758XrDebugUtilsMessageSeverityFlagsEXT LoaderLogMessageSeveritiesToDebugUtilsMessageSeverities(59XrLoaderLogMessageSeverityFlags log_severities) {60XrDebugUtilsMessageSeverityFlagsEXT utils_severities = 0UL;61if ((log_severities & XR_LOADER_LOG_MESSAGE_SEVERITY_VERBOSE_BIT) != 0u) {62utils_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;63}64if ((log_severities & XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT) != 0u) {65utils_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;66}67if ((log_severities & XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT) != 0u) {68utils_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;69}70if ((log_severities & XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT) != 0u) {71utils_severities |= XR_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;72}73return utils_severities;74}7576XrLoaderLogMessageTypeFlagBits DebugUtilsMessageTypesToLoaderLogMessageTypes(XrDebugUtilsMessageTypeFlagsEXT utils_types) {77XrLoaderLogMessageTypeFlagBits log_types = 0UL;78if ((utils_types & XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT) != 0u) {79log_types |= XR_LOADER_LOG_MESSAGE_TYPE_GENERAL_BIT;80}81if ((utils_types & XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT) != 0u) {82log_types |= XR_LOADER_LOG_MESSAGE_TYPE_SPECIFICATION_BIT;83}84if ((utils_types & XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0u) {85log_types |= XR_LOADER_LOG_MESSAGE_TYPE_PERFORMANCE_BIT;86}87return log_types;88}8990XrDebugUtilsMessageTypeFlagsEXT LoaderLogMessageTypesToDebugUtilsMessageTypes(XrLoaderLogMessageTypeFlagBits log_types) {91XrDebugUtilsMessageTypeFlagsEXT utils_types = 0UL;92if ((log_types & XR_LOADER_LOG_MESSAGE_TYPE_GENERAL_BIT) != 0u) {93utils_types |= XR_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;94}95if ((log_types & XR_LOADER_LOG_MESSAGE_TYPE_SPECIFICATION_BIT) != 0u) {96utils_types |= XR_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;97}98if ((log_types & XR_LOADER_LOG_MESSAGE_TYPE_PERFORMANCE_BIT) != 0u) {99utils_types |= XR_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;100}101return utils_types;102}103104LoaderLogger::LoaderLogger() {105std::string debug_string = LoaderProperty::Get("XR_LOADER_DEBUG");106107// Add an error logger by default so that we at least get errors out to std::cerr.108// Normally we enable stderr output. But if the XR_LOADER_DEBUG environment variable is109// present as "none" then we don't.110if (debug_string != "none") {111AddLogRecorder(MakeStdErrLoaderLogRecorder(nullptr));112#ifdef __ANDROID__113// Add a logcat logger by default.114AddLogRecorder(MakeLogcatLoaderLogRecorder());115#endif // __ANDROID__116}117118#ifdef _WIN32119// Add an debugger logger by default so that we at least get errors out to the debugger.120AddLogRecorder(MakeDebuggerLoaderLogRecorder(nullptr));121#endif122123// If the environment variable to enable loader debugging is set, then enable the124// appropriate logging out to std::cout.125if (!debug_string.empty()) {126XrLoaderLogMessageSeverityFlags debug_flags = {};127if (debug_string == "error") {128debug_flags = XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT;129} else if (debug_string == "warn") {130debug_flags = XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT | XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT;131} else if (debug_string == "info") {132debug_flags = XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT | XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT |133XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT;134} else if (debug_string == "all" || debug_string == "verbose") {135debug_flags = XR_LOADER_LOG_MESSAGE_SEVERITY_ERROR_BIT | XR_LOADER_LOG_MESSAGE_SEVERITY_WARNING_BIT |136XR_LOADER_LOG_MESSAGE_SEVERITY_INFO_BIT | XR_LOADER_LOG_MESSAGE_SEVERITY_VERBOSE_BIT;137}138AddLogRecorder(MakeStdOutLoaderLogRecorder(nullptr, debug_flags));139}140}141142void LoaderLogger::AddLogRecorder(std::unique_ptr<LoaderLogRecorder>&& recorder) {143std::unique_lock<std::shared_timed_mutex> lock(_mutex);144_recorders.push_back(std::move(recorder));145}146147void LoaderLogger::AddLogRecorderForXrInstance(XrInstance instance, std::unique_ptr<LoaderLogRecorder>&& recorder) {148std::unique_lock<std::shared_timed_mutex> lock(_mutex);149_recordersByInstance[instance].insert(recorder->UniqueId());150_recorders.emplace_back(std::move(recorder));151}152153void LoaderLogger::RemoveLogRecorder(uint64_t unique_id) {154std::unique_lock<std::shared_timed_mutex> lock(_mutex);155vector_remove_if_and_erase(156_recorders, [=](std::unique_ptr<LoaderLogRecorder> const& recorder) { return recorder->UniqueId() == unique_id; });157for (auto& recorders : _recordersByInstance) {158auto& messengersForInstance = recorders.second;159if (messengersForInstance.count(unique_id) > 0) {160messengersForInstance.erase(unique_id);161}162}163}164165void LoaderLogger::RemoveLogRecordersForXrInstance(XrInstance instance) {166std::unique_lock<std::shared_timed_mutex> lock(_mutex);167if (_recordersByInstance.find(instance) != _recordersByInstance.end()) {168auto recorders = _recordersByInstance[instance];169vector_remove_if_and_erase(_recorders, [=](std::unique_ptr<LoaderLogRecorder> const& recorder) {170return recorders.find(recorder->UniqueId()) != recorders.end();171});172_recordersByInstance.erase(instance);173}174}175176bool LoaderLogger::LogMessage(XrLoaderLogMessageSeverityFlagBits message_severity, XrLoaderLogMessageTypeFlags message_type,177const std::string& message_id, const std::string& command_name, const std::string& message,178const std::vector<XrSdkLogObjectInfo>& objects) {179XrLoaderLogMessengerCallbackData callback_data = {};180callback_data.message_id = message_id.c_str();181callback_data.command_name = command_name.c_str();182callback_data.message = message.c_str();183184auto names_and_labels = data_.PopulateNamesAndLabels(objects);185callback_data.objects = names_and_labels.sdk_objects.empty() ? nullptr : names_and_labels.sdk_objects.data();186callback_data.object_count = static_cast<uint8_t>(names_and_labels.objects.size());187188callback_data.session_labels = names_and_labels.labels.empty() ? nullptr : names_and_labels.labels.data();189callback_data.session_labels_count = static_cast<uint8_t>(names_and_labels.labels.size());190191std::shared_lock<std::shared_timed_mutex> lock(_mutex);192bool exit_app = false;193for (std::unique_ptr<LoaderLogRecorder>& recorder : _recorders) {194if ((recorder->MessageSeverities() & message_severity) == message_severity &&195(recorder->MessageTypes() & message_type) == message_type) {196exit_app |= recorder->LogMessage(message_severity, message_type, &callback_data);197}198}199return exit_app;200}201202// Extension-specific logging functions203bool LoaderLogger::LogDebugUtilsMessage(XrDebugUtilsMessageSeverityFlagsEXT message_severity,204XrDebugUtilsMessageTypeFlagsEXT message_type,205const XrDebugUtilsMessengerCallbackDataEXT* callback_data) {206bool exit_app = false;207XrLoaderLogMessageSeverityFlags log_message_severity = DebugUtilsSeveritiesToLoaderLogMessageSeverities(message_severity);208XrLoaderLogMessageTypeFlags log_message_type = DebugUtilsMessageTypesToLoaderLogMessageTypes(message_type);209210AugmentedCallbackData augmented_data;211data_.WrapCallbackData(&augmented_data, callback_data);212213// Loop through the recorders214std::shared_lock<std::shared_timed_mutex> lock(_mutex);215for (std::unique_ptr<LoaderLogRecorder>& recorder : _recorders) {216// Only send the message if it's a debug utils recorder and of the type the recorder cares about.217if (recorder->Type() != XR_LOADER_LOG_DEBUG_UTILS ||218(recorder->MessageSeverities() & log_message_severity) != log_message_severity ||219(recorder->MessageTypes() & log_message_type) != log_message_type) {220continue;221}222223exit_app |= recorder->LogDebugUtilsMessage(message_severity, message_type, augmented_data.exported_data);224}225return exit_app;226}227228void LoaderLogger::AddObjectName(uint64_t object_handle, XrObjectType object_type, const std::string& object_name) {229data_.AddObjectName(object_handle, object_type, object_name);230}231232void LoaderLogger::BeginLabelRegion(XrSession session, const XrDebugUtilsLabelEXT* label_info) {233data_.BeginLabelRegion(session, *label_info);234}235236void LoaderLogger::EndLabelRegion(XrSession session) { data_.EndLabelRegion(session); }237238void LoaderLogger::InsertLabel(XrSession session, const XrDebugUtilsLabelEXT* label_info) {239data_.InsertLabel(session, *label_info);240}241242void LoaderLogger::DeleteSessionLabels(XrSession session) { data_.DeleteSessionLabels(session); }243244245