1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DisplayVkXcb.cpp:
7 // Implements the class methods for DisplayVkXcb.
8 //
9
10 #include "libANGLE/renderer/vulkan/xcb/DisplayVkXcb.h"
11
12 #include <xcb/xcb.h>
13
14 #include "libANGLE/Display.h"
15 #include "libANGLE/renderer/vulkan/vk_caps_utils.h"
16 #include "libANGLE/renderer/vulkan/xcb/WindowSurfaceVkXcb.h"
17
18 namespace rx
19 {
20
21 namespace
22 {
GetXcbVisualType(xcb_screen_t * screen)23 EGLint GetXcbVisualType(xcb_screen_t *screen)
24 {
25 // Visual type is the class member of xcb_visualtype_t whose id matches the root visual.
26 for (xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
27 depth_iter.rem; xcb_depth_next(&depth_iter))
28 {
29 for (xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
30 visual_iter.rem; xcb_visualtype_next(&visual_iter))
31 {
32 if (screen->root_visual == visual_iter.data->visual_id)
33 {
34 return visual_iter.data->_class;
35 }
36 }
37 }
38
39 return EGL_NONE;
40 }
41 } // namespace
42
DisplayVkXcb(const egl::DisplayState & state)43 DisplayVkXcb::DisplayVkXcb(const egl::DisplayState &state)
44 : DisplayVk(state), mXcbConnection(nullptr)
45 {}
46
initialize(egl::Display * display)47 egl::Error DisplayVkXcb::initialize(egl::Display *display)
48 {
49 mXcbConnection = xcb_connect(nullptr, nullptr);
50 if (mXcbConnection == nullptr)
51 {
52 return egl::EglNotInitialized();
53 }
54 return DisplayVk::initialize(display);
55 }
56
terminate()57 void DisplayVkXcb::terminate()
58 {
59 ASSERT(mXcbConnection != nullptr);
60 xcb_disconnect(mXcbConnection);
61 mXcbConnection = nullptr;
62 DisplayVk::terminate();
63 }
64
isValidNativeWindow(EGLNativeWindowType window) const65 bool DisplayVkXcb::isValidNativeWindow(EGLNativeWindowType window) const
66 {
67 // There doesn't appear to be an xcb function explicitly for checking the validity of a
68 // window ID, but xcb_query_tree_reply will return nullptr if the window doesn't exist.
69 xcb_query_tree_cookie_t cookie =
70 xcb_query_tree(mXcbConnection, static_cast<xcb_window_t>(window));
71 xcb_query_tree_reply_t *reply = xcb_query_tree_reply(mXcbConnection, cookie, nullptr);
72 if (reply)
73 {
74 free(reply);
75 return true;
76 }
77 return false;
78 }
79
createWindowSurfaceVk(const egl::SurfaceState & state,EGLNativeWindowType window)80 SurfaceImpl *DisplayVkXcb::createWindowSurfaceVk(const egl::SurfaceState &state,
81 EGLNativeWindowType window)
82 {
83 return new WindowSurfaceVkXcb(state, window, mXcbConnection);
84 }
85
generateConfigs()86 egl::ConfigSet DisplayVkXcb::generateConfigs()
87 {
88 constexpr GLenum kColorFormats[] = {GL_BGRA8_EXT, GL_BGRX8_ANGLEX};
89 return egl_vk::GenerateConfigs(kColorFormats, egl_vk::kConfigDepthStencilFormats, this);
90 }
91
checkConfigSupport(egl::Config * config)92 bool DisplayVkXcb::checkConfigSupport(egl::Config *config)
93 {
94 // TODO(geofflang): Test for native support and modify the config accordingly.
95 // http://anglebug.com/2692
96
97 // Find the screen the window was created on:
98 xcb_screen_iterator_t screenIterator = xcb_setup_roots_iterator(xcb_get_setup(mXcbConnection));
99 ASSERT(screenIterator.rem);
100
101 xcb_screen_t *screen = screenIterator.data;
102 ASSERT(screen);
103
104 // Visual id is root_visual of the screen
105 config->nativeVisualID = screen->root_visual;
106 config->nativeVisualType = GetXcbVisualType(screen);
107
108 return true;
109 }
110
getWSIExtension() const111 const char *DisplayVkXcb::getWSIExtension() const
112 {
113 return VK_KHR_XCB_SURFACE_EXTENSION_NAME;
114 }
115
IsVulkanXcbDisplayAvailable()116 bool IsVulkanXcbDisplayAvailable()
117 {
118 return true;
119 }
120
CreateVulkanXcbDisplay(const egl::DisplayState & state)121 DisplayImpl *CreateVulkanXcbDisplay(const egl::DisplayState &state)
122 {
123 return new DisplayVkXcb(state);
124 }
125
waitNativeImpl()126 angle::Result DisplayVkXcb::waitNativeImpl()
127 {
128 XSync(mState.displayId, False);
129 return angle::Result::Continue;
130 }
131 } // namespace rx
132