diff --git a/configure b/configure
index 83a641ff542..ed3a1bd8295 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
@@ -16172,6 +16178,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 "$ac_cv_lib_soname_EGL"
+then :
+  case "x$with_opengl" in
+  x)   as_fn_append wine_notices "|EGL ${notice_platform}development files not found, the Wayland driver won't support OpenGL" ;;
+  xno) ;;
+  *)   as_fn_error $? "EGL ${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 :
@@ -23802,6 +23912,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 64083de89c4..7142eeb1a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1380,6 +1380,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 "$ac_cv_lib_soname_EGL"],
+                [EGL ${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..9f9b8909c41 100644
--- a/dlls/winewayland.drv/Makefile.in
+++ b/dlls/winewayland.drv/Makefile.in
@@ -1,11 +1,12 @@
 MODULE = winewayland.drv
 UNIXLIB = winewayland.so
-UNIX_CFLAGS = $(WAYLAND_CLIENT_CFLAGS) $(XKBCOMMON_CFLAGS) $(XKBREGISTRY_CFLAGS)
+UNIX_CFLAGS = $(EGL_CFLAGS) $(WAYLAND_CLIENT_CFLAGS) $(XKBCOMMON_CFLAGS) $(XKBREGISTRY_CFLAGS)
 UNIX_LIBS = -lwin32u $(WAYLAND_CLIENT_LIBS) $(XKBCOMMON_LIBS) $(XKBREGISTRY_LIBS) $(PTHREAD_LIBS) -lm
 
 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..765855e3944
--- /dev/null
+++ b/dlls/winewayland.drv/opengl.c
@@ -0,0 +1,163 @@
+/*
+ * 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 <string.h>
+
+#include "waylanddrv.h"
+#include "wine/debug.h"
+
+#if defined(SONAME_LIBEGL)
+
+WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
+
+#define WL_EGL_PLATFORM 1
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "wine/wgl.h"
+#include "wine/wgl_driver.h"
+
+static void *egl_handle;
+static struct opengl_funcs opengl_funcs;
+static EGLDisplay egl_display;
+
+#define DECL_FUNCPTR(f) static typeof(f) * p_##f
+DECL_FUNCPTR(eglGetError);
+DECL_FUNCPTR(eglGetPlatformDisplay);
+DECL_FUNCPTR(eglGetProcAddress);
+DECL_FUNCPTR(eglInitialize);
+DECL_FUNCPTR(eglQueryString);
+#undef DECL_FUNCPTR
+
+static BOOL has_extension(const char *list, const char *ext)
+{
+    size_t len = strlen(ext);
+    const char *cur = list;
+
+    while (cur && (cur = strstr(cur, ext)))
+    {
+        if ((!cur[len] || cur[len] == ' ') && (cur == list || cur[-1] == ' '))
+            return TRUE;
+        cur = strchr(cur, ' ');
+    }
+
+    return FALSE;
+}
+
+static void init_opengl(void)
+{
+    EGLint egl_version[2];
+    const char *egl_client_exts;
+
+    if (!(egl_handle = dlopen(SONAME_LIBEGL, RTLD_NOW|RTLD_GLOBAL)))
+    {
+        ERR("Failed to load %s: %s\n", SONAME_LIBEGL, dlerror());
+        return;
+    }
+
+#define LOAD_FUNCPTR_DLSYM(func) \
+    do { \
+        if (!(p_##func = dlsym(egl_handle, #func))) \
+            { ERR("Failed to load symbol %s\n", #func); goto err; } \
+    } while(0)
+    LOAD_FUNCPTR_DLSYM(eglGetProcAddress);
+    LOAD_FUNCPTR_DLSYM(eglQueryString);
+#undef LOAD_FUNCPTR_DLSYM
+
+    egl_client_exts = p_eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+
+#define REQUIRE_CLIENT_EXT(ext) \
+    do { \
+        if (!has_extension(egl_client_exts, #ext)) \
+            { ERR("Failed to find required extension %s\n", #ext); goto err; } \
+    } while(0)
+    REQUIRE_CLIENT_EXT(EGL_KHR_client_get_all_proc_addresses);
+    REQUIRE_CLIENT_EXT(EGL_KHR_platform_wayland);
+#undef REQUIRE_CLIENT_EXT
+
+#define LOAD_FUNCPTR_EGL(func) \
+    do { \
+        if (!(p_##func = (void *)p_eglGetProcAddress(#func))) \
+            { ERR("Failed to load symbol %s\n", #func); goto err; } \
+    } while(0)
+    LOAD_FUNCPTR_EGL(eglGetError);
+    LOAD_FUNCPTR_EGL(eglGetPlatformDisplay);
+    LOAD_FUNCPTR_EGL(eglInitialize);
+#undef LOAD_FUNCPTR_EGL
+
+    egl_display = p_eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR,
+                                          process_wayland.wl_display,
+                                          NULL);
+    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:
+    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)