From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 22 ++-------------------- dlls/opengl32/wgl.c | 24 +++++++++++++++++------- include/wine/opengl_driver.h | 1 + 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index ac81b99eeba..8e2fa4e05cc 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -129,7 +129,6 @@ struct context HGLRC client; /* client-side context handle */ 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 */ GLubyte *extensions; /* extension string */ @@ -432,10 +431,11 @@ static struct context *get_updated_context( TEB *teb, HGLRC client_context ); /* update context if it has been re-shared with another one */ static struct context *update_context( TEB *teb, HGLRC client_context, struct context *ctx ) { + struct opengl_client_context *client = opengl_client_context_from_client( client_context ); const struct opengl_funcs *funcs = get_context_funcs( client_context ); struct context *share; - if (ctx->tid) return ctx; /* currently in use */ + if (client->current_tid) return ctx; /* currently in use */ if (ctx->share == (HGLRC)-1) return ctx; /* not re-shared */ share = ctx->share ? get_updated_context( teb, ctx->share ) : NULL; @@ -1069,13 +1069,11 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD HGLRC client_context, struct context *ctx ) { struct opengl_client_context *client = opengl_client_context_from_client( ctx->base.client_context ); - DWORD tid = HandleToULong(teb->ClientId.UniqueThread); const char *version, *rest = ""; size_t count = 0, i; static pthread_once_t once = PTHREAD_ONCE_INIT; - ctx->tid = tid; teb->glReserved1[0] = draw_hdc; teb->glReserved1[1] = read_hdc; teb->glTable = (void *)funcs; @@ -1154,13 +1152,6 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC client_context ) { const struct opengl_funcs *funcs = get_context_funcs( client_context ); struct context *ctx = context_from_client_context( client_context ); - - if (ctx->tid) - { - RtlSetLastWin32Error( ERROR_BUSY ); - return FALSE; - } - funcs->p_context_destroy( &ctx->base ); free_context( ctx ); return TRUE; @@ -1362,28 +1353,19 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC client_context ) { - DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct context *ctx, *prev = get_current_context( teb, NULL, NULL ); if (client_context) { const struct opengl_funcs *funcs = get_context_funcs( client_context ); if (!(ctx = get_updated_context( teb, client_context ))) return FALSE; - if (ctx->tid && ctx->tid != tid) - { - RtlSetLastWin32Error( ERROR_BUSY ); - return FALSE; - } - if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, client_context )) return FALSE; - if (prev) prev->tid = 0; make_context_current( teb, funcs, draw_hdc, read_hdc, client_context, ctx ); } else if (prev) { const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_wglMakeContextCurrentARB( NULL, NULL, NULL )) return FALSE; - prev->tid = 0; teb->glTable = &null_opengl_funcs; } return TRUE; diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index eab3ddf3e44..27aae7cf6d8 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -379,16 +379,16 @@ BOOL WINAPI wglDeleteContext( HGLRC handle ) if (!ptr) return FALSE; args.oldContext = &ptr->context->obj; - if (handle && handle == teb->glCurrentRC) wglMakeCurrent( NULL, NULL ); + if (handle == teb->glCurrentRC) wglMakeCurrent( NULL, NULL ); + if (ptr->context->current_tid) + { + SetLastError( ERROR_BUSY ); + return FALSE; + } + if ((status = UNIX_CALL( wglDeleteContext, &args ))) WARN( "wglDeleteContext returned %#lx\n", status ); if (status || !args.ret) return FALSE; - if (handle == teb->glCurrentRC) - { - teb->glCurrentRC = 0; - teb->glReserved1[0] = 0; - teb->glReserved1[1] = 0; - } free_client_context( ptr ); return TRUE; } @@ -408,14 +408,24 @@ BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC handle ) { TEB *teb = NtCurrentTeb(); struct wglMakeContextCurrentARB_params args = { .teb = teb, .hDrawDC = draw_hdc, .hReadDC = read_hdc }; + struct opengl_client_context *context = NULL, *previous = opengl_client_context_from_handle( teb->glCurrentRC ); NTSTATUS status; TRACE( "draw_hdc %p, read_hdc %p, handle %p\n", draw_hdc, read_hdc, handle ); if (!get_context_from_handle( handle, &args.hglrc )) return FALSE; + if ((context = opengl_client_context_from_handle( handle )) && + context->current_tid && context->current_tid != GetCurrentThreadId()) + { + SetLastError( ERROR_BUSY ); + return FALSE; + } + if ((status = UNIX_CALL( wglMakeContextCurrentARB, &args ))) WARN( "wglMakeContextCurrentARB returned %#lx\n", status ); if (status || !args.ret) return FALSE; + if (context) context->current_tid = GetCurrentThreadId(); + if (previous) previous->current_tid = 0; teb->glCurrentRC = handle; teb->glReserved1[0] = draw_hdc; teb->glReserved1[1] = read_hdc; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 777a82c338a..edf65586fba 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -73,6 +73,7 @@ struct opengl_client_context struct HGLRC__ obj; /* client object header */ UINT64 unix_handle; UINT64 unix_funcs; + DWORD current_tid; /* thread that the context is current in */ GLenum last_error; int major_version; int minor_version; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10763