Commit 0045ec9d authored by Alexandre Julliard's avatar Alexandre Julliard

opengl32: Use proper handles for GL contexts and pass a context pointer to the…

opengl32: Use proper handles for GL contexts and pass a context pointer to the WGL driver functions.
parent f88231b9
...@@ -666,22 +666,23 @@ static BOOL nulldrv_UnrealizePalette( HPALETTE palette ) ...@@ -666,22 +666,23 @@ static BOOL nulldrv_UnrealizePalette( HPALETTE palette )
return FALSE; return FALSE;
} }
static BOOL nulldrv_wglCopyContext( HGLRC src, HGLRC dst, UINT mask ) static BOOL nulldrv_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask )
{ {
return FALSE; return FALSE;
} }
static HGLRC nulldrv_wglCreateContext( HDC hdc ) static struct wgl_context *nulldrv_wglCreateContext( HDC hdc )
{ {
return 0; return 0;
} }
static HGLRC nulldrv_wglCreateContextAttribsARB( HDC hdc, HGLRC share_ctx, const int *attribs ) static struct wgl_context *nulldrv_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *share_ctx,
const int *attribs )
{ {
return 0; return 0;
} }
static BOOL nulldrv_wglDeleteContext( HGLRC hglrc ) static BOOL nulldrv_wglDeleteContext( struct wgl_context *context )
{ {
return FALSE; return FALSE;
} }
...@@ -696,17 +697,17 @@ static PROC nulldrv_wglGetProcAddress( LPCSTR name ) ...@@ -696,17 +697,17 @@ static PROC nulldrv_wglGetProcAddress( LPCSTR name )
return NULL; return NULL;
} }
static BOOL nulldrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) static BOOL nulldrv_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context )
{ {
return FALSE; return FALSE;
} }
static BOOL nulldrv_wglMakeCurrent( HDC hdc, HGLRC hglrc ) static BOOL nulldrv_wglMakeCurrent( HDC hdc, struct wgl_context *context )
{ {
return FALSE; return FALSE;
} }
static BOOL nulldrv_wglShareLists( HGLRC org, HGLRC dst ) static BOOL nulldrv_wglShareLists( struct wgl_context *org, struct wgl_context *dst )
{ {
return FALSE; return FALSE;
} }
......
...@@ -895,7 +895,7 @@ static void test_opengl3(HDC hdc) ...@@ -895,7 +895,7 @@ static void test_opengl3(HDC hdc)
HGLRC gl3Ctx; HGLRC gl3Ctx;
DWORD error; DWORD error;
gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0); gl3Ctx = pwglCreateContextAttribsARB(hdc, (HGLRC)0xdeadbeef, 0);
todo_wine ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n"); ok(gl3Ctx == 0, "pwglCreateContextAttribsARB using an invalid shareList passed\n");
error = GetLastError(); error = GetLastError();
/* The Nvidia implementation seems to return hresults instead of win32 error codes */ /* The Nvidia implementation seems to return hresults instead of win32 error codes */
todo_wine ok(error == ERROR_INVALID_OPERATION || todo_wine ok(error == ERROR_INVALID_OPERATION ||
......
...@@ -79,6 +79,84 @@ extern INT WINAPI GdiDescribePixelFormat( HDC hdc, INT fmt, UINT size, PIXELFORM ...@@ -79,6 +79,84 @@ extern INT WINAPI GdiDescribePixelFormat( HDC hdc, INT fmt, UINT size, PIXELFORM
extern BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT fmt, const PIXELFORMATDESCRIPTOR *pfd ); extern BOOL WINAPI GdiSetPixelFormat( HDC hdc, INT fmt, const PIXELFORMATDESCRIPTOR *pfd );
extern BOOL WINAPI GdiSwapBuffers( HDC hdc ); extern BOOL WINAPI GdiSwapBuffers( HDC hdc );
/* handle management */
#define MAX_WGL_HANDLES 1024
struct wgl_handle
{
UINT handle;
struct wgl_context *context;
};
static struct wgl_handle wgl_handles[MAX_WGL_HANDLES];
static struct wgl_handle *next_free;
static unsigned int handle_count;
static CRITICAL_SECTION wgl_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &wgl_section,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": wgl_section") }
};
static CRITICAL_SECTION wgl_section = { &critsect_debug, -1, 0, 0, 0, 0 };
static inline HGLRC next_handle( struct wgl_handle *ptr )
{
WORD generation = HIWORD( ptr->handle ) + 1;
if (!generation) generation++;
ptr->handle = MAKELONG( ptr - wgl_handles, generation );
return ULongToHandle( ptr->handle );
}
static struct wgl_handle *get_handle_ptr( HGLRC handle )
{
unsigned int index = LOWORD( handle );
EnterCriticalSection( &wgl_section );
if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle)
return &wgl_handles[index];
LeaveCriticalSection( &wgl_section );
SetLastError( ERROR_INVALID_HANDLE );
return NULL;
}
static void release_handle_ptr( struct wgl_handle *ptr )
{
if (ptr) LeaveCriticalSection( &wgl_section );
}
static HGLRC alloc_handle( struct wgl_context *context )
{
HGLRC handle = 0;
struct wgl_handle *ptr = NULL;
EnterCriticalSection( &wgl_section );
if ((ptr = next_free))
next_free = (struct wgl_handle *)next_free->context;
else if (handle_count < MAX_WGL_HANDLES)
ptr = &wgl_handles[handle_count++];
if (ptr)
{
ptr->context = context;
handle = next_handle( ptr );
}
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
LeaveCriticalSection( &wgl_section );
return handle;
}
static void free_handle_ptr( struct wgl_handle *ptr )
{
ptr->handle &= ~0xffff;
ptr->context = (struct wgl_context *)next_free;
next_free = ptr;
LeaveCriticalSection( &wgl_section );
}
/*********************************************************************** /***********************************************************************
* wglSetPixelFormat(OPENGL32.@) * wglSetPixelFormat(OPENGL32.@)
*/ */
...@@ -93,12 +171,16 @@ BOOL WINAPI wglSetPixelFormat( HDC hdc, INT iPixelFormat, ...@@ -93,12 +171,16 @@ BOOL WINAPI wglSetPixelFormat( HDC hdc, INT iPixelFormat,
*/ */
BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{ {
if (!hglrcSrc || !hglrcDst) struct wgl_handle *src, *dst;
{ BOOL ret = FALSE;
SetLastError(ERROR_INVALID_HANDLE);
return FALSE; if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
} if ((dst = get_handle_ptr( hglrcDst )))
return wgl_driver->p_wglCopyContext(hglrcSrc, hglrcDst, mask); ret = wgl_driver->p_wglCopyContext( src->context, dst->context, mask );
release_handle_ptr( dst );
release_handle_ptr( src );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -106,12 +188,17 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) ...@@ -106,12 +188,17 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
*/ */
BOOL WINAPI wglDeleteContext(HGLRC hglrc) BOOL WINAPI wglDeleteContext(HGLRC hglrc)
{ {
if (!hglrc) struct wgl_handle *ptr = get_handle_ptr( hglrc );
if (!ptr) return FALSE;
if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
if (!wgl_driver->p_wglDeleteContext( ptr->context ))
{ {
SetLastError(ERROR_INVALID_HANDLE); release_handle_ptr( ptr );
return FALSE; return FALSE;
} }
return wgl_driver->p_wglDeleteContext(hglrc); free_handle_ptr( ptr );
return TRUE;
} }
/*********************************************************************** /***********************************************************************
...@@ -119,12 +206,19 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc) ...@@ -119,12 +206,19 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
*/ */
BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
{ {
if (!hglrc && !hdc && !NtCurrentTeb()->glContext) struct wgl_handle *ptr = NULL;
BOOL ret;
if (!hglrc && !hdc && !NtCurrentTeb()->glCurrentRC)
{ {
SetLastError( ERROR_INVALID_HANDLE ); SetLastError( ERROR_INVALID_HANDLE );
return FALSE; return FALSE;
} }
return wgl_driver->p_wglMakeCurrent(hdc, hglrc); if (hglrc && !(ptr = get_handle_ptr( hglrc ))) return FALSE;
ret = wgl_driver->p_wglMakeCurrent( hdc, ptr ? ptr->context : NULL );
if (ret) NtCurrentTeb()->glCurrentRC = hglrc;
release_handle_ptr( ptr );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -132,7 +226,20 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) ...@@ -132,7 +226,20 @@ BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
*/ */
static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs ) static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs )
{ {
return wgl_driver->p_wglCreateContextAttribsARB( hdc, share, attribs ); HGLRC ret = 0;
struct wgl_context *context;
struct wgl_handle *share_ptr = NULL;
if (share && !(share_ptr = get_handle_ptr( share ))) return 0;
if ((context = wgl_driver->p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL,
attribs )))
{
ret = alloc_handle( context );
if (!ret) wgl_driver->p_wglDeleteContext( context );
}
release_handle_ptr( share_ptr );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -140,20 +247,31 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int ...@@ -140,20 +247,31 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int
*/ */
static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) static BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
{ {
return wgl_driver->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, hglrc ); struct wgl_handle *ptr = NULL;
BOOL ret;
if (hglrc && !(ptr = get_handle_ptr( hglrc ))) return FALSE;
ret = wgl_driver->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr ? ptr->context : NULL );
if (ret) NtCurrentTeb()->glCurrentRC = hglrc;
release_handle_ptr( ptr );
return ret;
} }
/*********************************************************************** /***********************************************************************
* wglShareLists (OPENGL32.@) * wglShareLists (OPENGL32.@)
*/ */
BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2) BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
{ {
if (!hglrc1 || !hglrc2) BOOL ret = FALSE;
{ struct wgl_handle *src, *dst;
SetLastError(ERROR_INVALID_HANDLE);
return FALSE; if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
} if ((dst = get_handle_ptr( hglrcDst )))
return wgl_driver->p_wglShareLists(hglrc1, hglrc2); ret = wgl_driver->p_wglShareLists( src->context, dst->context );
release_handle_ptr( dst );
release_handle_ptr( src );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -169,7 +287,13 @@ HDC WINAPI wglGetCurrentDC(void) ...@@ -169,7 +287,13 @@ HDC WINAPI wglGetCurrentDC(void)
*/ */
HGLRC WINAPI wglCreateContext(HDC hdc) HGLRC WINAPI wglCreateContext(HDC hdc)
{ {
return wgl_driver->p_wglCreateContext(hdc); HGLRC ret = 0;
struct wgl_context *context = wgl_driver->p_wglCreateContext( hdc );
if (!context) return 0;
ret = alloc_handle( context );
if (!ret) wgl_driver->p_wglDeleteContext( context );
return ret;
} }
/*********************************************************************** /***********************************************************************
...@@ -177,7 +301,7 @@ HGLRC WINAPI wglCreateContext(HDC hdc) ...@@ -177,7 +301,7 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
*/ */
HGLRC WINAPI wglGetCurrentContext(void) HGLRC WINAPI wglGetCurrentContext(void)
{ {
return NtCurrentTeb()->glContext; return NtCurrentTeb()->glCurrentRC;
} }
/*********************************************************************** /***********************************************************************
......
...@@ -198,7 +198,7 @@ struct gdi_dc_funcs ...@@ -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 39 #define WINE_GDI_DRIVER_VERSION 40
#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 */
...@@ -226,18 +226,20 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g ...@@ -226,18 +226,20 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g
/* OpenGL support */ /* OpenGL support */
struct wgl_context;
struct wgl_funcs struct wgl_funcs
{ {
INT (*p_GetPixelFormat)(HDC); INT (*p_GetPixelFormat)(HDC);
BOOL (*p_wglCopyContext)(HGLRC,HGLRC,UINT); BOOL (*p_wglCopyContext)(struct wgl_context*,struct wgl_context*,UINT);
HGLRC (*p_wglCreateContext)(HDC); struct wgl_context* (*p_wglCreateContext)(HDC);
HGLRC (*p_wglCreateContextAttribsARB)(HDC,HGLRC,const int*); struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*);
BOOL (*p_wglDeleteContext)(HGLRC); BOOL (*p_wglDeleteContext)(struct wgl_context*);
HDC (*p_wglGetCurrentDC)(void); HDC (*p_wglGetCurrentDC)(void);
PROC (*p_wglGetProcAddress)(LPCSTR); PROC (*p_wglGetProcAddress)(LPCSTR);
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,HGLRC); BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*);
BOOL (*p_wglMakeCurrent)(HDC,HGLRC); BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);
BOOL (*p_wglShareLists)(HGLRC,HGLRC); BOOL (*p_wglShareLists)(struct wgl_context*,struct wgl_context*);
}; };
/* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */ /* the DC hook support is only exported on Win16, the 32-bit version is a Wine extension */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment