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 // WindowSurfaceVkWayland.cpp:
7 // Implements the class methods for WindowSurfaceVkWayland.
8 //
9
10 #include "libANGLE/renderer/vulkan/linux/wayland/WindowSurfaceVkWayland.h"
11
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/renderer/vulkan/ContextVk.h"
15 #include "libANGLE/renderer/vulkan/DisplayVk.h"
16 #include "libANGLE/renderer/vulkan/vk_renderer.h"
17
18 #include <wayland-egl-backend.h>
19
20 namespace rx
21 {
22
ResizeCallback(wl_egl_window * eglWindow,void * payload)23 void WindowSurfaceVkWayland::ResizeCallback(wl_egl_window *eglWindow, void *payload)
24 {
25 WindowSurfaceVkWayland *windowSurface = reinterpret_cast<WindowSurfaceVkWayland *>(payload);
26
27 if (windowSurface->mExtents.width != eglWindow->width ||
28 windowSurface->mExtents.height != eglWindow->height)
29 {
30 windowSurface->mExtents.width = eglWindow->width;
31 windowSurface->mExtents.height = eglWindow->height;
32
33 // Trigger swapchain resize
34 windowSurface->mResized = true;
35 }
36 }
37
WindowSurfaceVkWayland(const egl::SurfaceState & surfaceState,EGLNativeWindowType window,wl_display * display)38 WindowSurfaceVkWayland::WindowSurfaceVkWayland(const egl::SurfaceState &surfaceState,
39 EGLNativeWindowType window,
40 wl_display *display)
41 : WindowSurfaceVk(surfaceState, window), mWaylandDisplay(display)
42 {
43 wl_egl_window *eglWindow = reinterpret_cast<wl_egl_window *>(window);
44 eglWindow->resize_callback = WindowSurfaceVkWayland::ResizeCallback;
45 eglWindow->driver_private = this;
46
47 mExtents = gl::Extents(eglWindow->width, eglWindow->height, 1);
48 }
49
createSurfaceVk(vk::Context * context,gl::Extents * extentsOut)50 angle::Result WindowSurfaceVkWayland::createSurfaceVk(vk::Context *context, gl::Extents *extentsOut)
51 {
52 ANGLE_VK_CHECK(context,
53 vkGetPhysicalDeviceWaylandPresentationSupportKHR(
54 context->getRenderer()->getPhysicalDevice(),
55 context->getRenderer()->getQueueFamilyIndex(), mWaylandDisplay),
56 VK_ERROR_INITIALIZATION_FAILED);
57
58 wl_egl_window *eglWindow = reinterpret_cast<wl_egl_window *>(mNativeWindowType);
59
60 VkWaylandSurfaceCreateInfoKHR createInfo = {};
61
62 createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
63 createInfo.flags = 0;
64 createInfo.display = mWaylandDisplay;
65 createInfo.surface = eglWindow->surface;
66 ANGLE_VK_TRY(context, vkCreateWaylandSurfaceKHR(context->getRenderer()->getInstance(),
67 &createInfo, nullptr, &mSurface));
68
69 return getCurrentWindowSize(context, extentsOut);
70 }
71
getCurrentWindowSize(vk::Context * context,gl::Extents * extentsOut)72 angle::Result WindowSurfaceVkWayland::getCurrentWindowSize(vk::Context *context,
73 gl::Extents *extentsOut)
74 {
75 *extentsOut = mExtents;
76 return angle::Result::Continue;
77 }
78
getUserWidth(const egl::Display * display,EGLint * value) const79 egl::Error WindowSurfaceVkWayland::getUserWidth(const egl::Display *display, EGLint *value) const
80 {
81 *value = getWidth();
82 return egl::NoError();
83 }
84
getUserHeight(const egl::Display * display,EGLint * value) const85 egl::Error WindowSurfaceVkWayland::getUserHeight(const egl::Display *display, EGLint *value) const
86 {
87 *value = getHeight();
88 return egl::NoError();
89 }
90
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)91 angle::Result WindowSurfaceVkWayland::getAttachmentRenderTarget(
92 const gl::Context *context,
93 GLenum binding,
94 const gl::ImageIndex &imageIndex,
95 GLsizei samples,
96 FramebufferAttachmentRenderTarget **rtOut)
97 {
98 if (mResized)
99 {
100 // A wl_egl_window_resize() should take effect on the next operation which provokes a
101 // backbuffer to be pulled
102 ANGLE_TRY(doDeferredAcquireNextImage(context, true));
103 mResized = false;
104 }
105 return WindowSurfaceVk::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut);
106 }
107
108 } // namespace rx
109