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