From: Alexandros Frantzis alexandros.frantzis@collabora.com
The driver performs basic EGL initialization. --- configure | 112 ++++++++++++++++++++ configure.ac | 11 ++ dlls/winewayland.drv/Makefile.in | 1 + dlls/winewayland.drv/opengl.c | 136 +++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/waylanddrv_main.c | 1 + 6 files changed, 262 insertions(+) create mode 100644 dlls/winewayland.drv/opengl.c
diff --git a/configure b/configure index 5e1b3765413..a96f0172579 100755 --- a/configure +++ b/configure @@ -702,6 +702,8 @@ INOTIFY_LIBS INOTIFY_CFLAGS PCSCLITE_LIBS PCAP_LIBS +EGL_LIBS +EGL_CFLAGS XKBREGISTRY_LIBS XKBREGISTRY_CFLAGS XKBCOMMON_LIBS @@ -1803,6 +1805,8 @@ XKBCOMMON_CFLAGS XKBCOMMON_LIBS XKBREGISTRY_CFLAGS XKBREGISTRY_LIBS +EGL_CFLAGS +EGL_LIBS INOTIFY_CFLAGS INOTIFY_LIBS DBUS_CFLAGS @@ -2629,6 +2633,8 @@ Some influential environment variables: C compiler flags for xkbregistry, overriding pkg-config XKBREGISTRY_LIBS Linker flags for xkbregistry, overriding pkg-config + EGL_CFLAGS C compiler flags for egl, overriding pkg-config + EGL_LIBS Linker flags for egl, overriding pkg-config INOTIFY_CFLAGS C compiler flags for libinotify, overriding pkg-config INOTIFY_LIBS @@ -16137,6 +16143,110 @@ fi
CPPFLAGS=$ac_save_CPPFLAGS
+ if test "x$with_opengl" != "xno" + then + rm -f conftest.err +if ${EGL_CFLAGS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + EGL_CFLAGS=`$PKG_CONFIG --cflags egl 2>conftest.err` +fi +fi + +if ${EGL_LIBS:+false} : +then : + if test ${PKG_CONFIG+y} +then : + EGL_LIBS=`$PKG_CONFIG --libs egl 2>/dev/null` +fi +fi + +EGL_LIBS=${EGL_LIBS:-"-lEGL"} +printf "%s\n" "$as_me:${as_lineno-$LINENO}: egl cflags: $EGL_CFLAGS" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: egl libs: $EGL_LIBS" >&5 +if test -s conftest.err; then + printf %s "$as_me:${as_lineno-$LINENO}: egl errors: " >&5 + cat conftest.err >&5 +fi +rm -f conftest.err +ac_save_CPPFLAGS=$CPPFLAGS +CPPFLAGS="$CPPFLAGS $EGL_CFLAGS" +ac_fn_c_check_header_compile "$LINENO" "EGL/egl.h" "ac_cv_header_EGL_egl_h" "$ac_includes_default" +if test "x$ac_cv_header_EGL_egl_h" = xyes +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -lEGL" >&5 +printf %s "checking for -lEGL... " >&6; } +if test ${ac_cv_lib_soname_EGL+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_soname_save_LIBS=$LIBS +LIBS="-lEGL $EGL_LIBS $LIBS" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char eglGetProcAddress (); +int +main (void) +{ +return eglGetProcAddress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + case "$LIBEXT" in + dll) ac_cv_lib_soname_EGL=`$ac_cv_path_LDD conftest.exe | grep "EGL" | sed -e "s/dll.*/dll/"';2,$d'` ;; + dylib) ac_cv_lib_soname_EGL=`$OTOOL -L conftest$ac_exeext | grep "libEGL\.[0-9A-Za-z.]*dylib" | sed -e "s/^.*/(libEGL.[0-9A-Za-z.]*dylib).*$/\1/"';2,$d'` ;; + *) ac_cv_lib_soname_EGL=`$READELF -d conftest$ac_exeext | grep "NEEDED.*libEGL\.$LIBEXT" | sed -e "s/^.*\[\(libEGL\.$LIBEXT[^ ]*\)\].*$/\1/"';2,$d'` + if ${ac_cv_lib_soname_EGL:+false} : +then : + ac_cv_lib_soname_EGL=`$LDD conftest$ac_exeext | grep "libEGL\.$LIBEXT" | sed -e "s/^.*(libEGL.$LIBEXT[^ ]*).*$/\1/"';2,$d'` +fi ;; + esac +else $as_nop + ac_cv_lib_soname_EGL= +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LIBS=$ac_check_soname_save_LIBS +fi +if ${ac_cv_lib_soname_EGL:+false} : +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5 +printf "%s\n" "not found" >&6; } + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_soname_EGL" >&5 +printf "%s\n" "$ac_cv_lib_soname_EGL" >&6; } + +printf "%s\n" "#define SONAME_LIBEGL "$ac_cv_lib_soname_EGL"" >>confdefs.h + + +fi +fi + +CPPFLAGS=$ac_save_CPPFLAGS + + if test "x$with_wayland" != "x" + then + if test -z "$SONAME_LIBEGL" +then : + case "x$with_opengl" in + x) as_fn_append wine_notices "|Wayland EGL/GL ${notice_platform}development files not found, the Wayland driver won't support OpenGL" ;; + xno) ;; + *) as_fn_error $? "Wayland EGL/GL ${notice_platform}development files not found, the Wayland driver won't support OpenGL +This is an error since --with-opengl was requested." "$LINENO" 5 ;; +esac + +fi + fi + fi fi if test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o -z "$XKBREGISTRY_LIBS" -o "$ac_cv_header_linux_input_h" = "no" then : @@ -23738,6 +23848,8 @@ XKBCOMMON_CFLAGS = $XKBCOMMON_CFLAGS XKBCOMMON_LIBS = $XKBCOMMON_LIBS XKBREGISTRY_CFLAGS = $XKBREGISTRY_CFLAGS XKBREGISTRY_LIBS = $XKBREGISTRY_LIBS +EGL_CFLAGS = $EGL_CFLAGS +EGL_LIBS = $EGL_LIBS PCAP_LIBS = $PCAP_LIBS PCSCLITE_LIBS = $PCSCLITE_LIBS INOTIFY_CFLAGS = $INOTIFY_CFLAGS diff --git a/configure.ac b/configure.ac index 1c59651ba1e..9af42badc31 100644 --- a/configure.ac +++ b/configure.ac @@ -1377,6 +1377,17 @@ then WINE_PACKAGE_FLAGS(XKBREGISTRY,[xkbregistry],,,, [AC_CHECK_HEADERS([xkbcommon/xkbregistry.h]) AC_CHECK_LIB(xkbregistry,rxkb_context_new,[:],[XKBREGISTRY_LIBS=""],[$XKBREGISTRY_LIBS])]) + if test "x$with_opengl" != "xno" + then + WINE_PACKAGE_FLAGS(EGL,[egl],[-lEGL],,, + [AC_CHECK_HEADER([EGL/egl.h], + [WINE_CHECK_SONAME(EGL,eglGetProcAddress,,,[$EGL_LIBS])])]) + if test "x$with_wayland" != "x" + then + WINE_NOTICE_WITH(opengl, [test -z "$SONAME_LIBEGL"], + [Wayland EGL/GL ${notice_platform}development files not found, the Wayland driver won't support OpenGL]) + fi + fi fi WINE_NOTICE_WITH(wayland, [test -z "$WAYLAND_CLIENT_LIBS" -o -z "$WAYLAND_SCANNER" -o -z "$XKBCOMMON_LIBS" -o -z "$XKBREGISTRY_LIBS" -o "$ac_cv_header_linux_input_h" = "no"], [Wayland ${notice_platform}development files not found, the Wayland driver won't be supported.], diff --git a/dlls/winewayland.drv/Makefile.in b/dlls/winewayland.drv/Makefile.in index b47bdb262c0..e9e16b474ba 100644 --- a/dlls/winewayland.drv/Makefile.in +++ b/dlls/winewayland.drv/Makefile.in @@ -6,6 +6,7 @@ UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(XKBCOMMON_LIBS) $(XKBREGISTRY_LIBS SOURCES = \ display.c \ dllmain.c \ + opengl.c \ pointer-constraints-unstable-v1.xml \ relative-pointer-unstable-v1.xml \ version.rc \ diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c new file mode 100644 index 00000000000..54ae281c86a --- /dev/null +++ b/dlls/winewayland.drv/opengl.c @@ -0,0 +1,136 @@ +/* + * Wayland OpenGL functions + * + * Copyright 2020 Alexandros Frantzis for Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <dlfcn.h> + +#include "waylanddrv.h" +#include "wine/debug.h" + +#if defined(SONAME_LIBEGL) + +WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv); + +#include <EGL/egl.h> + +#include "wine/wgl.h" +#include "wine/wgl_driver.h" + +static void *egl_handle; +static struct opengl_funcs opengl_funcs; +static EGLDisplay egl_display; +static EGLint egl_version[2]; + +#define DECL_FUNCPTR(f) static __typeof__(f) * p_##f = NULL +DECL_FUNCPTR(eglGetDisplay); +DECL_FUNCPTR(eglGetError); +DECL_FUNCPTR(eglGetProcAddress); +DECL_FUNCPTR(eglInitialize); +#undef DECL_FUNCPTR + +static void* load_symbol(void *handle, const char *symbol) +{ + void *addr; + if (!(addr = dlsym(handle, symbol))) addr = p_eglGetProcAddress(symbol); + return addr; +} + +static void init_opengl(void) +{ + if (!(egl_handle = dlopen(SONAME_LIBEGL, RTLD_NOW|RTLD_GLOBAL))) + { + ERR("Failed to load %s: %s\n", SONAME_LIBEGL, dlerror()); + goto err; + } + + if (!(p_eglGetProcAddress = dlsym(egl_handle, "eglGetProcAddress"))) + { + ERR("Failed to load eglGetProcAddress\n"); + goto err; + } + +#define LOAD_FUNCPTR(func) \ + do { \ + if (!(p_##func = load_symbol(egl_handle, #func))) \ + { ERR("Failed to load symbol %s\n", #func); goto err; } \ + } while(0) + LOAD_FUNCPTR(eglGetDisplay); + LOAD_FUNCPTR(eglGetError); + LOAD_FUNCPTR(eglInitialize); +#undef LOAD_FUNCPTR + + egl_display = p_eglGetDisplay((EGLNativeDisplayType)process_wayland.wl_display); + if (egl_display == EGL_NO_DISPLAY) + { + ERR("Failed to get EGLDisplay\n"); + goto err; + } + if (!p_eglInitialize(egl_display, &egl_version[0], &egl_version[1])) + { + ERR("Failed to initialized EGLDisplay with error %d\n", p_eglGetError()); + goto err; + } + TRACE("EGL version %u.%u\n", egl_version[0], egl_version[1]); + + return; + +err: + if (egl_handle) + { + dlclose(egl_handle); + egl_handle = NULL; + } +} + +static BOOL has_opengl(void) +{ + static pthread_once_t init_once = PTHREAD_ONCE_INIT; + + return !pthread_once(&init_once, init_opengl) && egl_handle; +} + +/********************************************************************** + * WAYLAND_wine_get_wgl_driver + */ +struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version) +{ + if (version != WINE_WGL_DRIVER_VERSION) + { + ERR("Version mismatch, opengl32 wants %u but driver has %u\n", + version, WINE_WGL_DRIVER_VERSION); + return NULL; + } + if (!has_opengl()) return NULL; + return &opengl_funcs; +} + +#else /* No GL */ + +struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version) +{ + return NULL; +} + +#endif diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index f030f6fc6a0..66806503edf 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -332,5 +332,6 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect, struct window_surface **surface); const struct vulkan_funcs *WAYLAND_wine_get_vulkan_driver(UINT version); +struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
#endif /* __WINE_WAYLANDDRV_H */ diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index b60d282aacb..ca73cd4c97d 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -43,6 +43,7 @@ static const struct user_driver_funcs waylanddrv_funcs = .pWindowPosChanged = WAYLAND_WindowPosChanged, .pWindowPosChanging = WAYLAND_WindowPosChanging, .pwine_get_vulkan_driver = WAYLAND_wine_get_vulkan_driver, + .pwine_get_wgl_driver = WAYLAND_wine_get_wgl_driver, };
static NTSTATUS waylanddrv_unix_init(void *arg)