opengl32: Make the WGL driver context-specific.
This commit is contained in:
parent
676194383c
commit
83be88953b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue