The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

comp/window_direct_mode: Use XCB/Xlib interop.

Since there currently is no Vulkan extension that takes XCB handles to
aqcuire the display Xlib interop needs to be used.

Before this patch Monado was opening connections for both APIs, which
introduced overhead.

Even though all XCB handles can be casted to Xlib ones, this cannot be
done with the main xcb_connection_t / Display. In it's design the
interop between both APIs can create a xcb_connection_t from a XCB
handle, but not the other way round. So in an interop case the Xlib
connection is the main one, since it's on a higher level.
More information on this can be found here:
https://xcb.freedesktop.org/MixingCalls/

Unfortunately the clean solution for this would be to specify a Vulkan
extension that takes XCB handles. This would make sense since Vulkan
is aware of XCB in other parts of the API as well. In Mesa the Xlib
structs will be ultimately casted to XCB.

+25 -24
+1 -1
CMakeLists.txt
··· 50 50 find_package(udev REQUIRED) 51 51 set(BUILD_DRIVER_V4L2 TRUE) 52 52 if(PKGCONFIG_FOUND) 53 - pkg_check_modules(XCB xcb xcb-randr) 53 + pkg_check_modules(XCB xcb xcb-randr x11-xcb) 54 54 55 55 pkg_search_module(WAYLAND wayland-client) 56 56 pkg_search_module(WAYLAND_SCANNER wayland-scanner)
+2 -1
meson.build
··· 81 81 82 82 # TODO: make these behave well when not present 83 83 x11 = dependency('x11', required: get_option('xlib')) 84 + x11_xcb = dependency('x11-xcb', required: get_option('xlib')) 84 85 xcb = dependency('xcb', required: get_option('xcb')) 85 86 xcb_randr = dependency('xcb-randr', required: get_option('xcb')) 86 87 ··· 116 117 build_xcb = xcb.found() 117 118 endif 118 119 119 - build_xcb_xrandr_direct = build_xcb and build_xlib and xcb_randr.found() 120 + build_xcb_xrandr_direct = build_xcb and build_xlib and xcb_randr.found() and x11_xcb.found() 120 121 121 122 build_wayland = false 122 123 if get_option('wayland').enabled() or get_option('wayland').auto()
+21 -21
src/xrt/compositor/main/comp_window_direct_mode.cpp
··· 10 10 11 11 #include <xcb/xcb.h> 12 12 #include <xcb/randr.h> 13 + #include <X11/Xlib-xcb.h> 13 14 #include <X11/extensions/Xrandr.h> 14 15 15 16 #include <map> ··· 58 59 struct comp_window base = comp_window(); 59 60 60 61 Display *dpy = nullptr; 61 - xcb_connection_t *connection = nullptr; 62 62 xcb_screen_t *screen = nullptr; 63 63 64 64 std::map<uint32_t, xcb_randr_mode_info_t> randr_modes = {}; ··· 191 191 d->display = VK_NULL_HANDLE; 192 192 } 193 193 194 - if (w_direct->connection) { 195 - xcb_disconnect(w_direct->connection); 196 - w_direct->connection = nullptr; 194 + if (w_direct->dpy) { 195 + XCloseDisplay(w_direct->dpy); 196 + w_direct->dpy = nullptr; 197 197 } 198 198 199 199 delete reinterpret_cast<struct comp_window_direct *>(w); ··· 228 228 return false; 229 229 } 230 230 231 + xcb_connection_t *connection = XGetXCBConnection(w_direct->dpy); 232 + 231 233 xcb_screen_iterator_t iter = 232 - xcb_setup_roots_iterator(xcb_get_setup(w_direct->connection)); 234 + xcb_setup_roots_iterator(xcb_get_setup(connection)); 233 235 234 236 w_direct->screen = iter.data; 235 237 ··· 676 678 COMP_ERROR(w->base.c, "Could not open X display."); 677 679 return false; 678 680 } 679 - 680 - //! @todo only open one connection and use XGetXCBConnection. 681 - w->connection = xcb_connect(nullptr, nullptr); 682 - return !xcb_connection_has_error(w->connection); 681 + return true; 683 682 } 684 683 685 684 static VkResult ··· 743 742 static void 744 743 comp_window_direct_get_randr_outputs(struct comp_window_direct *w) 745 744 { 745 + xcb_connection_t *connection = XGetXCBConnection(w->dpy); 746 746 xcb_randr_query_version_cookie_t version_cookie = 747 - xcb_randr_query_version(w->connection, XCB_RANDR_MAJOR_VERSION, 747 + xcb_randr_query_version(connection, XCB_RANDR_MAJOR_VERSION, 748 748 XCB_RANDR_MINOR_VERSION); 749 749 xcb_randr_query_version_reply_t *version_reply = 750 - xcb_randr_query_version_reply(w->connection, version_cookie, NULL); 750 + xcb_randr_query_version_reply(connection, version_cookie, NULL); 751 751 752 752 if (version_reply == nullptr) { 753 753 COMP_ERROR(w->base.c, "Could not get RandR version."); ··· 766 766 767 767 xcb_generic_error_t *error = nullptr; 768 768 xcb_intern_atom_cookie_t non_desktop_cookie = xcb_intern_atom( 769 - w->connection, 1, strlen("non-desktop"), "non-desktop"); 769 + connection, 1, strlen("non-desktop"), "non-desktop"); 770 770 xcb_intern_atom_reply_t *non_desktop_reply = 771 - xcb_intern_atom_reply(w->connection, non_desktop_cookie, &error); 771 + xcb_intern_atom_reply(connection, non_desktop_cookie, &error); 772 772 773 773 if (error != nullptr) { 774 774 COMP_ERROR(w->base.c, "xcb_intern_atom_reply returned error %d", ··· 787 787 } 788 788 789 789 xcb_randr_get_screen_resources_cookie_t resources_cookie = 790 - xcb_randr_get_screen_resources(w->connection, w->screen->root); 790 + xcb_randr_get_screen_resources(connection, w->screen->root); 791 791 xcb_randr_get_screen_resources_reply_t *resources_reply = 792 - xcb_randr_get_screen_resources_reply(w->connection, 793 - resources_cookie, nullptr); 792 + xcb_randr_get_screen_resources_reply(connection, resources_cookie, 793 + nullptr); 794 794 xcb_randr_output_t *xcb_outputs = 795 795 xcb_randr_get_screen_resources_outputs(resources_reply); 796 796 ··· 804 804 805 805 for (int i = 0; i < count; i++) { 806 806 xcb_randr_get_output_info_cookie_t output_cookie = 807 - xcb_randr_get_output_info(w->connection, xcb_outputs[i], 807 + xcb_randr_get_output_info(connection, xcb_outputs[i], 808 808 XCB_CURRENT_TIME); 809 809 xcb_randr_get_output_info_reply_t *output_reply = 810 - xcb_randr_get_output_info_reply(w->connection, 811 - output_cookie, nullptr); 810 + xcb_randr_get_output_info_reply(connection, output_cookie, 811 + nullptr); 812 812 813 813 // Only outputs with an available mode should be used 814 814 // (it is possible to see 'ghost' outputs with non-desktop=1). ··· 828 828 // Find the first output that has the non-desktop property set. 829 829 xcb_randr_get_output_property_cookie_t prop_cookie; 830 830 prop_cookie = xcb_randr_get_output_property( 831 - w->connection, xcb_outputs[i], non_desktop_reply->atom, 831 + connection, xcb_outputs[i], non_desktop_reply->atom, 832 832 XCB_ATOM_NONE, 0, 4, 0, 0); 833 833 xcb_randr_get_output_property_reply_t *prop_reply = nullptr; 834 834 prop_reply = xcb_randr_get_output_property_reply( 835 - w->connection, prop_cookie, &error); 835 + connection, prop_cookie, &error); 836 836 if (error != nullptr) { 837 837 COMP_ERROR(w->base.c, 838 838 "xcb_randr_get_output_property_reply "
+1 -1
src/xrt/compositor/meson.build
··· 34 34 35 35 if build_xcb_xrandr_direct 36 36 compositor_srcs += ['main/comp_window_direct_mode.cpp'] 37 - compositor_deps += [xcb_randr] 37 + compositor_deps += [xcb_randr, x11_xcb] 38 38 endif 39 39 40 40 if build_opengl