From 4fb515a86d744e11f33ef058512a2d98ea8bc917 Mon Sep 17 00:00:00 2001 From: TellowKrinkle Date: Sun, 25 Jun 2023 22:37:15 -0500 Subject: [PATCH] VideoBackends:OGL: Wayland support --- Source/Core/Common/CMakeLists.txt | 7 +++ Source/Core/Common/GL/GLContext.cpp | 10 ++++ .../Core/Common/GL/GLInterface/EGLWayland.cpp | 47 +++++++++++++++++++ .../Core/Common/GL/GLInterface/EGLWayland.h | 28 +++++++++++ 4 files changed, 92 insertions(+) create mode 100644 Source/Core/Common/GL/GLInterface/EGLWayland.cpp create mode 100644 Source/Core/Common/GL/GLInterface/EGLWayland.h diff --git a/Source/Core/Common/CMakeLists.txt b/Source/Core/Common/CMakeLists.txt index 894fd38128..49d8402b1d 100644 --- a/Source/Core/Common/CMakeLists.txt +++ b/Source/Core/Common/CMakeLists.txt @@ -308,6 +308,13 @@ if(ENABLE_EGL AND EGL_FOUND) target_link_libraries(common PUBLIC ${EGL_LIBRARIES}) endif() +if(ENABLE_WAYLAND) + target_sources(common PRIVATE + GL/GLInterface/EGLWayland.cpp + GL/GLInterface/EGLWayland.h + ) +endif() + if(WIN32) target_sources(common PRIVATE CompatPatches.cpp diff --git a/Source/Core/Common/GL/GLContext.cpp b/Source/Core/Common/GL/GLContext.cpp index d2b0ae0076..67372c4f73 100644 --- a/Source/Core/Common/GL/GLContext.cpp +++ b/Source/Core/Common/GL/GLContext.cpp @@ -19,6 +19,9 @@ #if HAVE_X11 #include "Common/GL/GLInterface/EGLX11.h" #endif +#if HAVE_WAYLAND +#include "Common/GL/GLInterface/EGLWayland.h" +#endif #if defined(ANDROID) #include "Common/GL/GLInterface/EGLAndroid.h" #endif @@ -103,6 +106,13 @@ std::unique_ptr GLContext::Create(const WindowSystemInfo& wsi, bool s if (wsi.type == WindowSystemType::X11) context = std::make_unique(); #endif + +#endif +#if HAVE_WAYLAND && HAVE_EGL + if (wsi.type == WindowSystemType::Wayland) + context = std::make_unique(); +#endif +#if HAVE_EGL if (wsi.type == WindowSystemType::Headless || wsi.type == WindowSystemType::FBDev) context = std::make_unique(); #endif diff --git a/Source/Core/Common/GL/GLInterface/EGLWayland.cpp b/Source/Core/Common/GL/GLInterface/EGLWayland.cpp new file mode 100644 index 0000000000..1571f2de6f --- /dev/null +++ b/Source/Core/Common/GL/GLInterface/EGLWayland.cpp @@ -0,0 +1,47 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "Common/GL/GLInterface/EGLWayland.h" +#include "Common/MsgHandler.h" + +GLContextEGLWayland::~GLContextEGLWayland() +{ + if (m_window) + m_wl_egl_window_destroy(m_window); +} + +void GLContextEGLWayland::Update(u32 width, u32 height) +{ + GLContext::Update(width, height); + if (m_window) + m_wl_egl_window_resize(m_window, width, height, 0, 0); +} + +EGLDisplay GLContextEGLWayland::OpenEGLDisplay() +{ + return eglGetDisplay(static_cast(m_wsi.display_connection)); +} + +EGLNativeWindowType GLContextEGLWayland::GetEGLNativeWindow(EGLConfig config) +{ + if (!m_wayland_lib.IsOpen()) + { + std::string name = Common::DynamicLibrary::GetVersionedFilename("wayland-egl", 1); + m_wayland_lib.Open(name.c_str()); + if (!m_wayland_lib.IsOpen()) + { + PanicAlertFmt("Failed to load {}", name); + return reinterpret_cast(m_window); + } +#define LOAD(x) m_wayland_lib.GetSymbol(#x, &m_##x) + LOAD(wl_egl_window_create); + LOAD(wl_egl_window_destroy); + LOAD(wl_egl_window_resize); +#undef LOAD + } + if (m_window) + m_wl_egl_window_destroy(m_window); + m_window = m_wl_egl_window_create(static_cast(m_wsi.render_surface), + m_wsi.render_surface_width, m_wsi.render_surface_height); + return reinterpret_cast(m_window); +} diff --git a/Source/Core/Common/GL/GLInterface/EGLWayland.h b/Source/Core/Common/GL/GLInterface/EGLWayland.h new file mode 100644 index 0000000000..73cc90064b --- /dev/null +++ b/Source/Core/Common/GL/GLInterface/EGLWayland.h @@ -0,0 +1,28 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include "Common/DynamicLibrary.h" +#include "Common/GL/GLInterface/EGL.h" + +struct wl_egl_window; +struct wl_surface; + +class GLContextEGLWayland final : public GLContextEGL +{ +public: + ~GLContextEGLWayland() override; + + void Update(u32 width, u32 height) override; + +protected: + EGLDisplay OpenEGLDisplay() override; + EGLNativeWindowType GetEGLNativeWindow(EGLConfig config) override; + Common::DynamicLibrary m_wayland_lib; + wl_egl_window* (*m_wl_egl_window_create)(wl_surface* surface, int width, int height); + void (*m_wl_egl_window_destroy)(wl_egl_window* window); + void (*m_wl_egl_window_resize)(wl_egl_window* window, int width, int height, int dx, int dy); + wl_egl_window* m_window = nullptr; +};