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