• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021-2022 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 // DisplayVkWayland.cpp:
7 //    Implements the class methods for DisplayVkWayland.
8 //
9 
10 #include "libANGLE/renderer/vulkan/linux/wayland/DisplayVkWayland.h"
11 
12 #include <wayland-client.h>
13 
14 #include "common/angleutils.h"
15 #include "common/linux/dma_buf_utils.h"
16 #include "common/system_utils.h"
17 #include "libANGLE/Display.h"
18 #include "libANGLE/renderer/vulkan/RendererVk.h"
19 #include "libANGLE/renderer/vulkan/linux/wayland/WindowSurfaceVkWayland.h"
20 #include "libANGLE/renderer/vulkan/vk_caps_utils.h"
21 
22 namespace rx
23 {
24 
DisplayVkWayland(const egl::DisplayState & state)25 DisplayVkWayland::DisplayVkWayland(const egl::DisplayState &state)
26     : DisplayVkLinux(state), mOwnDisplay(false), mWaylandDisplay(nullptr)
27 {}
28 
initialize(egl::Display * display)29 egl::Error DisplayVkWayland::initialize(egl::Display *display)
30 {
31     EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId();
32     if (nativeDisplay == EGL_DEFAULT_DISPLAY)
33     {
34         mOwnDisplay     = true;
35         mWaylandDisplay = wl_display_connect(nullptr);
36     }
37     else
38     {
39         mWaylandDisplay = reinterpret_cast<wl_display *>(nativeDisplay);
40     }
41 
42     if (!mWaylandDisplay)
43     {
44         ERR() << "Failed to retrieve wayland display";
45         return egl::EglNotInitialized();
46     }
47 
48     egl::Error ret = DisplayVk::initialize(display);
49     if (ret.isError())
50     {
51         return ret;
52     }
53 
54     return ret;
55 }
56 
terminate()57 void DisplayVkWayland::terminate()
58 {
59     if (mOwnDisplay)
60     {
61         wl_display_disconnect(mWaylandDisplay);
62         mOwnDisplay = false;
63     }
64     mWaylandDisplay = nullptr;
65     DisplayVk::terminate();
66 }
67 
isValidNativeWindow(EGLNativeWindowType window) const68 bool DisplayVkWayland::isValidNativeWindow(EGLNativeWindowType window) const
69 {
70     // Wayland display Errors are fatal.
71     // If this function returns non-zero, the display is not valid anymore.
72     int error = wl_display_get_error(mWaylandDisplay);
73     if (error)
74     {
75         WARN() << "Wayland window is not valid: " << error << " " << strerror(error);
76     }
77     return error == 0;
78 }
79 
createWindowSurfaceVk(const egl::SurfaceState & state,EGLNativeWindowType window)80 SurfaceImpl *DisplayVkWayland::createWindowSurfaceVk(const egl::SurfaceState &state,
81                                                      EGLNativeWindowType window)
82 {
83     return new WindowSurfaceVkWayland(state, window, mWaylandDisplay);
84 }
85 
generateConfigs()86 egl::ConfigSet DisplayVkWayland::generateConfigs()
87 {
88     const std::array<GLenum, 1> kColorFormats = {GL_BGRA8_EXT};
89 
90     std::vector<GLenum> depthStencilFormats(
91         egl_vk::kConfigDepthStencilFormats,
92         egl_vk::kConfigDepthStencilFormats + ArraySize(egl_vk::kConfigDepthStencilFormats));
93 
94     if (getCaps().stencil8)
95     {
96         depthStencilFormats.push_back(GL_STENCIL_INDEX8);
97     }
98     return egl_vk::GenerateConfigs(kColorFormats.data(), kColorFormats.size(),
99                                    depthStencilFormats.data(), depthStencilFormats.size(), this);
100 }
101 
checkConfigSupport(egl::Config * config)102 void DisplayVkWayland::checkConfigSupport(egl::Config *config)
103 {
104     // In wayland there is no native visual ID or type
105 }
106 
getWSIExtension() const107 const char *DisplayVkWayland::getWSIExtension() const
108 {
109     return VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
110 }
111 
isWayland() const112 bool DisplayVkWayland::isWayland() const
113 {
114     return true;
115 }
116 
IsVulkanWaylandDisplayAvailable()117 bool IsVulkanWaylandDisplayAvailable()
118 {
119     wl_display *display = wl_display_connect(nullptr);
120     if (!display)
121     {
122         return false;
123     }
124     wl_display_disconnect(display);
125     return true;
126 }
127 
CreateVulkanWaylandDisplay(const egl::DisplayState & state)128 DisplayImpl *CreateVulkanWaylandDisplay(const egl::DisplayState &state)
129 {
130     return new DisplayVkWayland(state);
131 }
132 
133 }  // namespace rx
134