From 83be88953bc5a4fa6d3cd53f81c09f493e2dd86a Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 29 Jun 2012 15:53:37 +0200 Subject: [PATCH] opengl32: Make the WGL driver context-specific. --- dlls/gdi32/driver.c | 2 +- dlls/opengl32/wgl.c | 83 ++++++++++++++++++++++++--------------- dlls/winex11.drv/opengl.c | 5 +-- include/wine/gdi_driver.h | 4 +- 4 files changed, 55 insertions(+), 39 deletions(-) diff --git a/dlls/gdi32/driver.c b/dlls/gdi32/driver.c index 1dfdbb17623..f4c5f52c333 100644 --- a/dlls/gdi32/driver.c +++ b/dlls/gdi32/driver.c @@ -686,7 +686,7 @@ static void nulldrv_wglDeleteContext( struct wgl_context *context ) { } -static HDC nulldrv_wglGetCurrentDC(void) +static HDC nulldrv_wglGetCurrentDC( struct wgl_context *context ) { return 0; } diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index d0d9d837364..815dc422047 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -54,8 +54,6 @@ static struct void (WINAPI *p_wglGetIntegerv)(GLenum pname, GLint* params); } wine_wgl; -static const struct wgl_funcs *wgl_driver; - #ifdef SONAME_LIBGLU #define MAKE_FUNCPTR(f) static typeof(f) * p##f; MAKE_FUNCPTR(gluNewTess) @@ -85,9 +83,10 @@ extern BOOL WINAPI GdiSwapBuffers( HDC hdc ); struct wgl_handle { - UINT handle; - DWORD tid; - struct wgl_context *context; + UINT handle; + DWORD tid; + struct wgl_context * context; + const struct wgl_funcs *funcs; }; static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; @@ -103,6 +102,11 @@ static CRITICAL_SECTION_DEBUG critsect_debug = }; static CRITICAL_SECTION wgl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; +static inline const struct wgl_funcs *get_dc_funcs( HDC hdc ) +{ + return __wine_get_wgl_driver( hdc, WINE_GDI_DRIVER_VERSION ); +} + static inline HGLRC next_handle( struct wgl_handle *ptr ) { WORD generation = HIWORD( ptr->handle ) + 1; @@ -136,7 +140,7 @@ static void release_handle_ptr( struct wgl_handle *ptr ) if (ptr) LeaveCriticalSection( &wgl_section ); } -static HGLRC alloc_handle( struct wgl_context *context ) +static HGLRC alloc_handle( struct wgl_context *context, const struct wgl_funcs *funcs ) { HGLRC handle = 0; struct wgl_handle *ptr = NULL; @@ -150,6 +154,7 @@ static HGLRC alloc_handle( struct wgl_context *context ) if (ptr) { ptr->context = context; + ptr->funcs = funcs; handle = next_handle( ptr ); } else SetLastError( ERROR_NOT_ENOUGH_MEMORY ); @@ -161,6 +166,7 @@ static void free_handle_ptr( struct wgl_handle *ptr ) { ptr->handle &= ~0xffff; ptr->context = (struct wgl_context *)next_free; + ptr->funcs = NULL; next_free = ptr; LeaveCriticalSection( &wgl_section ); } @@ -184,8 +190,10 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE; if ((dst = get_handle_ptr( hglrcDst ))) - ret = wgl_driver->p_wglCopyContext( src->context, dst->context, mask ); - + { + if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE ); + else ret = src->funcs->p_wglCopyContext( src->context, dst->context, mask ); + } release_handle_ptr( dst ); release_handle_ptr( src ); return ret; @@ -207,7 +215,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc) return FALSE; } if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 ); - wgl_driver->p_wglDeleteContext( ptr->context ); + ptr->funcs->p_wglDeleteContext( ptr->context ); free_handle_ptr( ptr ); return TRUE; } @@ -225,7 +233,7 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; if (!ptr->tid || ptr->tid == GetCurrentThreadId()) { - ret = wgl_driver->p_wglMakeCurrent( hdc, ptr->context ); + ret = ptr->funcs->p_wglMakeCurrent( hdc, ptr->context ); if (ret) { if (prev) prev->tid = 0; @@ -242,7 +250,7 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) } else if (prev) { - if (!wgl_driver->p_wglMakeCurrent( 0, NULL )) return FALSE; + if (!prev->funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; NtCurrentTeb()->glCurrentRC = 0; } @@ -262,13 +270,15 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int HGLRC ret = 0; struct wgl_context *context; struct wgl_handle *share_ptr = NULL; + const struct wgl_funcs *funcs = get_dc_funcs( hdc ); + if (!funcs) return 0; if (share && !(share_ptr = get_handle_ptr( share ))) return 0; - if ((context = wgl_driver->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL, - attribs ))) + if ((context = funcs->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL, + attribs ))) { - ret = alloc_handle( context ); - if (!ret) wgl_driver->p_wglDeleteContext( context ); + ret = alloc_handle( context, funcs ); + if (!ret) funcs->p_wglDeleteContext( context ); } release_handle_ptr( share_ptr ); return ret; @@ -288,7 +298,7 @@ static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC h if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; if (!ptr->tid || ptr->tid == GetCurrentThreadId()) { - ret = wgl_driver->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->context ); + ret = ptr->funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->context ); if (ret) { if (prev) prev->tid = 0; @@ -305,7 +315,7 @@ static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC h } else if (prev) { - if (!wgl_driver->p_wglMakeCurrent( 0, NULL )) return FALSE; + if (!prev->funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; NtCurrentTeb()->glCurrentRC = 0; } @@ -322,8 +332,10 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst) if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE; if ((dst = get_handle_ptr( hglrcDst ))) - ret = wgl_driver->p_wglShareLists( src->context, dst->context ); - + { + if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE ); + else ret = src->funcs->p_wglShareLists( src->context, dst->context ); + } release_handle_ptr( dst ); release_handle_ptr( src ); return ret; @@ -334,7 +346,9 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst) */ HDC WINAPI wglGetCurrentDC(void) { - return wgl_driver->p_wglGetCurrentDC(); + struct wgl_handle *context = get_current_handle_ptr(); + if (!context) return 0; + return context->funcs->p_wglGetCurrentDC( context->context ); } /*********************************************************************** @@ -343,11 +357,13 @@ HDC WINAPI wglGetCurrentDC(void) HGLRC WINAPI wglCreateContext(HDC hdc) { HGLRC ret = 0; - struct wgl_context *context = wgl_driver->p_wglCreateContext( hdc ); + struct wgl_context *context; + const struct wgl_funcs *funcs = get_dc_funcs( hdc ); - if (!context) return 0; - ret = alloc_handle( context ); - if (!ret) wgl_driver->p_wglDeleteContext( context ); + if (!funcs) return 0; + if (!(context = funcs->p_wglCreateContext( hdc ))) return 0; + ret = alloc_handle( context, funcs ); + if (!ret) funcs->p_wglDeleteContext( context ); return ret; } @@ -536,7 +552,9 @@ INT WINAPI wglDescribePixelFormat(HDC hdc, INT iPixelFormat, UINT nBytes, */ INT WINAPI wglGetPixelFormat(HDC hdc) { - return wgl_driver->p_GetPixelFormat( hdc ); + const struct wgl_funcs *funcs = get_dc_funcs( hdc ); + if (!funcs) return 0; + return funcs->p_GetPixelFormat( hdc ); } /*********************************************************************** @@ -659,6 +677,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { void *local_func; OpenGL_extension ext; const OpenGL_extension *ext_ret; + struct wgl_handle *context = get_current_handle_ptr(); TRACE("(%s)\n", lpszProc); @@ -668,7 +687,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { /* Without an active context opengl32 doesn't know to what * driver it has to dispatch wglGetProcAddress. */ - if (wglGetCurrentContext() == NULL) + if (!context) { WARN("No active WGL context found\n"); return NULL; @@ -684,7 +703,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { /* If the function name starts with a 'w', it is a WGL extension */ if(lpszProc[0] == 'w') { - local_func = wgl_driver->p_wglGetProcAddress( lpszProc ); + local_func = context->funcs->p_wglGetProcAddress( lpszProc ); if (local_func == (void *)1) /* special function that needs a wrapper */ { ext_ret = bsearch( &ext, wgl_extensions, sizeof(wgl_extensions)/sizeof(wgl_extensions[0]), @@ -707,7 +726,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) { WARN("Extension '%s' required by function '%s' not supported!\n", ext_ret->extension, lpszProc); } - local_func = wgl_driver->p_wglGetProcAddress(ext_ret->name); + local_func = context->funcs->p_wglGetProcAddress( ext_ret->name ); /* After that, look at the extensions defined in the Linux OpenGL library */ if (local_func == NULL) { @@ -1290,14 +1309,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH wglSwapBuffers( HDC hdc ) static BOOL process_attach(void) { HDC hdc = GetDC( 0 ); + const struct wgl_funcs *funcs = get_dc_funcs( hdc ); - wgl_driver = __wine_get_wgl_driver( hdc, WINE_GDI_DRIVER_VERSION ); ReleaseDC( 0, hdc ); /* internal WGL functions */ - wine_wgl.p_wglFinish = (void *)wgl_driver->p_wglGetProcAddress("wglFinish"); - wine_wgl.p_wglFlush = (void *)wgl_driver->p_wglGetProcAddress("wglFlush"); - wine_wgl.p_wglGetIntegerv = (void *)wgl_driver->p_wglGetProcAddress("wglGetIntegerv"); + wine_wgl.p_wglFinish = (void *)funcs->p_wglGetProcAddress("wglFinish"); + wine_wgl.p_wglFlush = (void *)funcs->p_wglGetProcAddress("wglFlush"); + wine_wgl.p_wglGetIntegerv = (void *)funcs->p_wglGetProcAddress("wglGetIntegerv"); return TRUE; } diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index c278c461864..b35175010e2 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1728,11 +1728,8 @@ static BOOL glxdrv_wglShareLists(struct wgl_context *org, struct wgl_context *de /*********************************************************************** * glxdrv_wglGetCurrentDC */ -static HDC glxdrv_wglGetCurrentDC(void) +static HDC glxdrv_wglGetCurrentDC( struct wgl_context *ctx ) { - struct wgl_context *ctx = NtCurrentTeb()->glContext; - - if (!ctx) return NULL; TRACE("hdc %p\n", ctx->hdc); return ctx->hdc; } diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 22214f2eb75..822859286a7 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -198,7 +198,7 @@ struct gdi_dc_funcs }; /* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 40 +#define WINE_GDI_DRIVER_VERSION 41 #define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -235,7 +235,7 @@ struct wgl_funcs struct wgl_context* (*p_wglCreateContext)(HDC); struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*); void (*p_wglDeleteContext)(struct wgl_context*); - HDC (*p_wglGetCurrentDC)(void); + HDC (*p_wglGetCurrentDC)(struct wgl_context*); PROC (*p_wglGetProcAddress)(LPCSTR); BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*); BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);