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