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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,6 @@ static struct
|
||||||
void (WINAPI *p_wglGetIntegerv)(GLenum pname, GLint* params);
|
void (WINAPI *p_wglGetIntegerv)(GLenum pname, GLint* params);
|
||||||
} wine_wgl;
|
} wine_wgl;
|
||||||
|
|
||||||
static const struct wgl_funcs *wgl_driver;
|
|
||||||
|
|
||||||
#ifdef SONAME_LIBGLU
|
#ifdef SONAME_LIBGLU
|
||||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
|
#define MAKE_FUNCPTR(f) static typeof(f) * p##f;
|
||||||
MAKE_FUNCPTR(gluNewTess)
|
MAKE_FUNCPTR(gluNewTess)
|
||||||
|
@ -85,9 +83,10 @@ extern BOOL WINAPI GdiSwapBuffers( HDC hdc );
|
||||||
|
|
||||||
struct wgl_handle
|
struct wgl_handle
|
||||||
{
|
{
|
||||||
UINT handle;
|
UINT handle;
|
||||||
DWORD tid;
|
DWORD tid;
|
||||||
struct wgl_context *context;
|
struct wgl_context * context;
|
||||||
|
const struct wgl_funcs *funcs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct wgl_handle wgl_handles[MAX_WGL_HANDLES];
|
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 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 )
|
static inline HGLRC next_handle( struct wgl_handle *ptr )
|
||||||
{
|
{
|
||||||
WORD generation = HIWORD( ptr->handle ) + 1;
|
WORD generation = HIWORD( ptr->handle ) + 1;
|
||||||
|
@ -136,7 +140,7 @@ static void release_handle_ptr( struct wgl_handle *ptr )
|
||||||
if (ptr) LeaveCriticalSection( &wgl_section );
|
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;
|
HGLRC handle = 0;
|
||||||
struct wgl_handle *ptr = NULL;
|
struct wgl_handle *ptr = NULL;
|
||||||
|
@ -150,6 +154,7 @@ static HGLRC alloc_handle( struct wgl_context *context )
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
ptr->context = context;
|
ptr->context = context;
|
||||||
|
ptr->funcs = funcs;
|
||||||
handle = next_handle( ptr );
|
handle = next_handle( ptr );
|
||||||
}
|
}
|
||||||
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
@ -161,6 +166,7 @@ static void free_handle_ptr( struct wgl_handle *ptr )
|
||||||
{
|
{
|
||||||
ptr->handle &= ~0xffff;
|
ptr->handle &= ~0xffff;
|
||||||
ptr->context = (struct wgl_context *)next_free;
|
ptr->context = (struct wgl_context *)next_free;
|
||||||
|
ptr->funcs = NULL;
|
||||||
next_free = ptr;
|
next_free = ptr;
|
||||||
LeaveCriticalSection( &wgl_section );
|
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 (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
|
||||||
if ((dst = get_handle_ptr( hglrcDst )))
|
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( dst );
|
||||||
release_handle_ptr( src );
|
release_handle_ptr( src );
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -207,7 +215,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
|
if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
|
||||||
wgl_driver->p_wglDeleteContext( ptr->context );
|
ptr->funcs->p_wglDeleteContext( ptr->context );
|
||||||
free_handle_ptr( ptr );
|
free_handle_ptr( ptr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +233,7 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
|
||||||
if (!(ptr = get_handle_ptr( hglrc ))) return FALSE;
|
if (!(ptr = get_handle_ptr( hglrc ))) return FALSE;
|
||||||
if (!ptr->tid || ptr->tid == GetCurrentThreadId())
|
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 (ret)
|
||||||
{
|
{
|
||||||
if (prev) prev->tid = 0;
|
if (prev) prev->tid = 0;
|
||||||
|
@ -242,7 +250,7 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
|
||||||
}
|
}
|
||||||
else if (prev)
|
else if (prev)
|
||||||
{
|
{
|
||||||
if (!wgl_driver->p_wglMakeCurrent( 0, NULL )) return FALSE;
|
if (!prev->funcs->p_wglMakeCurrent( 0, NULL )) return FALSE;
|
||||||
prev->tid = 0;
|
prev->tid = 0;
|
||||||
NtCurrentTeb()->glCurrentRC = 0;
|
NtCurrentTeb()->glCurrentRC = 0;
|
||||||
}
|
}
|
||||||
|
@ -262,13 +270,15 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int
|
||||||
HGLRC ret = 0;
|
HGLRC ret = 0;
|
||||||
struct wgl_context *context;
|
struct wgl_context *context;
|
||||||
struct wgl_handle *share_ptr = NULL;
|
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 (share && !(share_ptr = get_handle_ptr( share ))) return 0;
|
||||||
if ((context = wgl_driver->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL,
|
if ((context = funcs->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL,
|
||||||
attribs )))
|
attribs )))
|
||||||
{
|
{
|
||||||
ret = alloc_handle( context );
|
ret = alloc_handle( context, funcs );
|
||||||
if (!ret) wgl_driver->p_wglDeleteContext( context );
|
if (!ret) funcs->p_wglDeleteContext( context );
|
||||||
}
|
}
|
||||||
release_handle_ptr( share_ptr );
|
release_handle_ptr( share_ptr );
|
||||||
return ret;
|
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 = get_handle_ptr( hglrc ))) return FALSE;
|
||||||
if (!ptr->tid || ptr->tid == GetCurrentThreadId())
|
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 (ret)
|
||||||
{
|
{
|
||||||
if (prev) prev->tid = 0;
|
if (prev) prev->tid = 0;
|
||||||
|
@ -305,7 +315,7 @@ static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC h
|
||||||
}
|
}
|
||||||
else if (prev)
|
else if (prev)
|
||||||
{
|
{
|
||||||
if (!wgl_driver->p_wglMakeCurrent( 0, NULL )) return FALSE;
|
if (!prev->funcs->p_wglMakeCurrent( 0, NULL )) return FALSE;
|
||||||
prev->tid = 0;
|
prev->tid = 0;
|
||||||
NtCurrentTeb()->glCurrentRC = 0;
|
NtCurrentTeb()->glCurrentRC = 0;
|
||||||
}
|
}
|
||||||
|
@ -322,8 +332,10 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
|
||||||
|
|
||||||
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
|
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
|
||||||
if ((dst = get_handle_ptr( hglrcDst )))
|
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( dst );
|
||||||
release_handle_ptr( src );
|
release_handle_ptr( src );
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -334,7 +346,9 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
|
||||||
*/
|
*/
|
||||||
HDC WINAPI wglGetCurrentDC(void)
|
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 WINAPI wglCreateContext(HDC hdc)
|
||||||
{
|
{
|
||||||
HGLRC ret = 0;
|
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;
|
if (!funcs) return 0;
|
||||||
ret = alloc_handle( context );
|
if (!(context = funcs->p_wglCreateContext( hdc ))) return 0;
|
||||||
if (!ret) wgl_driver->p_wglDeleteContext( context );
|
ret = alloc_handle( context, funcs );
|
||||||
|
if (!ret) funcs->p_wglDeleteContext( context );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +552,9 @@ INT WINAPI wglDescribePixelFormat(HDC hdc, INT iPixelFormat, UINT nBytes,
|
||||||
*/
|
*/
|
||||||
INT WINAPI wglGetPixelFormat(HDC hdc)
|
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;
|
void *local_func;
|
||||||
OpenGL_extension ext;
|
OpenGL_extension ext;
|
||||||
const OpenGL_extension *ext_ret;
|
const OpenGL_extension *ext_ret;
|
||||||
|
struct wgl_handle *context = get_current_handle_ptr();
|
||||||
|
|
||||||
TRACE("(%s)\n", lpszProc);
|
TRACE("(%s)\n", lpszProc);
|
||||||
|
|
||||||
|
@ -668,7 +687,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc) {
|
||||||
/* Without an active context opengl32 doesn't know to what
|
/* Without an active context opengl32 doesn't know to what
|
||||||
* driver it has to dispatch wglGetProcAddress.
|
* driver it has to dispatch wglGetProcAddress.
|
||||||
*/
|
*/
|
||||||
if (wglGetCurrentContext() == NULL)
|
if (!context)
|
||||||
{
|
{
|
||||||
WARN("No active WGL context found\n");
|
WARN("No active WGL context found\n");
|
||||||
return NULL;
|
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 the function name starts with a 'w', it is a WGL extension */
|
||||||
if(lpszProc[0] == 'w')
|
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 */
|
if (local_func == (void *)1) /* special function that needs a wrapper */
|
||||||
{
|
{
|
||||||
ext_ret = bsearch( &ext, wgl_extensions, sizeof(wgl_extensions)/sizeof(wgl_extensions[0]),
|
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);
|
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 */
|
/* After that, look at the extensions defined in the Linux OpenGL library */
|
||||||
if (local_func == NULL) {
|
if (local_func == NULL) {
|
||||||
|
@ -1290,14 +1309,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH wglSwapBuffers( HDC hdc )
|
||||||
static BOOL process_attach(void)
|
static BOOL process_attach(void)
|
||||||
{
|
{
|
||||||
HDC hdc = GetDC( 0 );
|
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 );
|
ReleaseDC( 0, hdc );
|
||||||
|
|
||||||
/* internal WGL functions */
|
/* internal WGL functions */
|
||||||
wine_wgl.p_wglFinish = (void *)wgl_driver->p_wglGetProcAddress("wglFinish");
|
wine_wgl.p_wglFinish = (void *)funcs->p_wglGetProcAddress("wglFinish");
|
||||||
wine_wgl.p_wglFlush = (void *)wgl_driver->p_wglGetProcAddress("wglFlush");
|
wine_wgl.p_wglFlush = (void *)funcs->p_wglGetProcAddress("wglFlush");
|
||||||
wine_wgl.p_wglGetIntegerv = (void *)wgl_driver->p_wglGetProcAddress("wglGetIntegerv");
|
wine_wgl.p_wglGetIntegerv = (void *)funcs->p_wglGetProcAddress("wglGetIntegerv");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1728,11 +1728,8 @@ static BOOL glxdrv_wglShareLists(struct wgl_context *org, struct wgl_context *de
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* glxdrv_wglGetCurrentDC
|
* 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);
|
TRACE("hdc %p\n", ctx->hdc);
|
||||||
return ctx->hdc;
|
return ctx->hdc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,7 +198,7 @@ struct gdi_dc_funcs
|
||||||
};
|
};
|
||||||
|
|
||||||
/* increment this when you change the DC function table */
|
/* 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_NULL_DRV 0 /* null driver */
|
||||||
#define GDI_PRIORITY_FONT_DRV 100 /* any font 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_wglCreateContext)(HDC);
|
||||||
struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*);
|
struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*);
|
||||||
void (*p_wglDeleteContext)(struct wgl_context*);
|
void (*p_wglDeleteContext)(struct wgl_context*);
|
||||||
HDC (*p_wglGetCurrentDC)(void);
|
HDC (*p_wglGetCurrentDC)(struct wgl_context*);
|
||||||
PROC (*p_wglGetProcAddress)(LPCSTR);
|
PROC (*p_wglGetProcAddress)(LPCSTR);
|
||||||
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*);
|
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*);
|
||||||
BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);
|
BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);
|
||||||
|
|
Loading…
Reference in New Issue