diff --git a/CMakeLists.txt b/CMakeLists.txt index 5079fcf..3529f7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,10 @@ set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_MODULE_STD 1) +add_compile_options( + -fstack-protector-strong + -fwrapv +) add_compile_definitions( WLR_USE_UNSTABLE XR_USE_PLATFORM_EGL @@ -16,6 +20,8 @@ add_compile_definitions( find_package(PkgConfig REQUIRED) +find_package(Boost REQUIRED) + pkg_check_modules(WAYLAND REQUIRED IMPORTED_TARGET GLOBAL wayland-server) pkg_check_modules(EGL REQUIRED IMPORTED_TARGET egl) pkg_check_modules(GLES2 REQUIRED IMPORTED_TARGET glesv2) @@ -44,6 +50,13 @@ set(PLATFORM DRM) set(BUILD_EXAMPLES OFF) FetchContent_MakeAvailable(raylib) +FetchContent_Declare( + cpptrace + GIT_REPOSITORY https://github.com/jeremy-rifkin/cpptrace.git + GIT_TAG v1.0.1 +) +FetchContent_MakeAvailable(cpptrace) + add_executable(${PROJECT_NAME}) target_sources(${PROJECT_NAME} PUBLIC src/main.cpp @@ -60,9 +73,17 @@ target_link_libraries(${PROJECT_NAME} PUBLIC PkgConfig::GLES2 PkgConfig::WLROOTS PkgConfig::OPENXR + + Boost::boost raylib + cpptrace::cpptrace ) +set_target_properties(${PROJECT_NAME} PROPERTIES + CXX_CLANG_TIDY "clang-tidy;-header-filter=^${CMAKE_SOURCE_DIR}/src/.*;-checks=*,-some-disabled-checks,misc-const-correctness,modernize-use-nullptr,bugprone-branch-clone,bugprone-use-after-move,performance-unnecessary-value-param,hicpp-no-malloc,cppcoreguidelines-pro-type-const-cast,clang-analyzer-core.NullDereference,-fuchsia-overloaded-operator,-readability-identifier-length,-bugprone-easily-swappable-parameters,-fuchsia-trailing-return,-misc-non-private-member-variables-in-classes,-readability-math-missing-parentheses,-llvmlibc-implementation-in-namespace,-misc-include-cleaner,-modernize-use-std-print,-llvmlibc-restrict-system-libc-headers,-fuchsia-statically-constructed-objects,-cppcoreguidelines-avoid-non-const-global-variables,-llvmlibc-callee-namespace,-misc-use-anonymous-namespace,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-hicpp-uppercase-literal-suffix,-readability-uppercase-literal-suffix,-fuchsia-default-arguments-calls,-altera-unroll-loops,-fuchsia-default-arguments-declarations,-readability-function-cognitive-complexity,-altera-struct-pack-align,-altera-id-dependent-backward-branch,-cppcoreguidelines-pro-type-reinterpret-cast,-boost-use-ranges,-cppcoreguidelines-owning-memory,-readability-redundant-declaration" +) + +# Wayland protocol codegen set(XDG_SHELL_XML ${WAYLAND_PROTOCOLS_DIR}/stable/xdg-shell/xdg-shell.xml ) diff --git a/flake.nix b/flake.nix index 9cfb168..9422fd4 100644 --- a/flake.nix +++ b/flake.nix @@ -60,6 +60,7 @@ xorg.libXi glfw + boost libffi wayland wayland-scanner diff --git a/src/LunarWM.cppm b/src/LunarWM.cppm index 6171c8e..5afba8a 100644 --- a/src/LunarWM.cppm +++ b/src/LunarWM.cppm @@ -1,5 +1,6 @@ module; +// NOLINTBEGIN #include #include @@ -11,6 +12,8 @@ module; #include #include +#include + #include #include #include @@ -32,6 +35,7 @@ extern "C" { #include #include #include +// NOLINTEND export module LunarWM.LunarWM; @@ -48,7 +52,7 @@ template<> struct formatter { return ctx.begin(); } - static constexpr std::string_view to_string(XrResult r) + static constexpr auto to_string(XrResult r) -> std::string_view { switch (r) { case XR_FRAME_DISCARDED: @@ -690,12 +694,15 @@ template<> struct formatter { template auto format(XrResult r, FmtCtx &ctx) const { - if (spec == 'd') + if (spec == 'd') { return format_to(ctx.out(), "{}", static_cast(r)); + } - std::string_view str = this->to_string(r); - if (!str.empty()) + std::string_view str + = std::__1::formatter::to_string(r); + if (!str.empty()) { return format_to(ctx.out(), "{}", str); + } return format_to(ctx.out(), "<0x{:x}>", static_cast(r)); } @@ -707,14 +714,14 @@ private: namespace LunarWM { -static Matrix xr_projection_matrix(XrFovf const &fov) +static auto xr_projection_matrix(XrFovf const &fov) -> Matrix { static_assert(RL_CULL_DISTANCE_FAR > RL_CULL_DISTANCE_NEAR); Matrix matrix {}; - float const near = (float)RL_CULL_DISTANCE_NEAR; - float const far = (float)RL_CULL_DISTANCE_FAR; + auto const near = static_cast(RL_CULL_DISTANCE_NEAR); + auto const far = static_cast(RL_CULL_DISTANCE_FAR); float const tan_angle_left = tanf(fov.angleLeft); float const tan_angle_right = tanf(fov.angleRight); @@ -748,16 +755,16 @@ static Matrix xr_projection_matrix(XrFovf const &fov) return matrix; } -static Matrix xr_matrix(XrPosef const &pose) +static auto xr_matrix(XrPosef const &pose) -> Matrix { - Matrix translation + Matrix const translation = MatrixTranslate(pose.position.x, pose.position.y, pose.position.z); - Matrix rotation = QuaternionToMatrix(Quaternion { pose.orientation.x, + Matrix const rotation = QuaternionToMatrix(Quaternion { pose.orientation.x, pose.orientation.y, pose.orientation.z, pose.orientation.w }); return rotation * translation; } -enum class SwapchainType { +enum class SwapchainType : std::uint8_t { Color, Depth, }; @@ -772,6 +779,12 @@ export struct LunarWM { LunarWM() = default; ~LunarWM(); + LunarWM(LunarWM const &) = delete; + auto operator=(LunarWM const &) -> LunarWM & = delete; + + LunarWM(LunarWM const &&) = delete; + auto operator=(LunarWM const &&) -> LunarWM & = delete; + void init(); void run(); @@ -784,7 +797,7 @@ private: void init_xr(); void poll_events_xr(); - bool render_layer(RenderLayerInfo &info, float dt); + auto render_layer(RenderLayerInfo &info, float dt) -> bool; void render_3d(float dt); bool m_initialized {}; @@ -802,19 +815,20 @@ private: struct Toplevel { Toplevel(Toplevel const &) = delete; - Toplevel &operator=(Toplevel const &) = delete; + auto operator=(Toplevel const &) -> Toplevel & = delete; Toplevel(Toplevel &&) = delete; - Toplevel &operator=(Toplevel &&) = delete; + auto operator=(Toplevel &&) -> Toplevel & = delete; Toplevel(LunarWM *srv, wlr_xdg_toplevel *xdg) : server(srv) , xdg_toplevel(xdg) + , surface(xdg->base->surface) { - surface = xdg->base->surface; + assert(surface); commit.notify = [](wl_listener *l, void *) { - auto tl = wl_container_of( + auto *tl = wl_container_of( l, static_cast(nullptr), commit); if (tl->xdg_toplevel->base->initial_commit) { @@ -826,12 +840,12 @@ private: wl_signal_add(&surface->events.commit, &commit); destroy.notify = [](wl_listener *l, void *) { - auto tl = wl_container_of(l, (Toplevel *)nullptr, destroy); + auto *tl = wl_container_of(l, (Toplevel *)nullptr, destroy); auto &vec = tl->server->m_wayland.toplevels; - vec.erase(std::remove_if(vec.begin(), vec.end(), - [tl](auto &p) { return p.get() == tl; }), - vec.end()); + auto const [first, last] = std::ranges::remove_if( + vec, [tl](auto &p) { return p.get() == tl; }); + vec.erase(first, last); }; wl_signal_add(&surface->events.destroy, &destroy); } @@ -840,11 +854,11 @@ private: { texture = wlr_surface_get_texture(surface); struct wlr_client_buffer *cl_buf = surface->buffer; - if (!texture || !cl_buf) { + if ((texture == nullptr) || (cl_buf == nullptr)) { return; } - if (locked_buffer && locked_buffer != &cl_buf->base) { + if ((locked_buffer != nullptr) && locked_buffer != &cl_buf->base) { wlr_buffer_unlock(locked_buffer); locked_buffer = nullptr; } @@ -854,13 +868,13 @@ private: wlr_gles2_texture_get_attribs(texture, &attribs); gles_texture = gles2_get_texture(texture); - if (!gles_texture) { + if (gles_texture == nullptr) { return; } - rl_texture.id = attribs.tex; - rl_texture.width = texture->width; - rl_texture.height = texture->height; + rl_texture.id = static_cast(attribs.tex); + rl_texture.width = static_cast(texture->width); + rl_texture.height = static_cast(texture->height); rl_texture.mipmaps = 1; rl_texture.format = gles_texture->has_alpha ? PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 @@ -874,7 +888,7 @@ private: { wl_list_remove(&commit.link); wl_list_remove(&destroy.link); - if (locked_buffer) { + if (locked_buffer != nullptr) { wlr_buffer_unlock(locked_buffer); } } @@ -909,9 +923,9 @@ private: wlr_renderer *renderer {}; wlr_egl *egl {}; - EGLDisplay egl_display; - EGLContext egl_context; - EGLConfig egl_config; + EGLDisplay egl_display {}; + EGLContext egl_context {}; + EGLConfig egl_config {}; wlr_allocator *allocator {}; wlr_compositor *compositor {}; @@ -919,10 +933,10 @@ private: wlr_data_device_manager *data_device_manager {}; wlr_seat *seat {}; - wl_list keyboards; + wl_list keyboards {}; wl_listener new_input_listener {}; - wlr_xdg_shell *xdg_shell; + wlr_xdg_shell *xdg_shell {}; wl_listener new_xdg_toplevel_listener {}; wl_listener new_xdg_popup_listener {}; @@ -947,12 +961,13 @@ private: swapchain_images_map; std::vector view_configuration_views; - XrEnvironmentBlendMode environment_blend_mode; + XrEnvironmentBlendMode environment_blend_mode {XR_ENVIRONMENT_BLEND_MODE_MAX_ENUM}; XrSpace local_space { XR_NULL_HANDLE }; XrSpace view_space { XR_NULL_HANDLE }; - std::uint32_t get_swapchain_image(XrSwapchain swapchain, uint32_t index) + auto get_swapchain_image(XrSwapchain swapchain, uint32_t index) + -> std::uint32_t { return swapchain_images_map[swapchain].second[index].image; } @@ -977,33 +992,36 @@ private: .projection = CAMERA_PERSPECTIVE, }; - bool begin_render(GLuint color_tex, GLuint depth_tex, uint32_t w, - uint32_t h, XrView const &view) + auto begin_render(GLuint color_tex, GLuint depth_tex, uint32_t w, + uint32_t h, XrView const &view) -> bool { - if (!fbo) // create once + if (fbo == 0u) { // create once glGenFramebuffers(1, &fbo); + } rlFramebufferAttach(fbo, color_tex, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); assert(rlFramebufferComplete(fbo)); glBindFramebuffer(GL_FRAMEBUFFER, fbo); - GLenum fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); + GLenum const fbStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (fbStatus != GL_FRAMEBUFFER_COMPLETE) { - printf("FBO incomplete: 0x%04x\n", fbStatus); + std::println("FBO incomplete: 0x{:04x}", fbStatus); return false; } tmp_rt = { .id = fbo, - .texture = { color_tex, (int)w, (int)h, 1, -1 }, - .depth = { depth_tex, (int)w, (int)h, 1, -1 } }; + .texture = { color_tex, static_cast(w), + static_cast(h), 1, -1 }, + .depth = { depth_tex, static_cast(w), static_cast(h), + 1, -1 } }; BeginTextureMode(tmp_rt); rlEnableStereoRender(); XrFovf const &fov = view.fov; - Matrix proj = xr_projection_matrix(fov); - Matrix viewM = MatrixInvert(xr_matrix(view.pose)); + Matrix const proj = xr_projection_matrix(fov); + Matrix const viewM = MatrixInvert(xr_matrix(view.pose)); rlSetMatrixProjectionStereo(proj, proj); rlSetMatrixViewOffsetStereo(viewM, viewM); @@ -1011,31 +1029,34 @@ private: return true; } - void end_render( - LunarWM &wm, SwapchainInfo &color_sc, SwapchainInfo *depth_sc) + static void end_render(LunarWM & /*wm*/, SwapchainInfo & /*color_sc*/, + SwapchainInfo * /*depth_sc*/) { rlDisableStereoRender(); EndTextureMode(); } - void update_camera(LunarWM &wm, Camera3D &camera, RenderLayerInfo &info) + static void update_camera( + LunarWM &wm, Camera3D &camera, RenderLayerInfo &info) { XrTime const time = info.predicted_display_time; XrSpaceLocation view_location { XR_TYPE_SPACE_LOCATION }; - XrResult result = xrLocateSpace( + XrResult const result = xrLocateSpace( wm.m_xr.view_space, wm.m_xr.local_space, time, &view_location); if (result != XR_SUCCESS) { return; } - if (view_location.locationFlags - & XR_SPACE_LOCATION_POSITION_VALID_BIT) { + if ((view_location.locationFlags + & XR_SPACE_LOCATION_POSITION_VALID_BIT) + != 0u) { auto const &pos = view_location.pose.position; camera.position = Vector3 { pos.x, pos.y, pos.z }; } - if (view_location.locationFlags - & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) { + if ((view_location.locationFlags + & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT) + != 0u) { auto const &rot = view_location.pose.orientation; auto const forward = Vector3RotateByQuaternion(Vector3 { 0, 0, -1 }, @@ -1070,8 +1091,8 @@ void LunarWM::init() this->init_wayland(); wlr_log(WLR_INFO, "0"); - auto draw = eglGetCurrentSurface(EGL_DRAW); - auto read = eglGetCurrentSurface(EGL_READ); + auto *draw = eglGetCurrentSurface(EGL_DRAW); + auto *read = eglGetCurrentSurface(EGL_READ); if (eglMakeCurrent(m_wayland.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, m_wayland.egl_context) == EGL_FALSE) { @@ -1086,7 +1107,7 @@ void LunarWM::init() InitWindow(0, 0, ""); wlr_log(WLR_INFO, "3"); - if (eglMakeCurrent(m_wayland.egl_display, read, draw, m_wayland.egl_context) + if (eglMakeCurrent(m_wayland.egl_display, draw, read, m_wayland.egl_context) == EGL_FALSE) { throw std::runtime_error("Failed to eglMakeCurrent"); } @@ -1096,31 +1117,31 @@ void LunarWM::init() void LunarWM::init_wayland() { - wlr_log_init(WLR_DEBUG, NULL); + wlr_log_init(WLR_DEBUG, nullptr); m_wayland.display = wl_display_create(); - if (!m_wayland.display) { + if (m_wayland.display == nullptr) { throw std::runtime_error("Failed to create wayland display"); } m_wayland.event_loop = wl_display_get_event_loop(m_wayland.display); - if (!m_wayland.event_loop) { + if (m_wayland.event_loop == nullptr) { throw std::runtime_error("Failed to get wayland event loop"); } m_wayland.backend = wlr_backend_autocreate(m_wayland.event_loop, nullptr); - if (!m_wayland.backend) { + if (m_wayland.backend == nullptr) { throw std::runtime_error("Failed to create wlroots backend"); } - setenv("WLR_RENDERER", "gles2", 1); + setenv("WLR_RENDERER", "gles2", 1); // NOLINT m_wayland.renderer = wlr_renderer_autocreate(m_wayland.backend); - if (!m_wayland.renderer) { + if (m_wayland.renderer == nullptr) { throw std::runtime_error("Failed to create wlroots renderer"); } m_wayland.egl = wlr_gles2_renderer_get_egl(m_wayland.renderer); - if (!m_wayland.egl) { + if (m_wayland.egl == nullptr) { throw std::runtime_error("Failed to get egl information from renderer"); } @@ -1135,24 +1156,24 @@ void LunarWM::init_wayland() m_wayland.allocator = wlr_allocator_autocreate(m_wayland.backend, m_wayland.renderer); - if (!m_wayland.allocator) { + if (m_wayland.allocator == nullptr) { throw std::runtime_error("Failed to create wlroots allocator"); } m_wayland.compositor = wlr_compositor_create(m_wayland.display, 5, m_wayland.renderer); - if (!m_wayland.compositor) { + if (m_wayland.compositor == nullptr) { throw std::runtime_error("Failed to create wlroots compositor"); } m_wayland.subcompositor = wlr_subcompositor_create(m_wayland.display); - if (!m_wayland.subcompositor) { + if (m_wayland.subcompositor == nullptr) { throw std::runtime_error("Failed to create wlroots subcompositor"); } m_wayland.data_device_manager = wlr_data_device_manager_create(m_wayland.display); - if (!m_wayland.data_device_manager) { + if (m_wayland.data_device_manager == nullptr) { throw std::runtime_error( "Failed to create wlroots data device manager"); } @@ -1163,77 +1184,74 @@ void LunarWM::init_wayland() m_wayland.new_input_listener.notify = [](wl_listener *listener, void *data) { - auto wm = reinterpret_cast(wl_container_of(listener, - static_cast(nullptr), m_wayland.new_input_listener)); - auto dev = reinterpret_cast(data); + auto *wm = wl_container_of(listener, static_cast(nullptr), + m_wayland.new_input_listener); + auto *dev = reinterpret_cast(data); if (dev->type == WLR_INPUT_DEVICE_KEYBOARD) { struct wlr_keyboard *wlr_keyboard = wlr_keyboard_from_input_device(dev); - Keyboard *keyboard = new Keyboard; + auto *keyboard = new Keyboard; keyboard->server = wm; keyboard->wlr_keyboard = wlr_keyboard; struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); struct xkb_keymap *keymap = xkb_keymap_new_from_names( - context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS); + context, nullptr, XKB_KEYMAP_COMPILE_NO_FLAGS); wlr_keyboard_set_keymap(wlr_keyboard, keymap); xkb_keymap_unref(keymap); xkb_context_unref(context); wlr_keyboard_set_repeat_info(wlr_keyboard, 25, 600); - keyboard->modifiers.notify - = [](struct wl_listener *listener, void *data) { - Keyboard *keyboard - = wl_container_of(listener, keyboard, modifiers); - wlr_seat_set_keyboard(keyboard->server->m_wayland.seat, - keyboard->wlr_keyboard); - wlr_seat_keyboard_notify_modifiers( - keyboard->server->m_wayland.seat, - &keyboard->wlr_keyboard->modifiers); - }; + keyboard->modifiers.notify = [](struct wl_listener *listener, + void * /*data*/) { + auto *kbd = wl_container_of(listener, keyboard, modifiers); + wlr_seat_set_keyboard( + kbd->server->m_wayland.seat, kbd->wlr_keyboard); + wlr_seat_keyboard_notify_modifiers( + kbd->server->m_wayland.seat, &kbd->wlr_keyboard->modifiers); + }; wl_signal_add( &wlr_keyboard->events.modifiers, &keyboard->modifiers); keyboard->key.notify = [](struct wl_listener *listener, void *data) { - Keyboard *keyboard = wl_container_of(listener, keyboard, key); - auto *server = keyboard->server; + auto *kbd = wl_container_of(listener, keyboard, key); + auto *server = kbd->server; auto *event = reinterpret_cast(data); struct wlr_seat *seat = server->m_wayland.seat; - uint32_t keycode = event->keycode + 8; - xkb_keysym_t const *syms; - int nsyms = xkb_state_key_get_syms( - keyboard->wlr_keyboard->xkb_state, keycode, &syms); + // uint32_t const keycode = event->keycode + 8; + xkb_keysym_t const *syms = nullptr; + // int const nsyms = xkb_state_key_get_syms( + // kbd->wlr_keyboard->xkb_state, keycode, &syms); - bool handled = false; - uint32_t modifiers - = wlr_keyboard_get_modifiers(keyboard->wlr_keyboard); + bool const handled = false; + uint32_t const modifiers + = wlr_keyboard_get_modifiers(kbd->wlr_keyboard); if ((modifiers & WLR_MODIFIER_LOGO) && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { - if (syms[XKB_KEY_Escape]) { - keyboard->server->terminate(); + if (syms[XKB_KEY_Escape]) { // NOLINT + kbd->server->terminate(); } } if (!handled) { - wlr_seat_set_keyboard(seat, keyboard->wlr_keyboard); + wlr_seat_set_keyboard(seat, kbd->wlr_keyboard); wlr_seat_keyboard_notify_key( seat, event->time_msec, event->keycode, event->state); } }; wl_signal_add(&wlr_keyboard->events.key, &keyboard->key); keyboard->destroy.notify - = [](struct wl_listener *listener, void *data) { - Keyboard *keyboard - = wl_container_of(listener, keyboard, destroy); - wl_list_remove(&keyboard->modifiers.link); - wl_list_remove(&keyboard->key.link); - wl_list_remove(&keyboard->destroy.link); - wl_list_remove(&keyboard->link); - free(keyboard); + = [](struct wl_listener *listener, void * /*data*/) { + auto *kbd = wl_container_of(listener, keyboard, destroy); + wl_list_remove(&kbd->modifiers.link); + wl_list_remove(&kbd->key.link); + wl_list_remove(&kbd->destroy.link); + wl_list_remove(&kbd->link); + free(kbd); // NOLINT }; wl_signal_add(&dev->events.destroy, &keyboard->destroy); @@ -1244,7 +1262,7 @@ void LunarWM::init_wayland() wlr_cursor_attach_input_device(wm->m_wayland.cursor, dev); } - std::uint32_t caps = WL_SEAT_CAPABILITY_POINTER; + std::uint32_t caps { WL_SEAT_CAPABILITY_POINTER }; if (!wl_list_empty(&wm->m_wayland.keyboards)) { caps |= WL_SEAT_CAPABILITY_KEYBOARD; } @@ -1254,7 +1272,7 @@ void LunarWM::init_wayland() wl_signal_add( &m_wayland.backend->events.new_input, &m_wayland.new_input_listener); m_wayland.seat = wlr_seat_create(m_wayland.display, "seat0"); - if (!m_wayland.seat) { + if (m_wayland.seat == nullptr) { throw std::runtime_error("Failed to create wlroots seat"); } @@ -1262,10 +1280,10 @@ void LunarWM::init_wayland() m_wayland.new_xdg_toplevel_listener.notify = [](wl_listener *listener, void *data) { - LunarWM *server - = wl_container_of(listener, static_cast(nullptr), - m_wayland.new_xdg_toplevel_listener); - auto toplevel = reinterpret_cast(data); + auto *server + { wl_container_of(listener, static_cast(nullptr), + m_wayland.new_xdg_toplevel_listener) }; + auto *toplevel { reinterpret_cast(data) }; if (toplevel->title) { wlr_log(WLR_INFO, "Got XDG toplevel title: %s", toplevel->title); @@ -1280,11 +1298,12 @@ void LunarWM::init_wayland() wl_signal_add(&m_wayland.xdg_shell->events.new_toplevel, &m_wayland.new_xdg_toplevel_listener); - m_wayland.new_xdg_popup_listener.notify = [](wl_listener *listener, - void *data) { - LunarWM *server = wl_container_of(listener, - static_cast(nullptr), m_wayland.new_xdg_popup_listener); - }; + m_wayland.new_xdg_popup_listener.notify + = [](wl_listener * /*listener*/, void * /*data*/) { + // auto *server = wl_container_of(listener, + // static_cast(nullptr), + // m_wayland.new_xdg_popup_listener); + }; wl_signal_add(&m_wayland.xdg_shell->events.new_popup, &m_wayland.new_xdg_popup_listener); } @@ -1296,19 +1315,21 @@ void LunarWM::init_xr() .engineVersion = 1, .apiVersion = XR_CURRENT_API_VERSION, }; - strncpy(app_info.applicationName, "LunarWM", XR_MAX_APPLICATION_NAME_SIZE); - strncpy(app_info.engineName, "LunarWM Engine", XR_MAX_ENGINE_NAME_SIZE); + strncpy(static_cast(app_info.applicationName), "LunarWM", + XR_MAX_APPLICATION_NAME_SIZE); + strncpy(static_cast(app_info.engineName), "LunarWM Engine", + XR_MAX_ENGINE_NAME_SIZE); std::vector instance_extensions { XR_EXT_DEBUG_UTILS_EXTENSION_NAME, XR_MNDX_EGL_ENABLE_EXTENSION_NAME, XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME, }; - std::vector apiLayers; + std::vector const apiLayers; std::vector active_instance_extensions; std::vector activeAPILayers; - uint32_t apiLayerCount = 0; + uint32_t apiLayerCount {}; std::vector apiLayerProperties; if (xrEnumerateApiLayerProperties(0, &apiLayerCount, nullptr) != XR_SUCCESS) { @@ -1321,18 +1342,19 @@ void LunarWM::init_xr() throw std::runtime_error("Failed to enumerate API layer properties"); } - for (auto &requestLayer : apiLayers) { - for (auto &layerProperty : apiLayerProperties) { - if (strcmp(requestLayer.c_str(), layerProperty.layerName) != 0) { + for (auto const &requestLayer : apiLayers) { + for (auto const &layerProperty : apiLayerProperties) { + if (strcmp(requestLayer.c_str(), + static_cast(layerProperty.layerName)) + != 0) { continue; - } else { - activeAPILayers.push_back(requestLayer.c_str()); - break; } + activeAPILayers.push_back(requestLayer.c_str()); + break; } } - uint32_t extensionCount = 0; + uint32_t extensionCount {}; std::vector extensionProperties; if (xrEnumerateInstanceExtensionProperties( nullptr, 0, &extensionCount, nullptr) @@ -1350,18 +1372,17 @@ void LunarWM::init_xr() } for (auto &requestedInstanceExtension : instance_extensions) { - bool found = false; + bool found {}; for (auto &extensionProperty : extensionProperties) { if (strcmp(requestedInstanceExtension.c_str(), - extensionProperty.extensionName) + static_cast(extensionProperty.extensionName)) != 0) { continue; - } else { - active_instance_extensions.push_back( - requestedInstanceExtension.c_str()); - found = true; - break; } + active_instance_extensions.push_back( + requestedInstanceExtension.c_str()); + found = true; + break; } if (!found) { throw std::runtime_error( @@ -1371,9 +1392,9 @@ void LunarWM::init_xr() } { - XrInstanceCreateInfo ci { + XrInstanceCreateInfo const ci { .type = XR_TYPE_INSTANCE_CREATE_INFO, - .next = NULL, + .next = nullptr, .createFlags = 0, .applicationInfo = app_info, .enabledApiLayerCount @@ -1384,7 +1405,7 @@ void LunarWM::init_xr() .enabledExtensionNames = active_instance_extensions.data(), }; - XrInstance instance; + XrInstance instance { nullptr }; if (xrCreateInstance(&ci, &instance) != XR_SUCCESS) { throw std::runtime_error("Failed to create OpenXR instance"); } @@ -1397,13 +1418,13 @@ void LunarWM::init_xr() .next = nullptr, }; - XrFormFactor factors[] { + std::array const factors { XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY, XR_FORM_FACTOR_HANDHELD_DISPLAY, }; for (auto const factor : factors) { gi.formFactor = factor; - XrSystemId system_id; + XrSystemId system_id = 0; if (xrGetSystem(*m_xr.instance, &gi, &system_id) == XR_SUCCESS) { m_xr.system_id = system_id; break; @@ -1420,16 +1441,18 @@ void LunarWM::init_xr() .next = nullptr, }; PFN_xrGetOpenGLESGraphicsRequirementsKHR - xrGetOpenGLESGraphicsRequirementsKHR; + xrGetOpenGLESGraphicsRequirementsKHR + = nullptr; xrGetInstanceProcAddr(*m_xr.instance, "xrGetOpenGLESGraphicsRequirementsKHR", - (PFN_xrVoidFunction *)&xrGetOpenGLESGraphicsRequirementsKHR); + reinterpret_cast( + &xrGetOpenGLESGraphicsRequirementsKHR)); if (xrGetOpenGLESGraphicsRequirementsKHR( *m_xr.instance, *m_xr.system_id, &reqs) != XR_SUCCESS) { throw std::runtime_error("Failed to get GLES graphics requirements"); } - printf("OpenGL ES range: %d.%d.%d – %d.%d.%d\n", + std::println("OpenGL ES range: {}.{}.{} - {}.{}.{}", XR_VERSION_MAJOR(reqs.minApiVersionSupported), XR_VERSION_MINOR(reqs.minApiVersionSupported), XR_VERSION_PATCH(reqs.minApiVersionSupported), @@ -1441,7 +1464,7 @@ void LunarWM::init_xr() glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR); { - XrGraphicsBindingEGLMNDX gbind = { + XrGraphicsBindingEGLMNDX gbind { .type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX, .next = nullptr, .getProcAddress = eglGetProcAddress, @@ -1450,7 +1473,7 @@ void LunarWM::init_xr() .context = m_wayland.egl_context, }; - XrSessionCreateInfo ci { + XrSessionCreateInfo const ci { .type = XR_TYPE_SESSION_CREATE_INFO, .next = &gbind, .createFlags = 0, @@ -1465,7 +1488,7 @@ void LunarWM::init_xr() // Swapchain time! std::vector view_config_types; { - std::uint32_t count; + std::uint32_t count {}; if (xrEnumerateViewConfigurations( *m_xr.instance, *m_xr.system_id, 0, &count, nullptr) != XR_SUCCESS) { @@ -1488,7 +1511,7 @@ void LunarWM::init_xr() } { - uint32_t count = 0; + uint32_t count {}; if (xrEnumerateViewConfigurationViews(*m_xr.instance, *m_xr.system_id, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, 0, &count, nullptr) != XR_SUCCESS) { @@ -1508,7 +1531,7 @@ void LunarWM::init_xr() std::vector swapchain_formats; { - std::uint32_t count; + std::uint32_t count {}; if (xrEnumerateSwapchainFormats(m_xr.session, 0, &count, nullptr) != XR_SUCCESS) { throw std::runtime_error( @@ -1523,60 +1546,59 @@ void LunarWM::init_xr() } } - std::vector swapchain_format_depth_needles { + std::vector const swapchain_format_depth_needles { GL_DEPTH_COMPONENT16, // GL_DEPTH_COMPONENT32F, // GL_DEPTH_COMPONENT24, }; std::vector::const_iterator const &swapchain_format_depth_it - = std::find_first_of(swapchain_formats.begin(), swapchain_formats.end(), - std::begin(swapchain_format_depth_needles), - std::end(swapchain_format_depth_needles)); + = boost::range::find_first_of( + swapchain_formats, swapchain_format_depth_needles); if (swapchain_format_depth_it == swapchain_formats.end()) { throw std::runtime_error( "Failed to find satisfying depth swapchain format"); } - auto const swapchain_format_depth = *swapchain_format_depth_it; + auto const swapchain_format_depth { *swapchain_format_depth_it }; - std::vector swapchain_format_color_needles { + std::vector const swapchain_format_color_needles { GL_SRGB8_ALPHA8 }; - std::vector::const_iterator const &swapchain_format_color_it - = std::find_first_of(swapchain_formats.begin(), swapchain_formats.end(), - std::begin(swapchain_format_color_needles), - std::end(swapchain_format_color_needles)); + auto const &swapchain_format_color_it + { boost::range::find_first_of( + swapchain_formats, swapchain_format_color_needles) }; if (swapchain_format_color_it == swapchain_formats.end()) { throw std::runtime_error( "Failed to find satisfying color swapchain format"); } - auto const swapchain_format_color = *swapchain_format_color_it; + auto const swapchain_format_color { *swapchain_format_color_it }; auto const AllocateSwapchainImageData - = [&](XrSwapchain swapchain, SwapchainType type, uint32_t count) { + { [&](XrSwapchain swapchain, SwapchainType type, uint32_t count) { m_xr.swapchain_images_map[swapchain].first = type; m_xr.swapchain_images_map[swapchain].second.resize( count, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR }); return reinterpret_cast( m_xr.swapchain_images_map[swapchain].second.data()); - }; + } }; - uint32_t const view_count = (uint32_t)m_xr.view_configuration_views.size(); + auto const view_count + { static_cast(m_xr.view_configuration_views.size()) }; uint32_t const eyeW - = m_xr.view_configuration_views[0].recommendedImageRectWidth; + { m_xr.view_configuration_views[0].recommendedImageRectWidth }; uint32_t const eyeH - = m_xr.view_configuration_views[0].recommendedImageRectHeight; - uint32_t const bufW = eyeW * view_count; + { m_xr.view_configuration_views[0].recommendedImageRectHeight }; + uint32_t const bufW { eyeW * view_count}; m_xr.swapchains.color.resize(1); m_xr.swapchains.depth.resize(1); { - auto &color_sc = m_xr.swapchains.color[0]; - auto &depth_sc = m_xr.swapchains.depth[0]; - auto &vcv = m_xr.view_configuration_views[0]; + auto &color_sc { m_xr.swapchains.color[0]}; + auto &depth_sc { m_xr.swapchains.depth[0]}; + auto &vcv { m_xr.view_configuration_views[0]}; { // Create color swapchain - XrSwapchainCreateInfo ci { + XrSwapchainCreateInfo const ci { .type = XR_TYPE_SWAPCHAIN_CREATE_INFO, .next = nullptr, .createFlags = 0, @@ -1600,7 +1622,7 @@ void LunarWM::init_xr() } { // Create depth swapchain - XrSwapchainCreateInfo ci { + XrSwapchainCreateInfo const ci { .type = XR_TYPE_SWAPCHAIN_CREATE_INFO, .next = nullptr, .createFlags = 0, @@ -1623,10 +1645,10 @@ void LunarWM::init_xr() } } - XrResult res; + XrResult res {}; // Enumerate swapchain images - uint32_t color_swapchain_image_count = 0; + uint32_t color_swapchain_image_count { 0 }; if (xrEnumerateSwapchainImages( color_sc.swapchain, 0, &color_swapchain_image_count, nullptr) != XR_SUCCESS) { @@ -1634,8 +1656,8 @@ void LunarWM::init_xr() "Failed to get Color Swapchain Images count."); } XrSwapchainImageBaseHeader *color_swapchain_images - = AllocateSwapchainImageData(color_sc.swapchain, - SwapchainType::Color, color_swapchain_image_count); + { AllocateSwapchainImageData(color_sc.swapchain, + SwapchainType::Color, color_swapchain_image_count)}; if (xrEnumerateSwapchainImages(color_sc.swapchain, color_swapchain_image_count, &color_swapchain_image_count, color_swapchain_images) @@ -1644,37 +1666,38 @@ void LunarWM::init_xr() "Failed to enumerate Color Swapchain Images."); } - uint32_t depth_swapchain_image_count = 0; - if ((res = xrEnumerateSwapchainImages( - depth_sc.swapchain, 0, &depth_swapchain_image_count, nullptr)) - != XR_SUCCESS) { + uint32_t depth_swapchain_image_count { }; + res = xrEnumerateSwapchainImages( + depth_sc.swapchain, 0, &depth_swapchain_image_count, nullptr); + if (res != XR_SUCCESS) { throw std::runtime_error(std::format( "Failed to get Depth Swapchain Images count. {}", res)); } + XrSwapchainImageBaseHeader *depth_swapchain_images - = AllocateSwapchainImageData(depth_sc.swapchain, - SwapchainType::Depth, depth_swapchain_image_count); - if ((res = xrEnumerateSwapchainImages(depth_sc.swapchain, - depth_swapchain_image_count, &depth_swapchain_image_count, - depth_swapchain_images)) - != XR_SUCCESS) { + { AllocateSwapchainImageData(depth_sc.swapchain, + SwapchainType::Depth, depth_swapchain_image_count) }; + res = xrEnumerateSwapchainImages(depth_sc.swapchain, + depth_swapchain_image_count, &depth_swapchain_image_count, + depth_swapchain_images); + if (res != XR_SUCCESS) { throw std::runtime_error( "Failed to enumerate Depth Swapchain Images."); } // Get image views - for (uint32_t j = 0; j < color_swapchain_image_count; j++) { - GLuint framebuffer = 0; + for (uint32_t j {}; j < color_swapchain_image_count; j++) { + GLuint framebuffer {}; glGenFramebuffers(1, &framebuffer); - GLenum attachment = GL_COLOR_ATTACHMENT0; + GLenum const attachment { GL_COLOR_ATTACHMENT0 }; glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_xr.get_swapchain_image(color_sc.swapchain, j), 0); - GLenum result = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + GLenum const result { glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) }; if (result != GL_FRAMEBUFFER_COMPLETE) { throw std::runtime_error("Failed to create color framebuffer"); } @@ -1682,18 +1705,18 @@ void LunarWM::init_xr() color_sc.image_views.push_back(framebuffer); } - for (uint32_t j = 0; j < depth_swapchain_image_count; j++) { - GLuint framebuffer = 0; + for (uint32_t j {}; j < depth_swapchain_image_count; j++) { + GLuint framebuffer {}; glGenFramebuffers(1, &framebuffer); - GLenum attachment = GL_DEPTH_ATTACHMENT; + GLenum const attachment { GL_DEPTH_ATTACHMENT }; glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, m_xr.get_swapchain_image(depth_sc.swapchain, j), 0); - GLenum result = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + GLenum const result { glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) }; if (result != GL_FRAMEBUFFER_COMPLETE) { throw std::runtime_error("Failed to create depth framebuffer"); } @@ -1703,6 +1726,15 @@ void LunarWM::init_xr() } } + if (!m_xr.instance) { + throw std::runtime_error( + "OpenXR instance is not initialized for some reason"); + } + if (!m_xr.system_id) { + throw std::runtime_error( + "OpenXR system ID is not initialized for some reason"); + } + std::vector environment_blend_modes; { // Get available blend modes std::uint32_t count {}; @@ -1721,11 +1753,12 @@ void LunarWM::init_xr() "Failed to get XR environment blend modes"); } } - std::vector requested_environment_blend_modes { - XR_ENVIRONMENT_BLEND_MODE_OPAQUE, - XR_ENVIRONMENT_BLEND_MODE_ADDITIVE, - XR_ENVIRONMENT_BLEND_MODE_MAX_ENUM, - }; + std::vector const + requested_environment_blend_modes { + XR_ENVIRONMENT_BLEND_MODE_OPAQUE, + XR_ENVIRONMENT_BLEND_MODE_ADDITIVE, + XR_ENVIRONMENT_BLEND_MODE_MAX_ENUM, + }; for (auto const &bm : requested_environment_blend_modes) { m_xr.environment_blend_mode = bm; @@ -1741,7 +1774,7 @@ void LunarWM::init_xr() } { // Reference space - XrReferenceSpaceCreateInfo ci { + XrReferenceSpaceCreateInfo const ci { .type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO, .next = nullptr, .referenceSpaceType = XR_REFERENCE_SPACE_TYPE_STAGE, @@ -1756,7 +1789,7 @@ void LunarWM::init_xr() } { // View reference space - XrReferenceSpaceCreateInfo ci { + XrReferenceSpaceCreateInfo const ci { .type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO, .next = nullptr, .referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW, @@ -1774,23 +1807,21 @@ void LunarWM::init_xr() void LunarWM::poll_events_xr() { XrEventDataBuffer event_data { XR_TYPE_EVENT_DATA_BUFFER }; - auto XrPollEvents = [&]() -> bool { - event_data = { XR_TYPE_EVENT_DATA_BUFFER }; + auto XrPollEvents { [&]() -> bool { + event_data = { .type = XR_TYPE_EVENT_DATA_BUFFER }; return xrPollEvent(*m_xr.instance, &event_data) == XR_SUCCESS; - }; + } }; while (XrPollEvents()) { switch (event_data.type) { case XR_TYPE_EVENT_DATA_EVENTS_LOST: { - XrEventDataEventsLost *el - = reinterpret_cast(&event_data); + auto *el { reinterpret_cast(&event_data) }; wlr_log(WLR_INFO, "OPENXR: Events Lost: %d", el->lostEventCount); break; } case XR_TYPE_EVENT_DATA_INSTANCE_LOSS_PENDING: { - XrEventDataInstanceLossPending *ilp - = reinterpret_cast( - &event_data); + auto *ilp { reinterpret_cast( + &event_data) }; wlr_log(WLR_INFO, "OPENXR: Instance Loss Pending at: %ld", ilp->lossTime); m_session_running = false; @@ -1798,9 +1829,9 @@ void LunarWM::poll_events_xr() break; } case XR_TYPE_EVENT_DATA_INTERACTION_PROFILE_CHANGED: { - XrEventDataInteractionProfileChanged *ipc - = reinterpret_cast( - &event_data); + auto *ipc + { reinterpret_cast( + &event_data) }; wlr_log(WLR_INFO, "OPENXR: Interaction Profile changed for Session: %p", ipc->session); @@ -1812,9 +1843,9 @@ void LunarWM::poll_events_xr() break; } case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: { - XrEventDataReferenceSpaceChangePending *scp - = reinterpret_cast( - &event_data); + auto *scp + { reinterpret_cast( + &event_data) }; wlr_log(WLR_INFO, "OPENXR: Reference Space Change pending for Session: %p", scp->session); @@ -1827,9 +1858,8 @@ void LunarWM::poll_events_xr() break; } case XR_TYPE_EVENT_DATA_SESSION_STATE_CHANGED: { - XrEventDataSessionStateChanged *sc - = reinterpret_cast( - &event_data); + auto *sc { reinterpret_cast( + &event_data) }; if (sc->session != m_xr.session) { wlr_log(WLR_ERROR, "XrEventDataSessionStateChanged for unknown Session"); @@ -1871,11 +1901,11 @@ void LunarWM::poll_events_xr() } } -bool LunarWM::render_layer(RenderLayerInfo &info, float dt) +auto LunarWM::render_layer(RenderLayerInfo &info, float dt) -> bool { // locate views ----------------------------------------------------------- - std::uint32_t view_count - = (std::uint32_t)m_xr.view_configuration_views.size(); + auto const view_count + {static_cast(m_xr.view_configuration_views.size()) }; std::vector views(view_count, { XR_TYPE_VIEW }); XrViewLocateInfo locInfo { XR_TYPE_VIEW_LOCATE_INFO }; @@ -1884,7 +1914,7 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) locInfo.space = m_xr.local_space; XrViewState viewState { XR_TYPE_VIEW_STATE }; - std::uint32_t located = 0; + std::uint32_t located {}; if (xrLocateViews(m_xr.session, &locInfo, &viewState, view_count, &located, views.data()) != XR_SUCCESS @@ -1894,31 +1924,36 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) } // acquire swapchain images ---------------------------------------------- - auto &color_sc = m_xr.swapchains.color[0]; - auto &depth_sc = m_xr.swapchains.depth[0]; + auto &color_sc { m_xr.swapchains.color[0] }; + auto &depth_sc { m_xr.swapchains.depth[0] }; - auto acquire_wait = [](XrSwapchain sc, std::uint32_t &idx) -> bool { - XrSwapchainImageAcquireInfo ai { XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO }; - if (xrAcquireSwapchainImage(sc, &ai, &idx) != XR_SUCCESS) + auto acquire_wait { [](XrSwapchain sc, std::uint32_t &idx) -> bool { + XrSwapchainImageAcquireInfo const ai { + XR_TYPE_SWAPCHAIN_IMAGE_ACQUIRE_INFO + }; + if (xrAcquireSwapchainImage(sc, &ai, &idx) != XR_SUCCESS) { return false; + } XrSwapchainImageWaitInfo wi { XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO }; wi.timeout = XR_INFINITE_DURATION; return xrWaitSwapchainImage(sc, &wi) == XR_SUCCESS; - }; + }}; - std::uint32_t colIdx = 0, depIdx = 0; + std::uint32_t colIdx {}; + std::uint32_t depIdx {}; if (!acquire_wait(color_sc.swapchain, colIdx) || !acquire_wait(depth_sc.swapchain, depIdx)) { wlr_log(WLR_ERROR, "Swap-chain acquire failed"); return false; } - GLuint color_tex = m_xr.get_swapchain_image(color_sc.swapchain, colIdx); - GLuint depth_tex = m_xr.get_swapchain_image(depth_sc.swapchain, depIdx); + GLuint color_tex { m_xr.get_swapchain_image(color_sc.swapchain, colIdx) }; + GLuint depth_tex { m_xr.get_swapchain_image(depth_sc.swapchain, depIdx) }; // build FBO -------------------------------------------------------------- - if (!m_renderer.fbo) + if (m_renderer.fbo == 0u) { glGenFramebuffers(1, &m_renderer.fbo); + } glBindFramebuffer(GL_FRAMEBUFFER, m_renderer.fbo); rlFramebufferAttach(m_renderer.fbo, color_tex, RL_ATTACHMENT_COLOR_CHANNEL0, RL_ATTACHMENT_TEXTURE2D, 0); @@ -1926,26 +1961,28 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) RL_ATTACHMENT_TEXTURE2D, 0); assert(rlFramebufferComplete(m_renderer.fbo)); - std::uint32_t eyeW - = m_xr.view_configuration_views[0].recommendedImageRectWidth; - std::uint32_t eyeH - = m_xr.view_configuration_views[0].recommendedImageRectHeight; + std::uint32_t const eyeW + { m_xr.view_configuration_views[0].recommendedImageRectWidth }; + std::uint32_t const eyeH + { m_xr.view_configuration_views[0].recommendedImageRectHeight }; - m_renderer.tmp_rt = { m_renderer.fbo, - { color_tex, (int)(eyeW * view_count), (int)eyeH, 1, -1 }, - { depth_tex, (int)(eyeW * view_count), (int)eyeH, 1, -1 } }; + m_renderer.tmp_rt = { .id = m_renderer.fbo, + .texture = { color_tex, static_cast(eyeW * view_count), + static_cast(eyeH), 1, -1 }, + .depth = { depth_tex, static_cast(eyeW * view_count), + static_cast(eyeH), 1, -1 } }; // head-space view matrix (matches rlOpenXR) ------------------------------ XrSpaceLocation headLoc { XR_TYPE_SPACE_LOCATION }; xrLocateSpace(m_xr.view_space, m_xr.local_space, info.predicted_display_time, &headLoc); - Matrix headView = MatrixInvert(xr_matrix(headLoc.pose)); + Matrix const headView { MatrixInvert(xr_matrix(headLoc.pose)) }; // per-eye projection + view-offset --------------------------------------- - Matrix projR = xr_projection_matrix(views[1].fov); - Matrix projL = xr_projection_matrix(views[0].fov); - Matrix viewOffR = MatrixMultiply(xr_matrix(views[1].pose), headView); - Matrix viewOffL = MatrixMultiply(xr_matrix(views[0].pose), headView); + Matrix const projR { xr_projection_matrix(views[1].fov) }; + Matrix const projL { xr_projection_matrix(views[0].fov) }; + Matrix const viewOffR { MatrixMultiply(xr_matrix(views[1].pose), headView) }; + Matrix const viewOffL { MatrixMultiply(xr_matrix(views[0].pose), headView) }; // draw ------------------------------------------------------------------- BeginTextureMode(m_renderer.tmp_rt); @@ -1954,7 +1991,8 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) rlSetMatrixProjectionStereo(projL, projR); // right, left (yes) rlSetMatrixViewOffsetStereo(viewOffL, viewOffR); - glViewport(0, 0, (GLsizei)(eyeW * view_count), (GLsizei)eyeH); + glViewport(0, 0, static_cast(eyeW * view_count), + static_cast(eyeH)); ClearBackground({ 0, 0, 10, 255 }); m_renderer.update_camera(*this, m_renderer.camera, info); @@ -1969,7 +2007,9 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) EndTextureMode(); // release swapchain images ---------------------------------------------- - XrSwapchainImageReleaseInfo ri { XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO }; + XrSwapchainImageReleaseInfo const ri { + XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO + }; xrReleaseSwapchainImage(color_sc.swapchain, &ri); xrReleaseSwapchainImage(depth_sc.swapchain, &ri); @@ -1977,14 +2017,16 @@ bool LunarWM::render_layer(RenderLayerInfo &info, float dt) info.layer_projection_views.resize( view_count, { XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW }); - for (std::uint32_t i = 0; i < view_count; ++i) { - int32_t xOff = (int32_t)i * (int32_t)eyeW; - auto &pv = info.layer_projection_views[i]; + for (std::uint32_t i {}; i < view_count; ++i) { + int32_t const xOff + { static_cast(i) * static_cast(eyeW) }; + auto &pv { info.layer_projection_views[i] }; pv.pose = views[i].pose; pv.fov = views[i].fov; pv.subImage.swapchain = color_sc.swapchain; - pv.subImage.imageRect.offset = { xOff, 0 }; - pv.subImage.imageRect.extent = { (int32_t)eyeW, (int32_t)eyeH }; + pv.subImage.imageRect.offset = { .x = xOff, .y = 0 }; + pv.subImage.imageRect.extent = { .width = static_cast(eyeW), + .height = static_cast(eyeH) }; pv.subImage.imageArrayIndex = 0; } @@ -2012,9 +2054,9 @@ LunarWM::~LunarWM() xrDestroySpace(m_xr.local_space); } - for (size_t i = 0; i < m_xr.swapchains.color.size(); i++) { - auto &color_sc = m_xr.swapchains.color[i]; - auto &depth_sc = m_xr.swapchains.depth[i]; + for (size_t i {}; i < m_xr.swapchains.color.size(); i++) { + auto &color_sc { m_xr.swapchains.color[i] }; + auto &depth_sc { m_xr.swapchains.depth[i] }; for (auto &iv : color_sc.image_views) { glDeleteFramebuffers(1, &iv); @@ -2038,16 +2080,16 @@ LunarWM::~LunarWM() wl_list_remove(&m_wayland.keyboards); wl_display_destroy_clients(m_wayland.display); - if (m_wayland.allocator) { + if (m_wayland.allocator != nullptr) { wlr_allocator_destroy(m_wayland.allocator); } - if (m_wayland.renderer) { + if (m_wayland.renderer != nullptr) { wlr_renderer_destroy(m_wayland.renderer); } - if (m_wayland.backend) { + if (m_wayland.backend != nullptr) { wlr_backend_destroy(m_wayland.backend); } - if (m_wayland.display) { + if (m_wayland.display != nullptr) { wl_display_destroy(m_wayland.display); } } @@ -2058,25 +2100,26 @@ void LunarWM::run() throw std::runtime_error("Failed to start backend"); } - auto const *socket = wl_display_add_socket_auto(m_wayland.display); - if (!socket) { + auto const *socket { wl_display_add_socket_auto(m_wayland.display) }; + if (socket == nullptr) { throw std::runtime_error("Failed to add wayland socket to display"); } - setenv("WAYLAND_DISPLAY", socket, true); + setenv("WAYLAND_DISPLAY", socket, 1); // NOLINT wlr_log(WLR_INFO, "Running compositor on WAYLAND_DISPLAY=%s", socket); m_running = true; while (m_running) { - auto now = Clock::now(); - float dt = std::chrono::duration(now - m_last_tick).count(); + auto now { Clock::now() }; + float const dt + { std::chrono::duration(now - m_last_tick).count() }; m_last_tick = now; wl_display_flush_clients(m_wayland.display); wl_event_loop_dispatch(m_wayland.event_loop, 0); - auto draw = eglGetCurrentSurface(EGL_DRAW); - auto read = eglGetCurrentSurface(EGL_READ); + auto *draw { eglGetCurrentSurface(EGL_DRAW) }; + auto *read { eglGetCurrentSurface(EGL_READ) }; if (eglMakeCurrent(m_wayland.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, m_wayland.egl_context) == EGL_FALSE) { @@ -2088,7 +2131,7 @@ void LunarWM::run() XrFrameState frame_state { .type = XR_TYPE_FRAME_STATE, }; - XrFrameWaitInfo frame_wait_info { + XrFrameWaitInfo const frame_wait_info { .type = XR_TYPE_FRAME_WAIT_INFO, .next = nullptr, }; @@ -2097,11 +2140,11 @@ void LunarWM::run() throw std::runtime_error("Failed to wait for OpenXR frame"); } - XrFrameBeginInfo frame_begin_info { + XrFrameBeginInfo const frame_begin_info { .type = XR_TYPE_FRAME_BEGIN_INFO, .next = nullptr, }; - XrResult res = xrBeginFrame(m_xr.session, &frame_begin_info); + XrResult res { xrBeginFrame(m_xr.session, &frame_begin_info) }; if (res != XR_FRAME_DISCARDED && res != XR_SUCCESS) { throw std::runtime_error( std::format("Failed to begin the OpenXR Frame: {}", res)); @@ -2112,12 +2155,12 @@ void LunarWM::run() RenderLayerInfo render_layer_info { .predicted_display_time = frame_state.predictedDisplayTime, }; - bool session_active - = (m_xr.session_state == XR_SESSION_STATE_SYNCHRONIZED + bool const session_active + { (m_xr.session_state == XR_SESSION_STATE_SYNCHRONIZED || m_xr.session_state == XR_SESSION_STATE_VISIBLE - || m_xr.session_state == XR_SESSION_STATE_FOCUSED); - if (session_active && frame_state.shouldRender) { - auto rendered = this->render_layer(render_layer_info, dt); + || m_xr.session_state == XR_SESSION_STATE_FOCUSED) }; + if (session_active && (frame_state.shouldRender != 0u)) { + auto rendered { this->render_layer(render_layer_info, dt) }; if (rendered) { render_layer_info.layers.push_back( reinterpret_cast( @@ -2125,7 +2168,7 @@ void LunarWM::run() } } - XrFrameEndInfo frame_end_info { + XrFrameEndInfo const frame_end_info { .type = XR_TYPE_FRAME_END_INFO, .displayTime = frame_state.predictedDisplayTime, .environmentBlendMode = m_xr.environment_blend_mode, @@ -2141,15 +2184,19 @@ void LunarWM::run() EndDrawing(); if (eglMakeCurrent( - m_wayland.egl_display, read, draw, m_wayland.egl_context) + m_wayland.egl_display, draw, read, m_wayland.egl_context) == EGL_FALSE) { throw std::runtime_error("Failed to eglMakeCurrent"); } - struct timespec n; - clock_gettime(CLOCK_MONOTONIC, &n); + struct timespec n {}; + if (clock_gettime(CLOCK_MONOTONIC, &n) != 0) { + throw std::runtime_error( + std::format("Failed call to gettime. errno={} ({})", errno, + strerror(errno))); // NOLINT + } for (auto const &tl : m_wayland.toplevels) { - if (tl->surface) { + if (tl->surface != nullptr) { wlr_surface_send_frame_done(tl->surface, &n); } } @@ -2159,15 +2206,16 @@ void LunarWM::run() static void DrawBillboardNoShear(Camera3D const &cam, Texture2D tex, Vector3 pos, float scale = 1.0f, Color tint = WHITE) { - Rectangle src = { 0, 0, (float)tex.width, (float)tex.height }; + Rectangle const src { 0, 0, static_cast(tex.width), + static_cast(tex.height) }; - Vector2 size = { scale * fabsf(src.width / src.height), scale }; - Vector2 origin = { size.x * 0.5f, size.y * 0.5f }; + Vector2 const size { scale * fabsf(src.width / src.height), scale }; + Vector2 const origin { size.x * 0.5f, size.y * 0.5f }; DrawBillboardPro(cam, tex, src, pos, cam.up, size, origin, 0.0f, tint); } -void LunarWM::render_3d(float dt) +void LunarWM::render_3d(float /*dt*/) { DrawGrid(10, 1); diff --git a/src/Math.cppm b/src/Math.cppm index 79041a4..360d8c4 100644 --- a/src/Math.cppm +++ b/src/Math.cppm @@ -1,51 +1,54 @@ module; -import std; - export module LunarWM.Math; -export namespace LunarWM { -namespace Math { +import std; + +export namespace LunarWM::Math { template requires std::is_arithmetic_v struct Vec2 { template - requires std::is_arithmetic_v Vec2 operator+(Vec2 const &other) + requires std::is_arithmetic_v + auto operator+(Vec2 const &other) -> Vec2 { return { x + other.x, y + other.y }; } template - requires std::is_arithmetic_v Vec2 operator-(Vec2 const &other) + requires std::is_arithmetic_v + auto operator-(Vec2 const &other) -> Vec2 { return { x - other.x, y - other.y }; } template - requires std::is_arithmetic_v Vec2 operator*(Vec2 const &other) + requires std::is_arithmetic_v + auto operator*(Vec2 const &other) -> Vec2 { return { x * other.x, y * other.x }; } template - requires std::is_arithmetic_v Vec2 operator*(T scalar) + requires std::is_arithmetic_v auto operator*(T scalar) -> Vec2 { return { x * scalar, y * scalar }; } template - requires std::is_arithmetic_v Vec2 operator/(T scalar) + requires std::is_arithmetic_v auto operator/(T scalar) -> Vec2 { return { x / scalar, y / scalar }; } template - requires std::is_arithmetic_v Vec2 operator-() + requires std::is_arithmetic_v auto operator-() -> Vec2 { return { -x, -y }; } - T length() const { return std::sqrt(x * x + y * y); } - T lengthSquared() const { return x * x + y * y; } - Vec2 normalized() const + auto length() const -> T { return std::sqrt(x * x + y * y); } + auto lengthSquared() const -> T { return x * x + y * y; } + auto normalized() const -> Vec2 { T len = length(); - if (len == T(0)) + if (len == T(0)) { return { T(0), T(0) }; + } return *this / len; } @@ -53,7 +56,8 @@ requires std::is_arithmetic_v struct Vec2 { }; template -requires std::is_arithmetic_v Vec2 operator*(T scalar, Vec2 const &v) +requires std::is_arithmetic_v +auto operator*(T scalar, Vec2 const &v) -> Vec2 { return { v.x * scalar, v.y * scalar }; } @@ -71,23 +75,23 @@ requires std::is_arithmetic_v struct Rect { { } - T &x() { return pos.x; } - T &y() { return pos.y; } - T &w() { return size.x; } - T &h() { return size.y; } + auto x() -> T & { return pos.x; } + auto y() -> T & { return pos.y; } + auto w() -> T & { return size.x; } + auto h() -> T & { return size.y; } - T x() const { return pos.x; } - T y() const { return pos.y; } - T w() const { return size.x; } - T h() const { return size.y; } + auto x() const -> T { return pos.x; } + auto y() const -> T { return pos.y; } + auto w() const -> T { return size.x; } + auto h() const -> T { return size.y; } - T left() const { return x(); } - T right() const { return x() + w(); } - T top() const { return y(); } - T bottom() const { return y() + h(); } + auto left() const -> T { return x(); } + auto right() const -> T { return x() + w(); } + auto top() const -> T { return y(); } + auto bottom() const -> T { return y() + h(); } - T &left() { return x(); } - T &top() { return y(); } + auto left() -> T & { return x(); } + auto top() -> T & { return y(); } Vec2 pos, size; }; @@ -95,57 +99,63 @@ requires std::is_arithmetic_v struct Rect { template requires std::is_arithmetic_v struct Box { template - requires std::is_arithmetic_v Vec2 &operator[](U const index) + requires std::is_arithmetic_v auto operator[](U const index) -> Vec2 & { - if (index < 0 || index > 1) + if (index < 0 || index > 1) { throw std::out_of_range("A box only has two points"); + } return m_data[index]; } - Vec2 &first() { return m_data[0]; } - Vec2 &second() { return m_data[1]; } - T &x0() { return m_data[0].x; } - T &y0() { return m_data[0].y; } - T &x1() { return m_data[1].x; } - T &y1() { return m_data[1].y; } - T &left() + auto first() -> Vec2 & { return m_data[0]; } + auto second() -> Vec2 & { return m_data[1]; } + auto x0() -> T & { return m_data[0].x; } + auto y0() -> T & { return m_data[0].y; } + auto x1() -> T & { return m_data[1].x; } + auto y1() -> T & { return m_data[1].y; } + auto left() -> T & { - if (x0() < x1()) + if (x0() < x1()) { return x0(); + } return x1(); } - T &right() + auto right() -> T & { - if (x0() > x1()) + if (x0() > x1()) { return x0(); + } return x1(); } - T &top() + auto top() -> T & { - if (y0() < y1()) + if (y0() < y1()) { return y0(); + } return y1(); } - T &bottom() + auto bottom() -> T & { - if (y0() > y1()) + if (y0() > y1()) { return y0(); + } return y1(); } - Box() { } - Box(Rect rect) + Box() = default; + explicit Box(Rect rect) { this->m_data[0] = rect.pos; this->m_data[1] = rect.pos + rect.size; } private: - Vec2 m_data[2] = {}; + std::array, 2> m_data = {}; }; template -requires std::is_arithmetic_v std::vector> subtract_rect( - Math::Rect const &src, Math::Rect const &clip) +requires std::is_arithmetic_v +auto subtract_rect(Math::Rect const &src, Math::Rect const &clip) + -> std::vector> { std::vector> result; @@ -208,5 +218,4 @@ requires std::is_arithmetic_v struct Viewport { Vec2 depth_limits; }; -} // namespace Math -} // namespace LunarWM +} // namespace LunarWM::Math diff --git a/src/main.cpp b/src/main.cpp index 254d793..3b0afeb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,14 +1,30 @@ +// NOLINTBEGIN +#include #include +#include +#include +// NOLINTEND + import std; import LunarWM.LunarWM; -std::unique_ptr g_comp; +static std::unique_ptr g_comp; -int main(void) { - g_comp = std::make_unique(); - g_comp->init(); - std::signal(SIGINT, [](int) { g_comp->terminate(); }); - g_comp->run(); +auto main() noexcept -> int // NOLINT(bugprone-exception-escape) +{ + CPPTRACE_TRY + { + g_comp = std::make_unique(); + g_comp->init(); + assert( + std::signal(SIGINT, [](int) { g_comp->terminate(); }) != SIG_ERR); + g_comp->run(); + } + CPPTRACE_CATCH(std::exception const &e) + { + std::println(std::cerr, "Uncaught exception: {}", e.what()); + cpptrace::from_current_exception().print(); + } }