From f514b0571d7455def9e80641f71ed85087cf28d6 Mon Sep 17 00:00:00 2001 From: Fufu Fang Date: Tue, 23 Mar 2021 10:24:43 +0000 Subject: [PATCH] Creating logging mechanism for debugging Introduce a logging mechanism in the layer for replacing the old ones used in individual files. Change-Id: I7559f8a99396eeb0b9da6e5ef58cc4b7bd5a82af Signed-off-by: Fufu Fang --- CMakeLists.txt | 1 + util/log.cpp | 104 +++++++++++++++++++++++++++++ util/log.hpp | 67 +++++++++++++++++++ wsi/swapchain_base.cpp | 15 ++--- wsi/wayland/surface_properties.cpp | 7 +- wsi/wayland/swapchain.cpp | 52 ++++++++------- wsi/wayland/wl_helpers.cpp | 10 +-- wsi/wayland/wl_helpers.hpp | 7 -- 8 files changed, 213 insertions(+), 50 deletions(-) create mode 100644 util/log.cpp create mode 100644 util/log.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 95c6856..031142d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,7 @@ add_library(${PROJECT_NAME} SHARED util/timed_semaphore.cpp util/custom_allocator.cpp util/extension_list.cpp + util/log.cpp wsi/swapchain_base.cpp wsi/wsi_factory.cpp wsi/headless/surface_properties.cpp diff --git a/util/log.cpp b/util/log.cpp new file mode 100644 index 0000000..3e616f5 --- /dev/null +++ b/util/log.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "log.hpp" +#include +#include +#include +#include +#include +#include + +namespace util +{ + +#ifndef NDEBUG + +/** + * @brief check if a log level is enabled, and print it +*/ +static int check_and_print_log_level(int level) +{ + struct log_state + { + int level = WSI_DEFAULT_LOG_LEVEL; + log_state() + { + char *env = std::getenv("VULKAN_WSI_DEBUG_LEVEL"); + if (env != nullptr) + { + try + { + level = std::stoi(env); + } + catch (const std::exception &e) + { + std::fprintf(stderr, "Error: %s\n", e.what()); + } + } + } + }; + static log_state state; + + int result = level <= state.level; + if (result) + { + switch (level) + { + case 0: + /* Reserved for no logging */ + break; + case 1: + std::fprintf(stderr, "ERROR"); + break; + case 2: + std::fprintf(stderr, "WARNING"); + break; + case 3: + std::fprintf(stderr, "INFO"); + break; + default: + std::fprintf(stderr, "LEVEL_%d", level); + break; + } + } + return result; +} + +void wsi_log_message(int level, const char *file, int line, const char *format, ...) +{ + if (check_and_print_log_level(level)) + { + std::fprintf(stderr, "(%s:%d): ", file, line); + std::va_list args; + va_start(args, format); + std::vfprintf(stderr, format, args); + va_end(args); + std::putc('\n', stderr); + } +} + +#endif + +} /* namespace util */ \ No newline at end of file diff --git a/util/log.hpp b/util/log.hpp new file mode 100644 index 0000000..f77df9e --- /dev/null +++ b/util/log.hpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#pragma once +namespace util +{ +#define WSI_DEFAULT_LOG_LEVEL 1 + +/** + * @brief Log a message to a certain log level + * + * @details For the log level, we use a bigger integer to represent an increased + * level of verbosity. If this is not specified, the log level is default to 1. + * We use a "staircase" approach with respect to printing logs. We print all log + * messages equal or below the log level set, e.g. if VULKAN_WSI_DEBUG_LEVEL + * is set to 2, messages with log level 1 and 2 are printed. Please note that + * the newline character '\n' is automatically appended. + * + * @param[in] level The log level of this message, you can set an arbitary + * integer however please refer to the included macros for + * the sensible defaults. + * @param[in] file The source file name (``__FILE__``) + * @param[in] line The source file line number (``__LINE__``) + * @param[in] format A C-style formatting string. + */ + +void wsi_log_message(int level, const char *file, int line, const char *format, ...) +#ifdef __GNUC__ + __attribute__((format(printf, 4, 5))) +#endif + ; + +#ifdef NDEBUG +static constexpr bool wsi_log_enable = false; +#else +static constexpr bool wsi_log_enable = true; +#endif + +#define WSI_LOG(level, ...) \ + do { if (::util::wsi_log_enable) ::util::wsi_log_message(level, __FILE__, __LINE__, __VA_ARGS__); } while (0) + +#define WSI_LOG_ERROR(...) WSI_LOG(1, __VA_ARGS__) +#define WSI_LOG_WARNING(...) WSI_LOG(2, __VA_ARGS__) +#define WSI_LOG_INFO(...) WSI_LOG(3, __VA_ARGS__) + +} /* namespace util */ \ No newline at end of file diff --git a/wsi/swapchain_base.cpp b/wsi/swapchain_base.cpp index 33df950..2a40a57 100644 --- a/wsi/swapchain_base.cpp +++ b/wsi/swapchain_base.cpp @@ -40,14 +40,9 @@ #include #include +#include "util/log.hpp" + #include "swapchain_base.hpp" - -#if VULKAN_WSI_DEBUG > 0 -#define WSI_PRINT_ERROR(...) fprintf(stderr, ##__VA_ARGS__) -#else -#define WSI_PRINT_ERROR(...) (void)0 -#endif - namespace wsi { @@ -337,13 +332,13 @@ void swapchain_base::teardown() } else { - WSI_PRINT_ERROR("m_page_flip_thread is not joinable"); + WSI_LOG_ERROR("m_page_flip_thread is not joinable"); } res = sem_destroy(&m_start_present_semaphore); if (res != 0) { - WSI_PRINT_ERROR("sem_destroy failed for start_present_semaphore with %d\n", errno); + WSI_LOG_ERROR("sem_destroy failed for start_present_semaphore with %d", errno); } } @@ -598,6 +593,4 @@ VkResult swapchain_base::wait_for_free_buffer(uint64_t timeout) return retval; } -#undef WSI_PRINT_ERROR - } /* namespace wsi */ diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp index a1d254c..bec0655 100644 --- a/wsi/wayland/surface_properties.cpp +++ b/wsi/wayland/surface_properties.cpp @@ -37,6 +37,7 @@ #include "wl_helpers.hpp" #include "wl_object_owner.hpp" #include "util/drm/drm_utils.hpp" +#include "util/log.hpp" #define NELEMS(x) (sizeof(x) / sizeof(x[0])) @@ -144,7 +145,7 @@ static VkResult query_supported_formats( auto registry = registry_owner{wl_display_get_registry(display)}; if (registry.get() == nullptr) { - WSI_PRINT_ERROR("Failed to get wl display registry.\n"); + WSI_LOG_ERROR("Failed to get wl display registry."); return VK_ERROR_SURFACE_LOST_KHR; } @@ -153,7 +154,7 @@ static VkResult query_supported_formats( int res = wl_registry_add_listener(registry.get(), ®istry_listener, &dmabuf_interface); if (res < 0) { - WSI_PRINT_ERROR("Failed to add registry listener.\n"); + WSI_LOG_ERROR("Failed to add registry listener."); return VK_ERROR_SURFACE_LOST_KHR; } @@ -161,7 +162,7 @@ static VkResult query_supported_formats( res = wl_display_roundtrip(display); if (res < 0) { - WSI_PRINT_ERROR("Roundtrip failed.\n"); + WSI_LOG_ERROR("Roundtrip failed."); return VK_ERROR_SURFACE_LOST_KHR; } diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp index a2435af..cafc6a4 100644 --- a/wsi/wayland/swapchain.cpp +++ b/wsi/wayland/swapchain.cpp @@ -38,6 +38,7 @@ #include #include "util/drm/drm_utils.hpp" +#include "util/log.hpp" #define MAX_PLANES 4 @@ -103,7 +104,7 @@ swapchain::~swapchain() res = wsialloc_delete(&m_wsi_allocator); if (res != 0) { - WSI_PRINT_ERROR("error deleting the allocator: %d\n", res); + WSI_LOG_ERROR("error deleting the allocator: %d", res); } if (m_surface_queue != nullptr) { @@ -129,30 +130,31 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH m_surface = vk_surf->surface; m_surface_queue = wl_display_create_queue(m_display); + if (m_surface_queue == nullptr) { - WSI_PRINT_ERROR("Failed to create wl surface display_queue.\n"); + WSI_LOG_ERROR("Failed to create wl surface display_queue."); return VK_ERROR_INITIALIZATION_FAILED; } m_buffer_queue = wl_display_create_queue(m_display); if (m_buffer_queue == nullptr) { - WSI_PRINT_ERROR("Failed to create wl buffer display_queue.\n"); + WSI_LOG_ERROR("Failed to create wl buffer display_queue."); return VK_ERROR_INITIALIZATION_FAILED; } auto display_proxy = make_proxy_with_queue(m_display, m_surface_queue); if (display_proxy == nullptr) { - WSI_PRINT_ERROR("Failed to create wl display proxy.\n"); + WSI_LOG_ERROR("Failed to create wl display proxy."); return VK_ERROR_INITIALIZATION_FAILED; } auto registry = registry_owner{ wl_display_get_registry(display_proxy.get()) }; if (registry == nullptr) { - WSI_PRINT_ERROR("Failed to get wl display registry.\n"); + WSI_LOG_ERROR("Failed to get wl display registry."); return VK_ERROR_INITIALIZATION_FAILED; } @@ -160,14 +162,14 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH int res = wl_registry_add_listener(registry.get(), ®istry_listener, &m_dmabuf_interface); if (res < 0) { - WSI_PRINT_ERROR("Failed to add registry listener.\n"); + WSI_LOG_ERROR("Failed to add registry listener."); return VK_ERROR_INITIALIZATION_FAILED; } res = wl_display_roundtrip_queue(m_display, m_surface_queue); if (res < 0) { - WSI_PRINT_ERROR("Roundtrip failed.\n"); + WSI_LOG_ERROR("Roundtrip failed."); return VK_ERROR_INITIALIZATION_FAILED; } @@ -179,7 +181,7 @@ VkResult swapchain::init_platform(VkDevice device, const VkSwapchainCreateInfoKH res = wsialloc_new(-1, &m_wsi_allocator); if (res != 0) { - WSI_PRINT_ERROR("Failed to create wsi allocator.\n"); + WSI_LOG_ERROR("Failed to create wsi allocator."); return VK_ERROR_INITIALIZATION_FAILED; } @@ -232,7 +234,7 @@ VkResult swapchain::allocate_plane_memory(int fd, VkDeviceMemory *memory) const off_t dma_buf_size = lseek(fd, 0, SEEK_END); if (dma_buf_size < 0) { - WSI_PRINT_ERROR("Failed to get DMA Buf size.\n"); + WSI_LOG_ERROR("Failed to get DMA Buf size."); return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -252,7 +254,7 @@ VkResult swapchain::allocate_plane_memory(int fd, VkDeviceMemory *memory) if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Failed to import memory.\n"); + WSI_LOG_ERROR("Failed to import memory."); return result; } @@ -268,7 +270,7 @@ VkResult swapchain::get_fd_mem_type_index(int fd, uint32_t &mem_idx) m_device, VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, fd, &mem_props); if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Error querying Fd properties.\n"); + WSI_LOG_ERROR("Error querying Fd properties."); return result; } @@ -355,7 +357,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland result = get_drm_format_properties(image_create_info.format, drm_format_props); if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Failed to get format properties.\n"); + WSI_LOG_ERROR("Failed to get format properties."); return result; } auto is_disjoint = is_disjoint_supported(drm_format_props, modifier); @@ -393,25 +395,25 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland } if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Failed to get physical device format support.\n"); + WSI_LOG_ERROR("Failed to get physical device format support."); return result; } if (format_props.imageFormatProperties.maxExtent.width < image_create_info.extent.width || format_props.imageFormatProperties.maxExtent.height < image_create_info.extent.height || format_props.imageFormatProperties.maxExtent.depth < image_create_info.extent.depth) { - WSI_PRINT_ERROR("Physical device does not support required extent.\n"); + WSI_LOG_ERROR("Physical device does not support required extent."); return VK_ERROR_INITIALIZATION_FAILED; } if (format_props.imageFormatProperties.maxMipLevels < image_create_info.mipLevels || format_props.imageFormatProperties.maxArrayLayers < image_create_info.arrayLayers) { - WSI_PRINT_ERROR("Physical device does not support required array layers or mip levels.\n"); + WSI_LOG_ERROR("Physical device does not support required array layers or mip levels."); return VK_ERROR_INITIALIZATION_FAILED; } if ((format_props.imageFormatProperties.sampleCounts & image_create_info.samples) != image_create_info.samples) { - WSI_PRINT_ERROR("Physical device does not support required sample count.\n"); + WSI_LOG_ERROR("Physical device does not support required sample count."); return VK_ERROR_INITIALIZATION_FAILED; } @@ -422,7 +424,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland if (!(external_props.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR)) { - WSI_PRINT_ERROR("Export/Import not supported.\n"); + WSI_LOG_ERROR("Export/Import not supported."); return VK_ERROR_INITIALIZATION_FAILED; } else @@ -435,7 +437,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland image_data->stride, image_data->buffer_fd, image_data->offset, nullptr); if (res != 0) { - WSI_PRINT_ERROR("Failed allocation of DMA Buffer.\n"); + WSI_LOG_ERROR("Failed allocation of DMA Buffer."); return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -486,7 +488,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland } if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Image creation failed.\n"); + WSI_LOG_ERROR("Image creation failed."); return result; } { @@ -536,7 +538,7 @@ VkResult swapchain::allocate_image(VkImageCreateInfo &image_create_info, wayland { if (image_data->buffer_fd[plane] != image_data->buffer_fd[0]) { - WSI_PRINT_ERROR("Different fds per plane for a non disjoint image.\n"); + WSI_LOG_ERROR("Different fds per plane for a non disjoint image."); return VK_ERROR_INITIALIZATION_FAILED; } } @@ -569,7 +571,7 @@ VkResult swapchain::create_image(VkImageCreateInfo image_create_info, swapchain_ VkResult result = allocate_image(image_create_info, image_data, &image.image); if (result != VK_SUCCESS) { - WSI_PRINT_ERROR("Failed to allocate image.\n"); + WSI_LOG_ERROR("Failed to allocate image."); destroy_image(image); return result; } @@ -578,7 +580,7 @@ VkResult swapchain::create_image(VkImageCreateInfo image_create_info, swapchain_ auto dmabuf_interface_proxy = make_proxy_with_queue(m_dmabuf_interface.get(), m_surface_queue); if (dmabuf_interface_proxy == nullptr) { - WSI_PRINT_ERROR("Failed to allocate dma-buf interface proxy.\n"); + WSI_LOG_ERROR("Failed to allocate dma-buf interface proxy."); destroy_image(image); return VK_ERROR_INITIALIZATION_FAILED; } @@ -665,7 +667,7 @@ void swapchain::present_image(uint32_t pendingIndex) if (res <= 0) { - WSI_PRINT_ERROR("error waiting for Wayland compositor frame hint\n"); + WSI_LOG_ERROR("error waiting for Wayland compositor frame hint"); m_is_valid = false; /* try to present anyway */ } @@ -681,7 +683,7 @@ void swapchain::present_image(uint32_t pendingIndex) auto surface_proxy = make_proxy_with_queue(m_surface, m_surface_queue); if (surface_proxy == nullptr) { - WSI_PRINT_ERROR("failed to create wl_surface proxy\n"); + WSI_LOG_ERROR("failed to create wl_surface proxy"); m_is_valid = false; return; } @@ -717,7 +719,7 @@ void swapchain::present_image(uint32_t pendingIndex) res = wl_display_flush(m_display); if (res < 0) { - WSI_PRINT_ERROR("error flushing the display\n"); + WSI_LOG_ERROR("error flushing the display"); /* Setting the swapchain as invalid */ m_is_valid = false; } diff --git a/wsi/wayland/wl_helpers.cpp b/wsi/wayland/wl_helpers.cpp index a651250..1d453c2 100644 --- a/wsi/wayland/wl_helpers.cpp +++ b/wsi/wayland/wl_helpers.cpp @@ -32,6 +32,8 @@ #include "wl_object_owner.hpp" +#include "util/log.hpp" + struct formats_vector { util::vector *formats{nullptr}; @@ -78,7 +80,7 @@ VkResult get_supported_formats_and_modifiers( &drm_supported_formats); if (res < 0) { - WSI_PRINT_ERROR("Failed to add zwp_linux_dmabuf_v1 listener.\n"); + WSI_LOG_ERROR("Failed to add zwp_linux_dmabuf_v1 listener."); return VK_ERROR_UNKNOWN; } @@ -86,13 +88,13 @@ VkResult get_supported_formats_and_modifiers( res = wl_display_roundtrip(display); if (res < 0) { - WSI_PRINT_ERROR("Roundtrip failed.\n"); + WSI_LOG_ERROR("Roundtrip failed."); return VK_ERROR_UNKNOWN; } if (drm_supported_formats.is_out_of_memory) { - WSI_PRINT_ERROR("Host got out of memory.\n"); + WSI_LOG_ERROR("Host got out of memory."); return VK_ERROR_OUT_OF_HOST_MEMORY; } @@ -115,7 +117,7 @@ extern "C" { if (dmabuf_interface_obj == nullptr) { - WSI_PRINT_ERROR("Failed to get zwp_linux_dmabuf_v1 interface.\n"); + WSI_LOG_ERROR("Failed to get zwp_linux_dmabuf_v1 interface."); return; } diff --git a/wsi/wayland/wl_helpers.hpp b/wsi/wayland/wl_helpers.hpp index 3f0d55a..f1a6369 100644 --- a/wsi/wayland/wl_helpers.hpp +++ b/wsi/wayland/wl_helpers.hpp @@ -28,13 +28,6 @@ #include #include #include "util/custom_allocator.hpp" - -#if VULKAN_WSI_DEBUG > 0 -#define WSI_PRINT_ERROR(...) fprintf(stderr, __FILE__, __LINE__, __func__, ##__VA_ARGS__) -#else -#define WSI_PRINT_ERROR(...) (void)0 -#endif - struct drm_format_pair { uint32_t fourcc;