• 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 <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