opengl32: Make the WGL driver context-specific.

This commit is contained in:
Alexandre Julliard 2012-06-29 15:53:37 +02:00
parent 676194383c
commit 83be88953b
4 changed files with 55 additions and 39 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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*);