-- v3: winex11: Add an option to use the new EGL OpenGL backend. winex11: Remove now unnecessary x11drv_context structure. win32u: Move EGL make_current context function out of the drivers. win32u: Add an EGLSurface pointer to opengl_drawable struct. win32u: Add traces to wglGetExtensionsString*.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index a2e5a29ffd8..d7ebb386867 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -787,12 +787,14 @@ static char wgl_extensions[4096];
static const char *win32u_wglGetExtensionsStringARB( HDC hdc ) { + TRACE( "hdc %p\n", hdc ); if (TRACE_ON(wgl)) dump_extensions( wgl_extensions ); return wgl_extensions; }
static const char *win32u_wglGetExtensionsStringEXT(void) { + TRACE( "\n" ); if (TRACE_ON(wgl)) dump_extensions( wgl_extensions ); return wgl_extensions; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 4 ++++ dlls/wineandroid.drv/opengl.c | 15 ++++++--------- dlls/winewayland.drv/opengl.c | 14 ++++++-------- dlls/winex11.drv/opengl.c | 1 - include/wine/opengl_driver.h | 1 + 5 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index d7ebb386867..781b9df159d 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -243,11 +243,15 @@ void opengl_drawable_release( struct opengl_drawable *drawable )
if (!ref) { + const struct opengl_funcs *funcs = &display_funcs; + const struct egl_platform *egl = &display_egl; + pthread_mutex_lock( &drawables_lock ); opengl_drawable_detach( drawable ); pthread_mutex_unlock( &drawables_lock );
drawable->funcs->destroy( drawable ); + if (drawable->surface) funcs->p_eglDestroySurface( egl->display, drawable->surface ); free( drawable ); } } diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index c3c77b03170..6d4e67fb4e0 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -53,9 +53,7 @@ static const struct opengl_drawable_funcs android_drawable_funcs; struct gl_drawable { struct opengl_drawable base; - struct list entry; ANativeWindow *window; - EGLSurface surface; };
static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) @@ -82,8 +80,8 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, A if (!window) gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); else gl->window = grab_ioctl_window( window );
- if (!window) gl->surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); - else gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL ); + if (!window) gl->base.surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); + else gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL );
TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; @@ -92,7 +90,6 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, A static void android_drawable_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); - if (gl->surface) funcs->p_eglDestroySurface( egl->display, gl->surface ); release_ioctl_window( gl->window ); }
@@ -153,7 +150,7 @@ static BOOL android_make_current( struct opengl_drawable *draw_base, struct open { struct gl_drawable *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), context ); - return funcs->p_eglMakeCurrent( egl->display, context ? draw->surface : EGL_NO_SURFACE, context ? read->surface : EGL_NO_SURFACE, context ); + return funcs->p_eglMakeCurrent( egl->display, context ? draw->base.surface : EGL_NO_SURFACE, context ? read->base.surface : EGL_NO_SURFACE, context ); }
static EGLenum android_init_egl_platform( const struct egl_platform *platform, EGLNativeDisplayType *platform_display ) @@ -174,9 +171,9 @@ static BOOL android_drawable_swap( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->surface ); + TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->base.surface );
- funcs->p_eglSwapBuffers( egl->display, gl->surface ); + funcs->p_eglSwapBuffers( egl->display, gl->base.surface ); return TRUE; }
@@ -184,7 +181,7 @@ static void android_drawable_flush( struct opengl_drawable *base, UINT flags ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "drawable %s, surface %p, flags %#x\n", debugstr_opengl_drawable( base ), gl->surface, flags ); + TRACE( "drawable %s, surface %p, flags %#x\n", debugstr_opengl_drawable( base ), gl->base.surface, flags );
if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); } diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index bfc3ac7518f..bd84ea43932 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -51,7 +51,6 @@ struct wayland_gl_drawable struct opengl_drawable base; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; - EGLSurface surface; BOOL double_buffered; };
@@ -64,7 +63,6 @@ static void wayland_drawable_destroy(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- if (gl->surface) funcs->p_eglDestroySurface(egl->display, gl->surface); if (gl->wl_egl_window) wl_egl_window_destroy(gl->wl_egl_window); if (gl->client) { @@ -131,9 +129,9 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc goto err; }
- gl->surface = funcs->p_eglCreateWindowSurface(egl->display, egl_config_for_format(format), - gl->wl_egl_window, attribs); - if (!gl->surface) + gl->base.surface = funcs->p_eglCreateWindowSurface(egl->display, egl_config_for_format(format), + gl->wl_egl_window, attribs); + if (!gl->base.surface) { ERR("Failed to create EGL surface\n"); goto err; @@ -141,7 +139,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc
gl->double_buffered = is_onscreen_format(format);
- TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->surface); + TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface);
return gl;
@@ -167,7 +165,7 @@ static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct openg { struct wayland_gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), context); - return funcs->p_eglMakeCurrent(egl->display, context ? draw->surface : EGL_NO_SURFACE, context ? read->surface : EGL_NO_SURFACE, context); + return funcs->p_eglMakeCurrent(egl->display, context ? draw->base.surface : EGL_NO_SURFACE, context ? read->base.surface : EGL_NO_SURFACE, context); }
static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) @@ -218,7 +216,7 @@ static BOOL wayland_drawable_swap(struct opengl_drawable *base)
/* Although all the EGL surfaces we create are double-buffered, we want to * use some as single-buffered, so avoid swapping those. */ - if (gl->double_buffered) funcs->p_eglSwapBuffers(egl->display, gl->surface); + if (gl->double_buffered) funcs->p_eglSwapBuffers(egl->display, gl->base.surface);
return TRUE; } diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 80554860bdc..6d4c1144506 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -883,7 +883,6 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd, hdc ))) return FALSE; - /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI there is no way to query it. */ gl->rect = rect;
gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 55d862c9dfe..188c7b81249 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -157,6 +157,7 @@ struct opengl_drawable HDC hdc; /* DC the drawable was created for */ struct list entry; /* entry in win32u managed list */ LONG updated; /* has been moved / resized / reparented */ + EGLSurface surface; /* surface for EGL based drivers */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 10 +++++++--- dlls/wineandroid.drv/opengl.c | 9 +-------- dlls/winewayland.drv/opengl.c | 9 +-------- 3 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 781b9df159d..65318895a65 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -575,10 +575,14 @@ static BOOL egldrv_context_destroy( void *context ) return TRUE; }
-static BOOL egldrv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) +static BOOL egldrv_make_current( struct opengl_drawable *draw, struct opengl_drawable *read, void *context ) { - FIXME( "stub!\n" ); - return FALSE; + const struct opengl_funcs *funcs = &display_funcs; + const struct egl_platform *egl = &display_egl; + + TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw ), debugstr_opengl_drawable( read ), context ); + + return funcs->p_eglMakeCurrent( egl->display, context ? draw->surface : EGL_NO_SURFACE, context ? read->surface : EGL_NO_SURFACE, context ); }
static const struct opengl_driver_funcs egldrv_funcs = diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 6d4e67fb4e0..ba72dbd4979 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -146,13 +146,6 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg return TRUE; }
-static BOOL android_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *context ) -{ - struct gl_drawable *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); - TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), context ); - return funcs->p_eglMakeCurrent( egl->display, context ? draw->base.surface : EGL_NO_SURFACE, context ? read->base.surface : EGL_NO_SURFACE, context ); -} - static EGLenum android_init_egl_platform( const struct egl_platform *platform, EGLNativeDisplayType *platform_display ) { egl = platform; @@ -197,7 +190,6 @@ static struct opengl_driver_funcs android_driver_funcs = .p_get_proc_address = android_get_proc_address, .p_init_wgl_extensions = android_init_wgl_extensions, .p_surface_create = android_surface_create, - .p_make_current = android_make_current, };
static const struct opengl_drawable_funcs android_drawable_funcs = @@ -231,6 +223,7 @@ UINT ANDROID_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, android_driver_funcs.p_describe_pixel_format = (*driver_funcs)->p_describe_pixel_format; android_driver_funcs.p_context_create = (*driver_funcs)->p_context_create; android_driver_funcs.p_context_destroy = (*driver_funcs)->p_context_destroy; + android_driver_funcs.p_make_current = (*driver_funcs)->p_make_current;
*driver_funcs = &android_driver_funcs; return STATUS_SUCCESS; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index bd84ea43932..9f1660a80a6 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -161,13 +161,6 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); }
-static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *context) -{ - struct wayland_gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); - TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), context); - return funcs->p_eglMakeCurrent(egl->display, context ? draw->base.surface : EGL_NO_SURFACE, context ? read->base.surface : EGL_NO_SURFACE, context); -} - static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { struct opengl_drawable *previous; @@ -249,7 +242,6 @@ static struct opengl_driver_funcs wayland_driver_funcs = { .p_init_egl_platform = wayland_init_egl_platform, .p_surface_create = wayland_opengl_surface_create, - .p_make_current = wayland_make_current, .p_pbuffer_create = wayland_pbuffer_create, .p_pbuffer_updated = wayland_pbuffer_updated, .p_pbuffer_bind = wayland_pbuffer_bind, @@ -285,6 +277,7 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c wayland_driver_funcs.p_init_wgl_extensions = (*driver_funcs)->p_init_wgl_extensions; wayland_driver_funcs.p_context_create = (*driver_funcs)->p_context_create; wayland_driver_funcs.p_context_destroy = (*driver_funcs)->p_context_destroy; + wayland_driver_funcs.p_make_current = (*driver_funcs)->p_make_current;
*driver_funcs = &wayland_driver_funcs; return STATUS_SUCCESS;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 148 ++++++++++++++++---------------------- 1 file changed, 62 insertions(+), 86 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 6d4c1144506..9a0c8c69ec2 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -194,11 +194,6 @@ struct glx_pixel_format DWORD dwFlags; /* We store some PFD_* flags in here for emulated bitmap formats */ };
-struct x11drv_context -{ - GLXContext ctx; -}; - struct gl_drawable { struct opengl_drawable base; @@ -860,7 +855,7 @@ static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) return ret; }
-static GLXContext create_glxcontext( struct x11drv_context *context, int format, GLXContext share, const int *attribs ) +static GLXContext create_glxcontext( int format, GLXContext share, const int *attribs ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); GLXContext ctx; @@ -1178,14 +1173,10 @@ static BOOL x11drv_describe_pixel_format( int format, struct wgl_pixel_format *p /*********************************************************************** * glxdrv_wglDeleteContext */ -static BOOL x11drv_context_destroy(void *private) +static BOOL x11drv_context_destroy( void *context ) { - struct x11drv_context *ctx = private; - - TRACE("(%p)\n", ctx); - - if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); - free( ctx ); + TRACE("(%p)\n", context); + pglXDestroyContext( gdi_display, context ); return TRUE; }
@@ -1196,24 +1187,16 @@ static void *x11drv_get_proc_address( const char *name ) return pglXGetProcAddressARB( (const GLubyte *)name ); }
-static BOOL x11drv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) +static BOOL x11drv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *context ) { struct gl_drawable *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); - struct x11drv_context *ctx = private; BOOL ret;
- TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), private ); - - if (!private) - { - pglXMakeCurrent( gdi_display, None, NULL ); - NtCurrentTeb()->glReserved2 = NULL; - return TRUE; - } + TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), context );
- if (!pglXMakeContextCurrent) ret = pglXMakeCurrent( gdi_display, draw->drawable, ctx->ctx ); - else ret = pglXMakeContextCurrent( gdi_display, draw->drawable, read->drawable, ctx->ctx ); - NtCurrentTeb()->glReserved2 = ctx; + if (!pglXMakeContextCurrent || !context) ret = pglXMakeCurrent( gdi_display, context ? draw->drawable : None, context ); + else ret = pglXMakeContextCurrent( gdi_display, draw->drawable, read->drawable, context ); + if (ret) NtCurrentTeb()->glReserved2 = context; return ret; }
@@ -1271,78 +1254,71 @@ static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags ) /*********************************************************************** * X11DRV_wglCreateContextAttribsARB */ -static BOOL x11drv_context_create( int format, void *share_private, const int *attribList, void **private ) +static BOOL x11drv_context_create( int format, void *share, const int *attribList, void **context ) { - struct x11drv_context *ret, *hShareContext = share_private; int glx_attribs[16] = {0}, *pContextAttribList = glx_attribs; int err = 0;
- TRACE("(%d %p %p)\n", format, hShareContext, attribList); + TRACE("(%d %p %p)\n", format, share, attribList);
- if ((ret = calloc( 1, sizeof(*ret) ))) + if (attribList) { - if (attribList) + /* attribList consists of pairs {token, value] terminated with 0 */ + while(attribList[0] != 0) { - /* attribList consists of pairs {token, value] terminated with 0 */ - while(attribList[0] != 0) + TRACE("%#x %#x\n", attribList[0], attribList[1]); + switch(attribList[0]) { - TRACE("%#x %#x\n", attribList[0], attribList[1]); - switch(attribList[0]) - { - case WGL_CONTEXT_MAJOR_VERSION_ARB: - pContextAttribList[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - case WGL_CONTEXT_MINOR_VERSION_ARB: - pContextAttribList[0] = GLX_CONTEXT_MINOR_VERSION_ARB; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - case WGL_CONTEXT_LAYER_PLANE_ARB: - break; - case WGL_CONTEXT_FLAGS_ARB: - pContextAttribList[0] = GLX_CONTEXT_FLAGS_ARB; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: - pContextAttribList[0] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - case WGL_CONTEXT_PROFILE_MASK_ARB: - pContextAttribList[0] = GLX_CONTEXT_PROFILE_MASK_ARB; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - case WGL_RENDERER_ID_WINE: - pContextAttribList[0] = GLX_RENDERER_ID_MESA; - pContextAttribList[1] = attribList[1]; - pContextAttribList += 2; - break; - default: - ERR("Unhandled attribList pair: %#x %#x\n", attribList[0], attribList[1]); - } - attribList += 2; + case WGL_CONTEXT_MAJOR_VERSION_ARB: + pContextAttribList[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + case WGL_CONTEXT_MINOR_VERSION_ARB: + pContextAttribList[0] = GLX_CONTEXT_MINOR_VERSION_ARB; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + case WGL_CONTEXT_LAYER_PLANE_ARB: + break; + case WGL_CONTEXT_FLAGS_ARB: + pContextAttribList[0] = GLX_CONTEXT_FLAGS_ARB; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: + pContextAttribList[0] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + case WGL_CONTEXT_PROFILE_MASK_ARB: + pContextAttribList[0] = GLX_CONTEXT_PROFILE_MASK_ARB; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + case WGL_RENDERER_ID_WINE: + pContextAttribList[0] = GLX_RENDERER_ID_MESA; + pContextAttribList[1] = attribList[1]; + pContextAttribList += 2; + break; + default: + ERR("Unhandled attribList pair: %#x %#x\n", attribList[0], attribList[1]); } + attribList += 2; } + }
- X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL); - ret->ctx = create_glxcontext( ret, format, hShareContext ? hShareContext->ctx : NULL, - attribList ? glx_attribs : NULL ); - XSync(gdi_display, False); - if ((err = X11DRV_check_error()) || !ret->ctx) - { - /* In the future we should convert the GLX error to a win32 one here if needed */ - WARN("Context creation failed (error %#x).\n", err); - free( ret ); - return FALSE; - } + X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL); + *context = create_glxcontext( format, share, attribList ? glx_attribs : NULL ); + XSync(gdi_display, False); + if ((err = X11DRV_check_error()) || !*context) + { + /* In the future we should convert the GLX error to a win32 one here if needed */ + WARN("Context creation failed (error %#x).\n", err); + return FALSE; }
- TRACE( "-> %p\n", ret ); - *private = ret; + TRACE( "-> %p\n", *context ); return TRUE; }
@@ -1533,7 +1509,7 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs )
static BOOL x11drv_surface_swap( struct opengl_drawable *base ) { - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; + GLXContext ctx = NtCurrentTeb()->glReserved2; struct gl_drawable *gl = impl_from_opengl_drawable( base ); INT64 ust, msc, sbc, target_sbc = 0;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 1 + dlls/winex11.drv/opengl.c | 125 ++++++++++++++++++++++++++++++++- dlls/winex11.drv/x11drv.h | 1 + dlls/winex11.drv/x11drv_main.c | 4 ++ include/wine/wgl.h | 2 + 5 files changed, 131 insertions(+), 2 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 17e44ec824a..4d3cc0562cc 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -775,6 +775,7 @@ my %supported_egl_extensions = "EGL_KHR_no_config_context" => 1, "EGL_KHR_platform_android" => 1, "EGL_KHR_platform_wayland" => 1, + "EGL_KHR_platform_x11" => 1, );
my %supported_apis = diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 9a0c8c69ec2..547608aa79f 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -222,6 +222,7 @@ enum glx_swap_control_method
static struct glx_pixel_format *pixel_formats; static int nb_pixel_formats, nb_onscreen_formats; +static const struct egl_platform *egl;
/* Selects the preferred GLX swap control method for use by wglSwapIntervalEXT */ static enum glx_swap_control_method swap_control_method = GLX_SWAP_CONTROL_NONE; @@ -324,9 +325,10 @@ static const GLubyte *(*pglGetString)(GLenum name);
static void *opengl_handle; static const struct opengl_funcs *funcs; -static const struct opengl_driver_funcs x11drv_driver_funcs; +static struct opengl_driver_funcs x11drv_driver_funcs; static const struct opengl_drawable_funcs x11drv_surface_funcs; static const struct opengl_drawable_funcs x11drv_pbuffer_funcs; +static const struct opengl_drawable_funcs x11drv_egl_surface_funcs;
/* check if the extension is present in the list */ static BOOL has_extension( const char *list, const char *ext ) @@ -468,6 +470,50 @@ done: return ret; }
+static EGLenum x11drv_init_egl_platform( const struct egl_platform *platform, EGLNativeDisplayType *platform_display ) +{ + egl = platform; + *platform_display = gdi_display; + return EGL_PLATFORM_X11_KHR; +} + +static inline EGLConfig egl_config_for_format(int format) +{ + assert(format > 0 && format <= 2 * egl->config_count); + if (format <= egl->config_count) return egl->configs[format - 1]; + return egl->configs[format - egl->config_count - 1]; +} + +static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) +{ + struct opengl_drawable *previous; + struct gl_drawable *gl; + RECT rect; + + if ((previous = *drawable) && previous->format == format) return TRUE; + NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) ); + + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, hwnd, hdc ))) return FALSE; + gl->rect = rect; + + gl->window = create_client_window( hwnd, &default_visual, default_colormap ); + gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(format), + (void *)gl->window, NULL ); + if (!gl->base.surface) + { + destroy_client_window( hwnd, gl->window ); + free( gl ); + return FALSE; + } + + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); + XFlush( gdi_display ); + + if (previous) opengl_drawable_release( previous ); + *drawable = &gl->base; + return TRUE; +} + /********************************************************************** * X11DRV_OpenglInit */ @@ -482,6 +528,17 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c } funcs = opengl_funcs;
+ if (use_egl) + { + if (!opengl_funcs->egl_handle) return STATUS_NOT_SUPPORTED; + WARN( "Using experimental EGL OpenGL backend\n" ); + x11drv_driver_funcs = **driver_funcs; + x11drv_driver_funcs.p_init_egl_platform = x11drv_init_egl_platform; + x11drv_driver_funcs.p_surface_create = x11drv_egl_surface_create; + *driver_funcs = &x11drv_driver_funcs; + return STATUS_SUCCESS; + } + /* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and include all dependencies */ opengl_handle = dlopen( SONAME_LIBGL, RTLD_NOW | RTLD_GLOBAL ); @@ -1530,7 +1587,62 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) return TRUE; }
-static const struct opengl_driver_funcs x11drv_driver_funcs = +static void x11drv_egl_surface_destroy( struct opengl_drawable *base ) +{ + struct gl_drawable *gl = impl_from_opengl_drawable( base ); + + TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) ); + + destroy_client_window( gl->base.hwnd, gl->window ); +} + +static void x11drv_egl_surface_detach( struct opengl_drawable *base ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); +} + +static void x11drv_egl_surface_update( struct opengl_drawable *base ) +{ + struct gl_drawable *gl = impl_from_opengl_drawable( base ); + + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); + + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); +} + +static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) +{ + struct gl_drawable *gl = impl_from_opengl_drawable( base ); + + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); + + if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); + if (flags & GL_FLUSH_UPDATED) + { + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + } + + present_gl_drawable( gl, TRUE, !(flags & GL_FLUSH_FINISHED) ); +} + +static BOOL x11drv_egl_surface_swap( struct opengl_drawable *base ) +{ + struct gl_drawable *gl = impl_from_opengl_drawable( base ); + + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); + + funcs->p_eglSwapBuffers( egl->display, gl->base.surface ); + + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + + present_gl_drawable( gl, TRUE, FALSE ); + return TRUE; +} + +static struct opengl_driver_funcs x11drv_driver_funcs = { .p_get_proc_address = x11drv_get_proc_address, .p_init_pixel_formats = x11drv_init_pixel_formats, @@ -1562,6 +1674,15 @@ static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = .swap = x11drv_pbuffer_swap, };
+static const struct opengl_drawable_funcs x11drv_egl_surface_funcs = +{ + .destroy = x11drv_egl_surface_destroy, + .detach = x11drv_egl_surface_detach, + .update = x11drv_egl_surface_update, + .flush = x11drv_egl_surface_flush, + .swap = x11drv_egl_surface_swap, +}; + #else /* no OpenGL includes */
/********************************************************************** diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index e61ced9a25e..dfca33dcc97 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -454,6 +454,7 @@ extern BOOL keyboard_grabbed; extern unsigned int screen_bpp; extern BOOL usexrandr; extern BOOL usexvidmode; +extern BOOL use_egl; extern BOOL use_take_focus; extern BOOL use_primary_selection; extern BOOL use_system_cursors; diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index c625107dcfa..c97088f09bc 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -68,6 +68,7 @@ Window root_window; BOOL usexvidmode = TRUE; BOOL usexrandr = TRUE; BOOL usexcomposite = TRUE; +BOOL use_egl = FALSE; BOOL use_take_focus = TRUE; BOOL use_primary_selection = FALSE; BOOL use_system_cursors = TRUE; @@ -450,6 +451,9 @@ static void setup_options(void) if (!get_config_key( hkey, appkey, "Managed", buffer, sizeof(buffer) )) managed_mode = IS_OPTION_TRUE( buffer[0] );
+ if (!get_config_key( hkey, appkey, "UseEGL", buffer, sizeof(buffer) )) + use_egl = IS_OPTION_TRUE( buffer[0] ); + if (!get_config_key( hkey, appkey, "UseXVidMode", buffer, sizeof(buffer) )) usexvidmode = IS_OPTION_TRUE( buffer[0] );
diff --git a/include/wine/wgl.h b/include/wine/wgl.h index 6ba341d11a4..e6b465e360f 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -268,6 +268,8 @@ typedef unsigned int GLhandleARB; #define EGL_PIXMAP_BIT 0x0002 #define EGL_PLATFORM_ANDROID_KHR 0x3141 #define EGL_PLATFORM_WAYLAND_KHR 0x31D8 +#define EGL_PLATFORM_X11_KHR 0x31D5 +#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 #define EGL_PRESENT_OPAQUE_EXT 0x31DF #define EGL_READ 0x305A #define EGL_RED_SIZE 0x3024
v3: Fix some wineandroid compilation failure.