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/RendererVk.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(), 0, mWaylandDisplay),
55 VK_ERROR_INITIALIZATION_FAILED);
56
57 wl_egl_window *eglWindow = reinterpret_cast<wl_egl_window *>(mNativeWindowType);
58
59 VkWaylandSurfaceCreateInfoKHR createInfo = {};
60
61 createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
62 createInfo.flags = 0;
63 createInfo.display = mWaylandDisplay;
64 createInfo.surface = eglWindow->surface;
65 ANGLE_VK_TRY(context, vkCreateWaylandSurfaceKHR(context->getRenderer()->getInstance(),
66 &createInfo, nullptr, &mSurface));
67
68 return getCurrentWindowSize(context, extentsOut);
69 }
70
getCurrentWindowSize(vk::Context * context,gl::Extents * extentsOut)71 angle::Result WindowSurfaceVkWayland::getCurrentWindowSize(vk::Context *context,
72 gl::Extents *extentsOut)
73 {
74 *extentsOut = mExtents;
75 return angle::Result::Continue;
76 }
77
getUserWidth(const egl::Display * display,EGLint * value) const78 egl::Error WindowSurfaceVkWayland::getUserWidth(const egl::Display *display, EGLint *value) const
79 {
80 *value = getWidth();
81 return egl::NoError();
82 }
83
getUserHeight(const egl::Display * display,EGLint * value) const84 egl::Error WindowSurfaceVkWayland::getUserHeight(const egl::Display *display, EGLint *value) const
85 {
86 *value = getHeight();
87 return egl::NoError();
88 }
89
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)90 angle::Result WindowSurfaceVkWayland::getAttachmentRenderTarget(
91 const gl::Context *context,
92 GLenum binding,
93 const gl::ImageIndex &imageIndex,
94 GLsizei samples,
95 FramebufferAttachmentRenderTarget **rtOut)
96 {
97 if (mResized)
98 {
99 // A wl_egl_window_resize() should take effect on the next operation which provokes a
100 // backbuffer to be pulled
101 ANGLE_TRY(doDeferredAcquireNextImage(context, true));
102 mResized = false;
103 }
104 return WindowSurfaceVk::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut);
105 }
106
107 } // namespace rx
108