From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winewayland.drv/opengl.c | 96 +++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 4692d2f1e15..5f52ae25b67 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -24,6 +24,7 @@
#include "config.h"
+#include <assert.h> #include <dlfcn.h> #include <stdlib.h> #include <string.h> @@ -92,6 +93,7 @@ struct wgl_context EGLConfig config; EGLContext context; struct wayland_gl_drawable *draw, *read, *new_draw, *new_read; + EGLint attribs[16]; };
/* lookup the existing drawable for a window, gl_object_mutex must be held */ @@ -320,6 +322,68 @@ static BOOL wgl_context_make_current(struct wgl_context *ctx, HWND draw_hwnd, return ret; }
+static BOOL wgl_context_populate_attribs(struct wgl_context *ctx, const int *attribs) +{ + EGLint *egl_attribs = ctx->attribs; + + if (!attribs) goto out; + + for (; attribs[0] != 0; attribs += 2) + { + EGLint name; + + TRACE("%#x %#x\n", attribs[0], attribs[1]); + + /* Find the EGL attribute names corresponding to the WGL names. + * For all of the attributes below, the values match between the two + * systems, so we can use them directly. */ + switch (attribs[0]) + { + case WGL_CONTEXT_MAJOR_VERSION_ARB: + name = EGL_CONTEXT_MAJOR_VERSION_KHR; + break; + case WGL_CONTEXT_MINOR_VERSION_ARB: + name = EGL_CONTEXT_MINOR_VERSION_KHR; + break; + case WGL_CONTEXT_FLAGS_ARB: + name = EGL_CONTEXT_FLAGS_KHR; + break; + case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: + name = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; + break; + case WGL_CONTEXT_PROFILE_MASK_ARB: + if (attribs[1] & WGL_CONTEXT_ES2_PROFILE_BIT_EXT) + { + ERR("OpenGL ES contexts are not supported\n"); + return FALSE; + } + name = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; + break; + default: + name = EGL_NONE; + FIXME("Unhandled attributes: %#x %#x\n", attribs[0], attribs[1]); + } + + if (name != EGL_NONE) + { + EGLint *dst = ctx->attribs; + /* Check if we have already set the same attribute and replace it. */ + for (; dst != egl_attribs && *dst != name; dst += 2) continue; + /* Our context attribute array should have enough space for all the + * attributes we support (we merge repetitions), plus EGL_NONE. */ + assert(dst - ctx->attribs <= ARRAY_SIZE(ctx->attribs) - 3); + dst[0] = name; + dst[1] = attribs[1]; + if (dst == egl_attribs) egl_attribs += 2; + } + } + +out: + *egl_attribs = EGL_NONE; + return TRUE; +} + + static void wgl_context_refresh(struct wgl_context *ctx) { BOOL refresh = FALSE; @@ -381,7 +445,8 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL internal) return TRUE; }
-static struct wgl_context *create_context(HDC hdc) +static struct wgl_context *create_context(HDC hdc, struct wgl_context *share, + const int *attribs) { struct wayland_gl_drawable *gl; struct wgl_context *ctx; @@ -394,8 +459,17 @@ static struct wgl_context *create_context(HDC hdc) goto out; }
+ if (!wgl_context_populate_attribs(ctx, attribs)) + { + ctx->attribs[0] = EGL_NONE; + goto out; + } + + /* For now only OpenGL is supported. */ + p_eglBindAPI(EGL_OPENGL_API); ctx->context = p_eglCreateContext(egl_display, EGL_NO_CONFIG_KHR, - EGL_NO_CONTEXT, NULL); + share ? share->context : EGL_NO_CONTEXT, + ctx->attribs);
pthread_mutex_lock(&gl_object_mutex); list_add_head(&gl_contexts, &ctx->entry); @@ -427,8 +501,15 @@ static BOOL wayland_wglCopyContext(struct wgl_context *src, static struct wgl_context *wayland_wglCreateContext(HDC hdc) { TRACE("hdc=%p\n", hdc); - p_eglBindAPI(EGL_OPENGL_API); - return create_context(hdc); + return create_context(hdc, NULL, NULL); +} + +static struct wgl_context *wayland_wglCreateContextAttribsARB(HDC hdc, + struct wgl_context *share, + const int *attribs) +{ + TRACE("hdc=%p share=%p attribs=%p\n", hdc, share, attribs); + return create_context(hdc, share, attribs); }
static BOOL wayland_wglDeleteContext(struct wgl_context *ctx) @@ -623,6 +704,11 @@ static BOOL init_opengl_funcs(void) opengl_funcs.ext.p_wglGetCurrentReadDCARB = (void *)1; /* never called */ opengl_funcs.ext.p_wglMakeContextCurrentARB = wayland_wglMakeContextCurrentARB;
+ register_extension("WGL_ARB_create_context"); + register_extension("WGL_ARB_create_context_no_error"); + register_extension("WGL_ARB_create_context_profile"); + opengl_funcs.ext.p_wglCreateContextAttribsARB = wayland_wglCreateContextAttribsARB; + return TRUE; }
@@ -751,6 +837,8 @@ static void init_opengl(void) if (!has_extension(egl_exts, #ext)) \ { ERR("Failed to find required extension %s\n", #ext); goto err; } \ } while(0) + REQUIRE_EXT(EGL_KHR_create_context); + REQUIRE_EXT(EGL_KHR_create_context_no_error); REQUIRE_EXT(EGL_KHR_no_config_context); #undef REQUIRE_EXT