From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 70 ++++++++++++++++++++++-------------- include/wine/opengl_driver.h | 3 ++ 2 files changed, 47 insertions(+), 26 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index a68e9fa0b56..f2cc34006e1 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -60,8 +60,7 @@ enum wgl_handle_type { HANDLE_PBUFFER = 0 << 12, HANDLE_CONTEXT = 1 << 12, - HANDLE_CONTEXT_V3 = 3 << 12, - HANDLE_GLSYNC = 4 << 12, + HANDLE_GLSYNC = 2 << 12, HANDLE_TYPE_MASK = 15 << 12, };
@@ -454,6 +453,19 @@ static BOOL check_extension_support( TEB *teb, const char *extension, const char return FALSE; }
+static int *memdup_attribs( const int *attribs ) +{ + const int *attr; + int *copy; + + if (!(attr = attribs)) return NULL; + while (*attr++) { /* nothing */ } + + if (!(copy = malloc( attr - attribs ))) return NULL; + memcpy( copy, attribs, (attr - attribs) * sizeof(*attr) ); + return copy; +} + static void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ) { const struct opengl_funcs *funcs = teb->glTable; @@ -567,20 +579,24 @@ static char *build_extension_list( TEB *teb ) return available_extensions; }
-static inline enum wgl_handle_type get_current_context_type( TEB *teb ) +static BOOL is_legacy_context( TEB *teb ) { - if (!teb->glCurrentRC) return HANDLE_CONTEXT; - return LOWORD(teb->glCurrentRC) & HANDLE_TYPE_MASK; + struct wgl_context *ctx; + + if (!(ctx = get_current_context( teb ))) return TRUE; + for (const int *attr = ctx->attribs; attr && attr[0]; attr += 2) + if (attr[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) return attr[1] < 3; + + return TRUE; }
/* Check if a GL extension is supported */ static BOOL is_extension_supported( TEB *teb, const char *extension ) { - enum wgl_handle_type type = get_current_context_type( teb ); char *available_extensions = NULL; BOOL ret = FALSE;
- if (type == HANDLE_CONTEXT) available_extensions = strdup( (const char *)wrap_glGetString( teb, GL_EXTENSIONS ) ); + if (is_legacy_context( teb )) available_extensions = strdup( (const char *)wrap_glGetString( teb, GL_EXTENSIONS ) ); if (!available_extensions) available_extensions = build_extension_list( teb );
if (!available_extensions) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" ); @@ -679,6 +695,8 @@ static HGLRC wrap_wglCreateContext( HDC hdc )
if (!funcs) return 0; if (!(context = funcs->p_wglCreateContext( hdc ))) return 0; + context->hdc = hdc; + ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); if (!ret) funcs->p_wglDeleteContext( context ); return ret; @@ -741,6 +759,7 @@ static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) free( ctx->wow64_version ); free( ctx->disabled_exts ); free( ctx->extensions ); + free( ctx->attribs ); ptr->funcs->p_wglDeleteContext( ctx ); free_handle_ptr( ptr ); return TRUE; @@ -802,13 +821,23 @@ NTSTATUS wgl_wglSwapBuffers( void *args ) static BOOL wrap_wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct wgl_context *src, *dst; + struct wgl_handle *src_ptr, *dst_ptr; BOOL ret = FALSE;
- if (!(src = wgl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = wgl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; + if (!(src_ptr = get_handle_ptr( hglrcSrc ))) return FALSE; + src_funcs = src_ptr->funcs; + if (!(dst_ptr = get_handle_ptr( hglrcDst ))) return FALSE; + dst_funcs = dst_ptr->funcs; + if (src_funcs != dst_funcs) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - else ret = src_funcs->p_wglShareLists( src, dst ); + else + { + struct wgl_context *src = src_ptr->u.context, *dst = dst_ptr->u.context; + if (!src->share) src->share = hglrcDst; + if (!dst->share) dst->share = hglrcSrc; + ret = src_funcs->p_wglShareLists( src, dst ); + } + return ret; }
@@ -840,22 +869,11 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a } if ((context = funcs->p_wglCreateContextAttribsARB( hdc, share_ctx, attribs ))) { - enum wgl_handle_type type = HANDLE_CONTEXT; - - if (attribs) - { - while (*attribs) - { - if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) - { - if (attribs[1] >= 3) type = HANDLE_CONTEXT_V3; - break; - } - attribs += 2; - } - } + context->hdc = hdc; + context->share = share; + context->attribs = memdup_attribs( attribs );
- ret = alloc_handle( type, funcs, context ); + ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); if (!ret) funcs->p_wglDeleteContext( context ); }
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index b48f2351b17..656caa1754b 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -65,6 +65,9 @@ struct wgl_pixel_format
struct wgl_context { + HDC hdc; /* context creation DC */ + HGLRC share; /* context to be shared with */ + int *attribs; /* creation attributes */ DWORD tid; /* thread that the context is current in */ UINT64 debug_callback; /* client pointer */ UINT64 debug_user; /* client pointer */