From b68208f089cf44e6d2383a79a09be5c906ed3d5d Mon Sep 17 00:00:00 2001 From: Royce Mitchell III Date: Thu, 12 Feb 2004 23:56:15 +0000 Subject: [PATCH] patch by blight: Simple GL programs should work if you have hardware-accelerated video drivers installed, still some bugs left and things to implement; Have already played a model-flight simulator with it. svn path=/trunk/; revision=8162 --- reactos/lib/opengl32/opengl32.c | 37 ++++++---- reactos/lib/opengl32/opengl32.h | 4 +- reactos/lib/opengl32/wgl.c | 122 ++++++++++++++++++++------------ 3 files changed, 102 insertions(+), 61 deletions(-) diff --git a/reactos/lib/opengl32/opengl32.c b/reactos/lib/opengl32/opengl32.c index 8ae6c95f72e..ac35879d643 100644 --- a/reactos/lib/opengl32/opengl32.c +++ b/reactos/lib/opengl32/opengl32.c @@ -1,4 +1,4 @@ -/* $Id: opengl32.c,v 1.14 2004/02/09 08:00:15 vizzini Exp $ +/* $Id: opengl32.c,v 1.15 2004/02/12 23:56:15 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -34,13 +34,6 @@ static DWORD OPENGL32_InitializeDriver( GLDRIVERDATA *icd ); static BOOL OPENGL32_UnloadDriver( GLDRIVERDATA *icd ); /* global vars */ -/*const char* OPENGL32_funcnames[GLIDX_COUNT] SHARED = -{ -#define X(func, ret, typeargs, args) #func, - GLFUNCS_MACRO -#undef X -};*/ - DWORD OPENGL32_tls; GLPROCESSDATA OPENGL32_processdata; @@ -51,6 +44,8 @@ OPENGL32_ThreadDetach() { /* FIXME - do we need to release some HDC or something? */ GLTHREADDATA* lpData = NULL; + PROC *dispatchTable = NULL; + lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls ); if (lpData != NULL) { @@ -58,6 +53,16 @@ OPENGL32_ThreadDetach() DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)", GetLastError() ); } + + + dispatchTable = NtCurrentTeb()->glTable; + + if (dispatchTable != NULL) + { + if (!HeapFree( GetProcessHeap(), 0, dispatchTable )) + DBGPRINT( "Warning: HeapFree() on dispatch table failed (%d)", + GetLastError() ); + } } @@ -66,7 +71,7 @@ WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) { GLTHREADDATA* lpData = NULL; - ICDTable *dispatchTable = NULL; + PROC *dispatchTable = NULL; TEB *teb = NULL; SECURITY_ATTRIBUTES attrib = { sizeof (SECURITY_ATTRIBUTES), /* nLength */ NULL, /* lpSecurityDescriptor */ @@ -106,9 +111,9 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) /* The attached process creates a new thread. */ case DLL_THREAD_ATTACH: - dispatchTable = (ICDTable*)HeapAlloc( GetProcessHeap(), + dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, - sizeof (ICDTable) ); + sizeof (((ICDTable *)(0))->dispatch_table) ); if (dispatchTable == NULL) { DBGPRINT( "Error: Couldn't allocate GL dispatch table" ); @@ -129,13 +134,13 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) /* initialize dispatch table with empty functions */ #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \ - dispatchTable->dispatch_table[icdidx] = (PROC)glEmptyFunc##stack; \ + dispatchTable[icdidx] = (PROC)glEmptyFunc##stack; \ if (tebidx >= 0) \ teb->glDispatchTable[tebidx] = (PVOID)glEmptyFunc##stack; GLFUNCS_MACRO #undef X - teb->glTable = dispatchTable->dispatch_table; + teb->glTable = dispatchTable; TlsSetValue( OPENGL32_tls, lpData ); break; @@ -332,7 +337,7 @@ OPENGL32_InitializeDriver( GLDRIVERDATA *icd ) LOAD_DRV_PROC(icd, DrvSwapLayerBuffers, TRUE); /* we require at least one of DrvCreateContext and DrvCreateLayerContext */ - if (icd->DrvCreateContext == NULL || icd->DrvCreateLayerContext == NULL) + if (icd->DrvCreateContext == NULL && icd->DrvCreateLayerContext == NULL) { DBGPRINT( "Error: One of DrvCreateContext/DrvCreateLayerContext is required!" ); FreeLibrary( icd->handle ); @@ -464,8 +469,10 @@ OPENGL32_UnloadICD( GLDRIVERDATA *icd ) } icd->refcount--; - if (icd->refcount == 0) + //if (icd->refcount == 0) + if (0) ret = OPENGL32_UnloadDriver( icd ); + /* FIXME: InitializeICD crashes when called a second time */ /* release mutex */ if (!ReleaseMutex( OPENGL32_processdata.driver_mutex )) diff --git a/reactos/lib/opengl32/opengl32.h b/reactos/lib/opengl32/opengl32.h index 01e2ed35922..fee6b96418b 100644 --- a/reactos/lib/opengl32/opengl32.h +++ b/reactos/lib/opengl32/opengl32.h @@ -1,4 +1,4 @@ -/* $Id: opengl32.h,v 1.13 2004/02/11 17:39:24 vizzini Exp $ +/* $Id: opengl32.h,v 1.14 2004/02/12 23:56:15 royce Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -115,7 +115,7 @@ typedef struct tagGLDRIVERDATA BOOL APIENTRY (*DrvDescribeLayerPlane)( HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR ); int APIENTRY (*DrvDescribePixelFormat)( IN HDC, IN int, IN UINT, OUT LPPIXELFORMATDESCRIPTOR ); int APIENTRY (*DrvGetLayerPaletteEntries)( HDC, int, int, int, COLORREF * ); - FARPROC APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName ); + PROC APIENTRY (*DrvGetProcAddress)( LPCSTR lpProcName ); void APIENTRY (*DrvReleaseContext)(); BOOL APIENTRY (*DrvRealizeLayerPalette)( HDC, int, BOOL ); PICDTable APIENTRY (*DrvSetContext)( HDC hdc, HGLRC hglrc, SetContextCallBack callback ); diff --git a/reactos/lib/opengl32/wgl.c b/reactos/lib/opengl32/wgl.c index 12d3d99f4a2..76bc7286be5 100644 --- a/reactos/lib/opengl32/wgl.c +++ b/reactos/lib/opengl32/wgl.c @@ -127,7 +127,7 @@ WGL_ContainsContext( GLRC *glrc ) * be multiple times for one DrvSetContext call. * ARGUMENTS: [IN] table Function pointer table (first DWORD is number of * functions) - * RETURNS: unkown + * RETURNS: unkown (maybe void?) */ DWORD CALLBACK @@ -136,18 +136,27 @@ WGL_SetContextCallBack( const ICDTable *table ) /* UINT i;*/ TEB *teb; PROC *tebTable, *tebDispatchTable; + INT size; teb = NtCurrentTeb(); tebTable = (PROC *)teb->glTable; tebDispatchTable = (PROC *)teb->glDispatchTable; - DBGPRINT( "Function count: %d\n", table->num_funcs ); + if (table != NULL) + { + DBGPRINT( "Function count: %d\n", table->num_funcs ); - /* save table */ - memcpy( tebTable, table->dispatch_table, - sizeof (PROC) * table->num_funcs ); - memset( tebTable + sizeof (PROC) * table->num_funcs, 0, - sizeof (table->dispatch_table) - (sizeof (PROC) * table->num_funcs) ); + /* save table */ + size = sizeof (PROC) * table->num_funcs; + memcpy( tebTable, table->dispatch_table, size ); + memset( tebTable + table->num_funcs, 0, + sizeof (table->dispatch_table) - size ); + } + else + { + DBGPRINT( "Unsetting current context" ); + memset( tebTable, 0, sizeof (table->dispatch_table) ); + } /* FIXME: pull in software fallbacks -- need mesa */ #if 0 /* unused atm */ @@ -165,7 +174,8 @@ WGL_SetContextCallBack( const ICDTable *table ) #define X(func, ret, typeargs, args, icdidx, tebidx, stack) \ if (tebTable[icdidx] == NULL) \ { \ - DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \ + if (table != NULL) \ + DBGPRINT( "Warning: GL proc '%s' is NULL", #func ); \ tebTable[icdidx] = (PROC)glEmptyFunc##stack; \ } GLFUNCS_MACRO @@ -209,6 +219,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd ) /* check input */ if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1) { + OPENGL32_UnloadICD( icd ); SetLastError( 0 ); /* FIXME: use appropriate errorcode */ return 0; } @@ -219,6 +230,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd ) if (icdNumFormats == 0) { DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() ); + OPENGL32_UnloadICD( icd ); return 0; } DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats ); @@ -269,6 +281,7 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd ) if (best == 0) SetLastError( 0 ); /* FIXME: set appropriate error */ + OPENGL32_UnloadICD( icd ); DBGPRINT( "Info: Suggesting pixelformat %d", best ); return best; @@ -503,6 +516,7 @@ rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes, ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd ); if (ret == 0) DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() ); + OPENGL32_UnloadICD( icd ); } /* FIXME: implement own functionality? */ @@ -576,7 +590,9 @@ rosglGetProcAddress( LPCSTR proc ) if (proc[0] == 'g' && proc[1] == 'l') /* glXXX */ { - PROC glXXX = OPENGL32_threaddata->glrc->icd->DrvGetProcAddress( proc ); + PROC glXXX = NULL; + GLDRIVERDATA *icd = OPENGL32_threaddata->glrc->icd; + glXXX = icd->DrvGetProcAddress( proc ); if (glXXX) { DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc ); @@ -619,47 +635,61 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc ) glFlush(); } - /* check hdc */ - if (GetObjectType( hdc ) != OBJ_DC) + /* check if current context is unset */ + if (glrc == NULL) { - DBGPRINT( "Error: hdc is not a DC handle!" ); - return FALSE; - } - - /* check if we know about this glrc */ - if (!WGL_ContainsContext( glrc )) - { - DBGPRINT( "Error: hglrc not found!" ); - return FALSE; /* FIXME: SetLastError() */ - } - - /* check if it is available */ - if (glrc->is_current) /* used by another thread */ - { - DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id ); - return FALSE; /* FIXME: SetLastError() */ - } - - /* call the ICD */ - if (glrc->hglrc != NULL) - { - icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc, - WGL_SetContextCallBack ); - if (icdTable == NULL) + if (OPENGL32_threaddata->glrc != NULL) { - DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() ); + OPENGL32_threaddata->glrc->is_current = FALSE; + OPENGL32_threaddata->glrc = NULL; + } + } + else + { + /* check hdc */ + if (GetObjectType( hdc ) != OBJ_DC && GetObjectType( hdc ) != OBJ_MEMDC) + { + DBGPRINT( "Error: hdc is not a DC handle!" ); return FALSE; } - DBGPRINT( "Info: DrvSetContext succeeded!" ); + + /* check if we know about this glrc */ + if (!WGL_ContainsContext( glrc )) + { + DBGPRINT( "Error: hglrc not found!" ); + return FALSE; /* FIXME: SetLastError() */ + } + + /* check if it is available */ + if (glrc->is_current && glrc->thread_id != GetCurrentThreadId()) /* used by another thread */ + { + DBGPRINT( "Error: hglrc is current for thread 0x%08x", glrc->thread_id ); + return FALSE; /* FIXME: SetLastError() */ + } + + /* call the ICD */ + if (glrc->hglrc != NULL) + { + icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc, + WGL_SetContextCallBack ); + if (icdTable == NULL) + { + DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() ); + return FALSE; + } + DBGPRINT( "Info: DrvSetContext succeeded!" ); + } + + /* make it current */ + if (OPENGL32_threaddata->glrc != NULL) + OPENGL32_threaddata->glrc->is_current = FALSE; + glrc->is_current = TRUE; + glrc->thread_id = GetCurrentThreadId(); + glrc->hdc = hdc; + OPENGL32_threaddata->glrc = glrc; } - /* make it current */ - if (OPENGL32_threaddata->glrc != NULL) - OPENGL32_threaddata->glrc->is_current = FALSE; - glrc->is_current = TRUE; - glrc->thread_id = GetCurrentThreadId(); - glrc->hdc = hdc; - OPENGL32_threaddata->glrc = glrc; + WGL_SetContextCallBack( icdTable ); if (icdTable != NULL) if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS) @@ -704,11 +734,13 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd ) { DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)", iFormat, GetLastError() ); + OPENGL32_UnloadICD( icd ); return FALSE; } OPENGL32_processdata.cachedHdc = hdc; OPENGL32_processdata.cachedFormat = iFormat; + OPENGL32_UnloadICD( icd ); return TRUE; } @@ -764,8 +796,10 @@ rosglSwapBuffers( HDC hdc ) if (!icd->DrvSwapBuffers( hdc )) { DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() ); + OPENGL32_UnloadICD( icd ); return FALSE; } + OPENGL32_UnloadICD( icd ); return TRUE; }