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 )
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;
}
static HGLRC nulldrv_wglCreateContext( HDC hdc )
static struct wgl_context *nulldrv_wglCreateContext( HDC hdc )
{
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;
}
static BOOL nulldrv_wglDeleteContext( HGLRC hglrc )
static BOOL nulldrv_wglDeleteContext( struct wgl_context *context )
{
return FALSE;
}
......@@ -696,17 +697,17 @@ static PROC nulldrv_wglGetProcAddress( LPCSTR name )
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;
}
static BOOL nulldrv_wglMakeCurrent( HDC hdc, HGLRC hglrc )
static BOOL nulldrv_wglMakeCurrent( HDC hdc, struct wgl_context *context )
{
return FALSE;
}
static BOOL nulldrv_wglShareLists( HGLRC org, HGLRC dst )
static BOOL nulldrv_wglShareLists( struct wgl_context *org, struct wgl_context *dst )
{
return FALSE;
}
......
......@@ -895,7 +895,7 @@ static void test_opengl3(HDC hdc)
HGLRC gl3Ctx;
DWORD error;
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();
/* The Nvidia implementation seems to return hresults instead of win32 error codes */
todo_wine ok(error == ERROR_INVALID_OPERATION ||
......
......@@ -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 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.@)
*/
......@@ -93,12 +171,16 @@ BOOL WINAPI wglSetPixelFormat( HDC hdc, INT iPixelFormat,
*/
BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
{
if (!hglrcSrc || !hglrcDst)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return wgl_driver->p_wglCopyContext(hglrcSrc, hglrcDst, mask);
struct wgl_handle *src, *dst;
BOOL ret = FALSE;
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
if ((dst = get_handle_ptr( hglrcDst )))
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)
*/
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 wgl_driver->p_wglDeleteContext(hglrc);
free_handle_ptr( ptr );
return TRUE;
}
/***********************************************************************
......@@ -119,12 +206,19 @@ BOOL WINAPI wglDeleteContext(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 );
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)
*/
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
*/
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.@)
*/
BOOL WINAPI wglShareLists(HGLRC hglrc1, HGLRC hglrc2)
BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
{
if (!hglrc1 || !hglrc2)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return wgl_driver->p_wglShareLists(hglrc1, hglrc2);
BOOL ret = FALSE;
struct wgl_handle *src, *dst;
if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
if ((dst = get_handle_ptr( hglrcDst )))
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)
*/
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)
*/
HGLRC WINAPI wglGetCurrentContext(void)
{
return NtCurrentTeb()->glContext;
return NtCurrentTeb()->glCurrentRC;
}
/***********************************************************************
......
......@@ -198,7 +198,7 @@ struct gdi_dc_funcs
};
/* 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_FONT_DRV 100 /* any font driver */
......@@ -226,18 +226,20 @@ static inline void push_dc_driver( PHYSDEV *dev, PHYSDEV physdev, const struct g
/* OpenGL support */
struct wgl_context;
struct wgl_funcs
{
INT (*p_GetPixelFormat)(HDC);
BOOL (*p_wglCopyContext)(HGLRC,HGLRC,UINT);
HGLRC (*p_wglCreateContext)(HDC);
HGLRC (*p_wglCreateContextAttribsARB)(HDC,HGLRC,const int*);
BOOL (*p_wglDeleteContext)(HGLRC);
HDC (*p_wglGetCurrentDC)(void);
PROC (*p_wglGetProcAddress)(LPCSTR);
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,HGLRC);
BOOL (*p_wglMakeCurrent)(HDC,HGLRC);
BOOL (*p_wglShareLists)(HGLRC,HGLRC);
INT (*p_GetPixelFormat)(HDC);
BOOL (*p_wglCopyContext)(struct wgl_context*,struct wgl_context*,UINT);
struct wgl_context* (*p_wglCreateContext)(HDC);
struct wgl_context* (*p_wglCreateContextAttribsARB)(HDC,struct wgl_context*,const int*);
BOOL (*p_wglDeleteContext)(struct wgl_context*);
HDC (*p_wglGetCurrentDC)(void);
PROC (*p_wglGetProcAddress)(LPCSTR);
BOOL (*p_wglMakeContextCurrentARB)(HDC,HDC,struct wgl_context*);
BOOL (*p_wglMakeCurrent)(HDC,struct wgl_context*);
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 */
......
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