From: Alexandros Frantzis alexandros.frantzis@collabora.com
Each WGL context is backed by an EGL context. --- dlls/winewayland.drv/opengl.c | 87 +++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index a7b8d0ba40d..621ee66d3ef 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -55,8 +55,11 @@ static const char *opengl_func_names[] = { ALL_WGL_FUNCS }; #undef USE_GL_FUNC
#define DECL_FUNCPTR(f) static __typeof__(f) * p_##f = NULL +DECL_FUNCPTR(eglBindAPI); DECL_FUNCPTR(eglChooseConfig); +DECL_FUNCPTR(eglCreateContext); DECL_FUNCPTR(eglCreateWindowSurface); +DECL_FUNCPTR(eglDestroyContext); DECL_FUNCPTR(eglDestroySurface); DECL_FUNCPTR(eglGetConfigAttrib); DECL_FUNCPTR(eglGetDisplay); @@ -67,17 +70,43 @@ DECL_FUNCPTR(eglInitialize);
static pthread_mutex_t gl_object_mutex = PTHREAD_MUTEX_INITIALIZER; static struct list gl_drawables = LIST_INIT(gl_drawables); +static struct list gl_contexts = LIST_INIT(gl_contexts);
struct wayland_gl_drawable { struct list entry; LONG ref; HWND hwnd; + int format; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; };
+struct wgl_context +{ + struct list entry; + EGLConfig config; + EGLContext context; +}; + +static struct wayland_gl_drawable *wayland_gl_drawable_get(HWND hwnd) +{ + struct wayland_gl_drawable *gl, *ret = NULL; + + pthread_mutex_lock(&gl_object_mutex); + LIST_FOR_EACH_ENTRY(gl, &gl_drawables, struct wayland_gl_drawable, entry) + { + if (gl->hwnd != hwnd) continue; + InterlockedIncrement(&gl->ref); + ret = gl; + break; + } + pthread_mutex_unlock(&gl_object_mutex); + + return ret; +} + static void wayland_gl_drawable_release(struct wayland_gl_drawable *gl) { if (InterlockedDecrement(&gl->ref)) return; @@ -110,6 +139,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for
gl->ref = 1; gl->hwnd = hwnd; + gl->format = format;
/* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the @@ -212,6 +242,57 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL internal) return TRUE; }
+static struct wgl_context *create_context(HDC hdc) +{ + struct wayland_gl_drawable *gl; + struct wgl_context *ctx; + + if (!(gl = wayland_gl_drawable_get(NtUserWindowFromDC(hdc)))) return NULL; + + if (!(ctx = calloc(1, sizeof(*ctx)))) + { + ERR("Failed to allocate memory for GL context\n"); + goto out; + } + + ctx->config = egl_configs[gl->format - 1]; + ctx->context = p_eglCreateContext(egl_display, ctx->config, EGL_NO_CONTEXT, NULL); + + pthread_mutex_lock(&gl_object_mutex); + list_add_head(&gl_contexts, &ctx->entry); + pthread_mutex_unlock(&gl_object_mutex); + + TRACE("ctx=%p egl_context=%p\n", ctx, ctx->context); + +out: + wayland_gl_drawable_release(gl); + return ctx; +} + +static BOOL wayland_wglCopyContext(struct wgl_context *src, + struct wgl_context *dst, UINT mask) +{ + FIXME("%p -> %p mask %#x unsupported\n", src, dst, mask); + return FALSE; +} + +static struct wgl_context *wayland_wglCreateContext(HDC hdc) +{ + TRACE("hdc=%p\n", hdc); + p_eglBindAPI(EGL_OPENGL_API); + return create_context(hdc); +} + +static BOOL wayland_wglDeleteContext(struct wgl_context *ctx) +{ + pthread_mutex_lock(&gl_object_mutex); + list_remove(&ctx->entry); + pthread_mutex_unlock(&gl_object_mutex); + p_eglDestroyContext(egl_display, ctx->context); + free(ctx); + return TRUE; +} + static BOOL has_opengl(void);
static int wayland_wglDescribePixelFormat(HDC hdc, int fmt, UINT size, @@ -417,8 +498,11 @@ static void init_opengl(void) if (!(p_##func = load_symbol(egl_handle, #func))) \ { ERR("Failed to load symbol %s\n", #func); goto err; } \ } while(0) + LOAD_FUNCPTR(eglBindAPI); LOAD_FUNCPTR(eglChooseConfig); + LOAD_FUNCPTR(eglCreateContext); LOAD_FUNCPTR(eglCreateWindowSurface); + LOAD_FUNCPTR(eglDestroyContext); LOAD_FUNCPTR(eglDestroySurface); LOAD_FUNCPTR(eglGetConfigAttrib); LOAD_FUNCPTR(eglGetDisplay); @@ -468,6 +552,9 @@ static struct opengl_funcs opengl_funcs = { .wgl = { + .p_wglCopyContext = wayland_wglCopyContext, + .p_wglCreateContext = wayland_wglCreateContext, + .p_wglDeleteContext = wayland_wglDeleteContext, .p_wglDescribePixelFormat = wayland_wglDescribePixelFormat, .p_wglGetProcAddress = wayland_wglGetProcAddress, .p_wglSetPixelFormat = wayland_wglSetPixelFormat,