- OpenGL bug fixes and cleanup. Patch by Anich Gregor.

svn path=/trunk/; revision=8497
This commit is contained in:
Filip Navara 2004-03-01 19:36:21 +00:00
parent 279a889834
commit a7c8c741c3
3 changed files with 330 additions and 165 deletions

View file

@ -1,4 +1,4 @@
/* $Id: opengl32.c,v 1.15 2004/02/12 23:56:15 royce Exp $ /* $Id: opengl32.c,v 1.16 2004/03/01 19:36:20 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -17,14 +17,6 @@
#include <string.h> #include <string.h>
#include "opengl32.h" #include "opengl32.h"
#define EXT_GET_DRIVERINFO 0x1101 /* ExtEscape code to get driver info */
typedef struct tagEXTDRIVERINFO
{
DWORD version; /* driver interface version */
DWORD driver_version; /* driver version */
WCHAR driver_name[256]; /* driver name */
} EXTDRIVERINFO;
/* function prototypes */ /* function prototypes */
/*static BOOL OPENGL32_LoadDrivers();*/ /*static BOOL OPENGL32_LoadDrivers();*/
static void OPENGL32_AppendICD( GLDRIVERDATA *icd ); static void OPENGL32_AppendICD( GLDRIVERDATA *icd );
@ -54,9 +46,7 @@ OPENGL32_ThreadDetach()
GetLastError() ); GetLastError() );
} }
dispatchTable = NtCurrentTeb()->glTable; dispatchTable = NtCurrentTeb()->glTable;
if (dispatchTable != NULL) if (dispatchTable != NULL)
{ {
if (!HeapFree( GetProcessHeap(), 0, dispatchTable )) if (!HeapFree( GetProcessHeap(), 0, dispatchTable ))
@ -66,6 +56,56 @@ OPENGL32_ThreadDetach()
} }
static
void
OPENGL32_ProcessDetach()
{
GLDRIVERDATA *icd, *icd2;
GLDCDATA *dcdata, *dcdata2;
GLRC *glrc, *glrc2;
/* free lists */
for (dcdata = OPENGL32_processdata.dcdata_list; dcdata != NULL;)
{
dcdata2 = dcdata;
dcdata = dcdata->next;
if (!HeapFree( GetProcessHeap(), 0, dcdata ))
DBGPRINT( "Warning: HeapFree() on DCDATA 0x%08x failed (%d)",
dcdata, GetLastError() );
}
for (glrc = OPENGL32_processdata.glrc_list; glrc != NULL;)
{
glrc2 = glrc;
glrc = glrc->next;
if (!HeapFree( GetProcessHeap(), 0, glrc ))
DBGPRINT( "Warning: HeapFree() on GLRC 0x%08x failed (%d)",
glrc, GetLastError() );
}
for (icd = OPENGL32_processdata.driver_list; icd != NULL;)
{
icd2 = icd;
icd = icd->next;
if (!HeapFree( GetProcessHeap(), 0, icd ))
DBGPRINT( "Warning: HeapFree() on DRIVERDATA 0x%08x failed (%d)",
icd, GetLastError() );
}
/* free mutexes */
if (OPENGL32_processdata.driver_mutex != NULL)
CloseHandle( OPENGL32_processdata.driver_mutex );
if (OPENGL32_processdata.glrc_mutex != NULL)
CloseHandle( OPENGL32_processdata.glrc_mutex );
if (OPENGL32_processdata.dcdata_mutex != NULL)
CloseHandle( OPENGL32_processdata.dcdata_mutex );
/* free TLS */
if (OPENGL32_tls != 0xffffffff)
TlsFree(OPENGL32_tls);
}
BOOL BOOL
WINAPI WINAPI
DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved) DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
@ -84,33 +124,41 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
* initialization or a call to LoadLibrary. * initialization or a call to LoadLibrary.
*/ */
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DBGTRACE( "Process attach" );
OPENGL32_tls = TlsAlloc(); OPENGL32_tls = TlsAlloc();
if ( 0xFFFFFFFF == OPENGL32_tls ) if ( 0xFFFFFFFF == OPENGL32_tls )
return FALSE; return FALSE;
memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) ); memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) );
/* create driver & glrc list mutex */ /* create driver, glrc & dcdata list mutex */
OPENGL32_processdata.driver_mutex = CreateMutex( &attrib, FALSE, NULL ); OPENGL32_processdata.driver_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.driver_mutex == NULL) if (OPENGL32_processdata.driver_mutex == NULL)
{ {
DBGPRINT( "Error: Couldn't create driver_list mutex (%d)", DBGPRINT( "Error: Couldn't create driver_list mutex (%d)",
GetLastError() ); GetLastError() );
TlsFree( OPENGL32_tls ); return FALSE;
} }
OPENGL32_processdata.glrc_mutex = CreateMutex( &attrib, FALSE, NULL ); OPENGL32_processdata.glrc_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.glrc_mutex == NULL) if (OPENGL32_processdata.glrc_mutex == NULL)
{ {
DBGPRINT( "Error: Couldn't create glrc_list mutex (%d)", DBGPRINT( "Error: Couldn't create glrc_list mutex (%d)",
GetLastError() ); GetLastError() );
CloseHandle( OPENGL32_processdata.driver_mutex ); return FALSE;
TlsFree( OPENGL32_tls ); }
OPENGL32_processdata.dcdata_mutex = CreateMutex( &attrib, FALSE, NULL );
if (OPENGL32_processdata.dcdata_mutex == NULL)
{
DBGPRINT( "Error: Couldn't create dcdata_list mutex (%d)",
GetLastError() );
return FALSE;
} }
/* No break: Initialize the index for first thread. */ /* No break: Initialize the index for first thread. */
/* The attached process creates a new thread. */ /* The attached process creates a new thread. */
case DLL_THREAD_ATTACH: case DLL_THREAD_ATTACH:
DBGTRACE( "Thread attach" );
dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(), dispatchTable = (PROC*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (((ICDTable *)(0))->dispatch_table) ); sizeof (((ICDTable *)(0))->dispatch_table) );
@ -146,18 +194,16 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
/* The thread of the attached process terminates. */ /* The thread of the attached process terminates. */
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
DBGTRACE( "Thread detach" );
/* Release the allocated memory for this thread.*/ /* Release the allocated memory for this thread.*/
OPENGL32_ThreadDetach(); OPENGL32_ThreadDetach();
break; break;
/* DLL unload due to process termination or FreeLibrary. */ /* DLL unload due to process termination or FreeLibrary. */
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
DBGTRACE( "Process detach" );
OPENGL32_ThreadDetach(); OPENGL32_ThreadDetach();
OPENGL32_ProcessDetach();
/* FIXME: free resources (driver list, glrc list) */
CloseHandle( OPENGL32_processdata.driver_mutex );
CloseHandle( OPENGL32_processdata.glrc_mutex );
TlsFree(OPENGL32_tls);
break; break;
} }
return TRUE; return TRUE;
@ -382,32 +428,6 @@ OPENGL32_UnloadDriver( GLDRIVERDATA *icd )
} }
/* FUNCTION: Load ICD from HDC (shared ICD data)
* RETURNS: GLDRIVERDATA pointer on success, NULL otherwise.
* NOTES: Make sure the handle you pass in is one for a DC!
* Increases the refcount of the ICD - use
* OPENGL32_UnloadICD to release the ICD.
*/
GLDRIVERDATA *OPENGL32_LoadICDForHDC( HDC hdc )
{
DWORD dwInput = 0;
LONG ret;
EXTDRIVERINFO info;
/* get driver name */
ret = ExtEscape( hdc, EXT_GET_DRIVERINFO, sizeof (dwInput), (LPCSTR)&dwInput,
sizeof (EXTDRIVERINFO), (LPSTR)&info );
if (ret < 0)
{
DBGPRINT( "Warning: ExtEscape to get the drivername failed!!! (%d)", GetLastError() );
return 0;
}
/* load driver (or get a reference) */
return OPENGL32_LoadICD( info.driver_name );
}
/* FUNCTION: Load ICD (shared ICD data) /* FUNCTION: Load ICD (shared ICD data)
* RETURNS: GLDRIVERDATA pointer on success, NULL otherwise. * RETURNS: GLDRIVERDATA pointer on success, NULL otherwise.
*/ */

View file

@ -1,4 +1,4 @@
/* $Id: opengl32.h,v 1.14 2004/02/12 23:56:15 royce Exp $ /* $Id: opengl32.h,v 1.15 2004/03/01 19:36:21 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -28,6 +28,7 @@ extern "C" {
# define DEBUG_OPENGL32_BRKPTS /* enable breakpoints */ # define DEBUG_OPENGL32_BRKPTS /* enable breakpoints */
# define DEBUG_OPENGL32_ICD_EXPORTS /* dumps the list of (un)supported glXXX # define DEBUG_OPENGL32_ICD_EXPORTS /* dumps the list of (un)supported glXXX
functions when an ICD is loaded. */ functions when an ICD is loaded. */
# define DEBUG_OPENGL32_TRACE /* prints much information about whats going on */
#endif /* !NDEBUG */ #endif /* !NDEBUG */
/* debug macros */ /* debug macros */
@ -54,6 +55,10 @@ ULONG DbgPrint(PCH Format,...);
# endif # endif
#endif #endif
#ifdef DEBUG_OPENGL32_TRACE
# define DBGTRACE( args... ) DBGPRINT( args )
#endif
/* function/data attributes */ /* function/data attributes */
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
#ifdef _MSC_VER #ifdef _MSC_VER
@ -129,7 +134,7 @@ typedef struct tagGLDRIVERDATA
struct tagGLDRIVERDATA *next; /* next ICD -- linked list */ struct tagGLDRIVERDATA *next; /* next ICD -- linked list */
} GLDRIVERDATA; } GLDRIVERDATA;
/* Out private OpenGL context (saved in TLS) */ /* Our private OpenGL context (stored in TLS) */
typedef struct tagGLRC typedef struct tagGLRC
{ {
GLDRIVERDATA *icd; /* driver used for this context */ GLDRIVERDATA *icd; /* driver used for this context */
@ -142,15 +147,26 @@ typedef struct tagGLRC
struct tagGLRC *next; /* linked list */ struct tagGLRC *next; /* linked list */
} GLRC; } GLRC;
/* OpenGL private device context data */
typedef struct tagGLDCDATA
{
HDC hdc; /* device context handle for which this data is */
GLDRIVERDATA *icd; /* driver used for this DC */
int pixel_format; /* selected pixel format */
struct tagGLDCDATA *next; /* linked list */
} GLDCDATA;
/* Process data */ /* Process data */
typedef struct tagGLPROCESSDATA typedef struct tagGLPROCESSDATA
{ {
GLDRIVERDATA *driver_list; /* list of loaded drivers */ GLDRIVERDATA *driver_list; /* list of loaded drivers */
HANDLE driver_mutex; /* mutex to protect driver list */ HANDLE driver_mutex; /* mutex to protect driver list */
GLRC *glrc_list; /* list of GL rendering contexts */ GLRC *glrc_list; /* list of GL rendering contexts */
HANDLE glrc_mutex; /* mutex to protect glrc list */ HANDLE glrc_mutex; /* mutex to protect glrc list */
HDC cachedHdc; /* cached HDC from last SetPixelFormat */ GLDCDATA *dcdata_list; /* list of GL private DC data */
INT cachedFormat; /* cached format from last SetPixelFormat */ HANDLE dcdata_mutex; /* mutex to protect glrc list */
} GLPROCESSDATA; } GLPROCESSDATA;
/* TLS data */ /* TLS data */
@ -164,7 +180,7 @@ extern GLPROCESSDATA OPENGL32_processdata;
#define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls )) #define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls ))
/* function prototypes */ /* function prototypes */
GLDRIVERDATA *OPENGL32_LoadICDForHDC( HDC hdc ); /*GLDRIVERDATA *OPENGL32_LoadICDForHDC( HDC hdc );*/
GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver ); GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver );
BOOL OPENGL32_UnloadICD( GLDRIVERDATA *icd ); BOOL OPENGL32_UnloadICD( GLDRIVERDATA *icd );
DWORD OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName ); DWORD OPENGL32_RegEnumDrivers( DWORD idx, LPWSTR name, LPDWORD cName );

View file

@ -21,12 +21,22 @@ extern "C" {
#define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" ) #define UNIMPLEMENTED DBGPRINT( "UNIMPLEMENTED" )
#endif//_MSC_VER #endif//_MSC_VER
#define EXT_GET_DRIVERINFO 0x1101 /* ExtEscape code to get driver info */
typedef struct tagEXTDRIVERINFO
{
DWORD version; /* driver interface version */
DWORD driver_version; /* driver version */
WCHAR driver_name[256]; /* driver name */
} EXTDRIVERINFO;
/* FUNCTION: Append OpenGL Rendering Context (GLRC) to list /* FUNCTION: Append OpenGL Rendering Context (GLRC) to list
* ARGUMENTS: [IN] glrc: GLRC to append to list * ARGUMENTS: [IN] glrc: GLRC to append to list
*/ */
static static
void void
WGL_AppendContext( GLRC *glrc ) ROSGL_AppendContext( GLRC *glrc )
{ {
/* synchronize */ /* synchronize */
if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) == if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
@ -57,7 +67,7 @@ WGL_AppendContext( GLRC *glrc )
*/ */
static static
void void
WGL_RemoveContext( GLRC *glrc ) ROSGL_RemoveContext( GLRC *glrc )
{ {
/* synchronize */ /* synchronize */
if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) == if (WaitForSingleObject( OPENGL32_processdata.glrc_mutex, INFINITE ) ==
@ -89,12 +99,55 @@ WGL_RemoveContext( GLRC *glrc )
DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() ); DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
} }
/* FUNCTION: Create a new GL Context (GLRC) and append it to the list
* RETURNS: Pointer to new GLRC on success; NULL on failure
*/
static
GLRC *
ROSGL_NewContext()
{
GLRC *glrc;
/* allocate GLRC */
glrc = (GLRC*)HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
/* append to list */
ROSGL_AppendContext( glrc );
return glrc;
}
/* FUNCTION: Delete a GL Context (GLRC) and remove it from the list
* ARGUMENTS: [IN] glrc GLRC to delete
* RETURNS: TRUE if there were no error; FALSE otherwise
*/
static
BOOL
ROSGL_DeleteContext( GLRC *glrc )
{
/* unload icd */
if (glrc->icd != NULL)
OPENGL32_UnloadICD( glrc->icd );
/* remove from list */
ROSGL_RemoveContext( glrc );
/* free memory */
HeapFree( GetProcessHeap(), 0, glrc );
return TRUE;
}
/* FUNCTION: Check wether a GLRC is in the list /* FUNCTION: Check wether a GLRC is in the list
* ARGUMENTS: [IN] glrc: GLRC to remove from list * ARGUMENTS: [IN] glrc: GLRC to remove from list
*/ */
static static
BOOL BOOL
WGL_ContainsContext( GLRC *glrc ) ROSGL_ContainsContext( GLRC *glrc )
{ {
GLRC *p; GLRC *p;
@ -122,16 +175,119 @@ WGL_ContainsContext( GLRC *glrc )
} }
/* FUNCTION: Get GL private DC data. Adds an empty GLDCDATA to the list if
* there is no data for the given DC and returns it.
* ARGUMENTS: [IN] hdc Device Context for which to get the data
* RETURNS: Pointer to GLDCDATA on success; NULL on failure
*/
static
GLDCDATA *
ROSGL_GetPrivateDCData( HDC hdc )
{
GLDCDATA *data;
/* synchronize */
if (WaitForSingleObject( OPENGL32_processdata.dcdata_mutex, INFINITE ) ==
WAIT_FAILED)
{
DBGPRINT( "Error: WaitForSingleObject() failed (%d)", GetLastError() );
return NULL; /* FIXME: do we have to expect such an error and handle it? */
}
/* look for data in list */
data = OPENGL32_processdata.dcdata_list;
while (data != NULL)
{
if (data->hdc == hdc) /* found */
break;
data = data->next;
}
/* allocate new data if not found in list */
if (data == NULL)
{
data = HeapAlloc( GetProcessHeap(),
HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS,
sizeof (GLDCDATA) );
if (data == NULL)
{
DBGPRINT( "Error: HeapAlloc() failed (%d)", GetLastError() );
}
else
{
data->hdc = hdc;
/* append data to list */
if (OPENGL32_processdata.dcdata_list == NULL)
OPENGL32_processdata.dcdata_list = data;
else
{
GLDCDATA *p = OPENGL32_processdata.dcdata_list;
while (p->next != NULL)
p = p->next;
p->next = data;
}
}
}
/* release mutex */
if (!ReleaseMutex( OPENGL32_processdata.dcdata_mutex ))
DBGPRINT( "Error: ReleaseMutex() failed (%d)", GetLastError() );
return data;
}
/* FUNCTION: Get ICD from HDC
* RETURNS: GLDRIVERDATA pointer on success, NULL otherwise.
* NOTES: Make sure the handle you pass in is one for a DC!
*/
static
GLDRIVERDATA *
ROSGL_ICDForHDC( HDC hdc )
{
GLDCDATA *dcdata;
dcdata = ROSGL_GetPrivateDCData( hdc );
if (dcdata == NULL)
return NULL;
if (dcdata->icd == NULL)
#if 1
{
DWORD dwInput = 0;
LONG ret;
EXTDRIVERINFO info;
/* get driver name */
ret = ExtEscape( hdc, EXT_GET_DRIVERINFO, sizeof (dwInput), (LPCSTR)&dwInput,
sizeof (EXTDRIVERINFO), (LPSTR)&info );
if (ret < 0)
{
DBGPRINT( "Warning: ExtEscape to get the drivername failed!!! (%d)", GetLastError() );
return 0;
}
/* load driver (or get a reference) */
dcdata->icd = OPENGL32_LoadICD( info.driver_name );
}
#else
dcdata->icd = OPENGL32_LoadICD( L"OGLICD" );
#endif
return dcdata->icd;
}
/* FUNCTION: SetContextCallBack passed to DrvSetContext. Gets called whenever /* FUNCTION: SetContextCallBack passed to DrvSetContext. Gets called whenever
* the current GL context (dispatch table) is to be changed - can * the current GL context (dispatch table) is to be changed.
* be multiple times for one DrvSetContext call.
* ARGUMENTS: [IN] table Function pointer table (first DWORD is number of * ARGUMENTS: [IN] table Function pointer table (first DWORD is number of
* functions) * functions)
* RETURNS: unkown (maybe void?) * RETURNS: unkown (maybe void?)
*/ */
DWORD DWORD
CALLBACK CALLBACK
WGL_SetContextCallBack( const ICDTable *table ) ROSGL_SetContextCallBack( const ICDTable *table )
{ {
/* UINT i;*/ /* UINT i;*/
TEB *teb; TEB *teb;
@ -211,26 +367,27 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
const DWORD compareFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | const DWORD compareFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL; PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL;
DBGTRACE( "Called!" );
/* load ICD */ /* load ICD */
icd = OPENGL32_LoadICDForHDC( hdc ); icd = ROSGL_ICDForHDC( hdc );
if (icd == NULL) if (icd == NULL)
return 0; return 0;
/* check input */ /* check input */
if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1) if (pfd->nSize != sizeof (PIXELFORMATDESCRIPTOR) || pfd->nVersion != 1)
{ {
OPENGL32_UnloadICD( icd );
SetLastError( 0 ); /* FIXME: use appropriate errorcode */ SetLastError( 0 ); /* FIXME: use appropriate errorcode */
return 0; return 0;
} }
/* get number of formats -- FIXME: use 1 or 0 as index? */ /* get number of formats */
icdNumFormats = icd->DrvDescribePixelFormat( hdc, 0, // __asm__( "int $3" );
sizeof (PIXELFORMATDESCRIPTOR), NULL ); icdNumFormats = icd->DrvDescribePixelFormat( hdc, 1,
sizeof (PIXELFORMATDESCRIPTOR), &icdPfd );
if (icdNumFormats == 0) if (icdNumFormats == 0)
{ {
DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() ); DBGPRINT( "Error: DrvDescribePixelFormat failed (%d)", GetLastError() );
OPENGL32_UnloadICD( icd );
return 0; return 0;
} }
DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats ); DBGPRINT( "Info: Enumerating %d pixelformats", icdNumFormats );
@ -281,7 +438,6 @@ rosglChoosePixelFormat( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
if (best == 0) if (best == 0)
SetLastError( 0 ); /* FIXME: set appropriate error */ SetLastError( 0 ); /* FIXME: set appropriate error */
OPENGL32_UnloadICD( icd );
DBGPRINT( "Info: Suggesting pixelformat %d", best ); DBGPRINT( "Info: Suggesting pixelformat %d", best );
return best; return best;
@ -302,12 +458,12 @@ rosglCopyContext( HGLRC hsrc, HGLRC hdst, UINT mask )
GLRC *dst = (GLRC *)hdst; GLRC *dst = (GLRC *)hdst;
/* check glrcs */ /* check glrcs */
if (!WGL_ContainsContext( src )) if (!ROSGL_ContainsContext( src ))
{ {
DBGPRINT( "Error: src GLRC not found!" ); DBGPRINT( "Error: src GLRC not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
} }
if (!WGL_ContainsContext( dst )) if (!ROSGL_ContainsContext( dst ))
{ {
DBGPRINT( "Error: dst GLRC not found!" ); DBGPRINT( "Error: dst GLRC not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
@ -335,10 +491,6 @@ HGLRC
APIENTRY APIENTRY
rosglCreateLayerContext( HDC hdc, int layer ) rosglCreateLayerContext( HDC hdc, int layer )
{ {
/* LONG ret;
WCHAR driver[256];
DWORD dw, size;*/
GLDRIVERDATA *icd = NULL; GLDRIVERDATA *icd = NULL;
GLRC *glrc; GLRC *glrc;
HGLRC drvHglrc = NULL; HGLRC drvHglrc = NULL;
@ -349,57 +501,13 @@ rosglCreateLayerContext( HDC hdc, int layer )
return NULL; return NULL;
} }
*/ */
/* allocate our GLRC */ /* create new GLRC */
glrc = (GLRC*)HeapAlloc( GetProcessHeap(), glrc = ROSGL_NewContext();
HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, sizeof (GLRC) );
if (glrc == NULL) if (glrc == NULL)
return NULL; return NULL;
#if 0 /* old code */
/* try to find an ICD */
for (dw = 0; drvHglrc == NULL; dw++) /* enumerate values */
{
size = sizeof (driver) / sizeof (driver[0]);
ret = OPENGL32_RegEnumDrivers( dw, driver, &size );
if (ret != ERROR_SUCCESS)
break;
icd = OPENGL32_LoadICD( driver );
if (icd == NULL) /* try next ICD */
continue;
if (icd->DrvCreateLayerContext)
drvHglrc = icd->DrvCreateLayerContext( hdc, layer );
if (drvHglrc == NULL)
{
if (layer == 0)
drvHglrc = icd->DrvCreateContext( hdc );
else
DBGPRINT( "Warning: CreateLayerContext not supported by ICD!" );
}
if (drvHglrc == NULL) /* try next ICD */
{
DBGPRINT( "Info: DrvCreateContext (driver = %ws) failed: %d",
icd->driver_name, GetLastError() );
OPENGL32_UnloadICD( icd );
continue;
}
/* the ICD was loaded successfully and we got a HGLRC in drvHglrc */
break;
}
if (drvHglrc == NULL || icd == NULL) /* no ICD was found */
{
/* FIXME: fallback to mesa */
DBGPRINT( "Error: No working ICD found!" );
HeapFree( GetProcessHeap(), 0, glrc );
return NULL;
}
#endif /* unused */
/* load ICD */ /* load ICD */
icd = OPENGL32_LoadICDForHDC( hdc ); icd = ROSGL_ICDForHDC( hdc );
if (icd == NULL) if (icd == NULL)
{ {
DBGPRINT( "Couldn't get ICD by HDC :-(" ); DBGPRINT( "Couldn't get ICD by HDC :-(" );
@ -422,8 +530,7 @@ rosglCreateLayerContext( HDC hdc, int layer )
{ {
/* FIXME: fallback to mesa? */ /* FIXME: fallback to mesa? */
DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() ); DBGPRINT( "Error: DrvCreate[Layer]Context failed! (%d)", GetLastError() );
OPENGL32_UnloadICD( icd ); ROSGL_DeleteContext( glrc );
HeapFree( GetProcessHeap(), 0, glrc );
return NULL; return NULL;
} }
@ -431,9 +538,6 @@ rosglCreateLayerContext( HDC hdc, int layer )
glrc->hglrc = drvHglrc; glrc->hglrc = drvHglrc;
glrc->icd = icd; glrc->icd = icd;
/* append glrc to context list */
WGL_AppendContext( glrc );
return (HGLRC)glrc; return (HGLRC)glrc;
} }
@ -461,7 +565,7 @@ rosglDeleteContext( HGLRC hglrc )
GLRC *glrc = (GLRC *)hglrc; GLRC *glrc = (GLRC *)hglrc;
/* check if we know about this context */ /* check if we know about this context */
if (!WGL_ContainsContext( glrc )) if (!ROSGL_ContainsContext( glrc ))
{ {
DBGPRINT( "Error: hglrc not found!" ); DBGPRINT( "Error: hglrc not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
@ -485,38 +589,41 @@ rosglDeleteContext( HGLRC hglrc )
} }
/* free resources */ /* free resources */
OPENGL32_UnloadICD( glrc->icd ); return ROSGL_DeleteContext( glrc );
WGL_RemoveContext( glrc );
HeapFree( GetProcessHeap(), 0, glrc );
return TRUE;
} }
BOOL BOOL
APIENTRY APIENTRY
rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane, rosglDescribeLayerPlane( HDC hdc, int iPixelFormat, int iLayerPlane,
UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd ) UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd )
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return FALSE; return FALSE;
} }
/* FUNCTION: Gets information about the pixelformat specified by iFormat and
* puts it into pfd.
* ARGUMENTS: [IN] hdc Handle to DC
* [IN] iFormat Pixelformat index
* [IN] nBytes sizeof (pfd) - at most nBytes are copied into pfd
* [OUT] pfd Pointer to a PIXELFORMATDESCRIPTOR
* RETURNS: Maximum pixelformat index/number of formats on success; 0 on failure
*/
int int
APIENTRY APIENTRY
rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes, rosglDescribePixelFormat( HDC hdc, int iFormat, UINT nBytes,
LPPIXELFORMATDESCRIPTOR pfd ) LPPIXELFORMATDESCRIPTOR pfd )
{ {
int ret = 0; int ret = 0;
GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc ); GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
if (icd != NULL) if (icd != NULL)
{ {
ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd ); ret = icd->DrvDescribePixelFormat( hdc, iFormat, nBytes, pfd );
if (ret == 0) if (ret == 0)
DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() ); DBGPRINT( "Error: DrvDescribePixelFormat(format=%d) failed (%d)", iFormat, GetLastError() );
OPENGL32_UnloadICD( icd );
} }
/* FIXME: implement own functionality? */ /* FIXME: implement own functionality? */
@ -553,24 +660,33 @@ rosglGetCurrentDC()
int int
APIENTRY APIENTRY
rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart, rosglGetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
int cEntries, COLORREF *pcr ) int cEntries, COLORREF *pcr )
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return 0; return 0;
} }
/* FUNCTION: Returns the current pixelformat for the given hdc.
* ARGUMENTS: [IN] hdc Handle to DC of which to get the pixelformat
* RETURNS: Pixelformat index on success; 0 on failure
*/
int int
WINAPI WINAPI
rosglGetPixelFormat( HDC hdc ) rosglGetPixelFormat( HDC hdc )
{ {
if (OPENGL32_processdata.cachedHdc == hdc) GLDCDATA *dcdata;
return OPENGL32_processdata.cachedFormat;
/* FIXME: create real implementation of this function */ DBGTRACE( "Called!" );
DBGPRINT( "Warning: Pixel format not cached, returning 0" );
return 0; dcdata = ROSGL_GetPrivateDCData( hdc );
if (dcdata == NULL)
{
DBGPRINT( "Error: ROSGL_GetPrivateDCData failed!" );
return 0;
}
return dcdata->pixel_format;
} }
@ -654,7 +770,7 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
} }
/* check if we know about this glrc */ /* check if we know about this glrc */
if (!WGL_ContainsContext( glrc )) if (!ROSGL_ContainsContext( glrc ))
{ {
DBGPRINT( "Error: hglrc not found!" ); DBGPRINT( "Error: hglrc not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
@ -671,7 +787,7 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
if (glrc->hglrc != NULL) if (glrc->hglrc != NULL)
{ {
icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc, icdTable = glrc->icd->DrvSetContext( hdc, glrc->hglrc,
WGL_SetContextCallBack ); ROSGL_SetContextCallBack );
if (icdTable == NULL) if (icdTable == NULL)
{ {
DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() ); DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
@ -689,13 +805,10 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
OPENGL32_threaddata->glrc = glrc; OPENGL32_threaddata->glrc = glrc;
} }
WGL_SetContextCallBack( icdTable ); if (ROSGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS)
{
if (icdTable != NULL) DBGPRINT( "Warning: ROSGL_SetContextCallBack failed!" );
if (WGL_SetContextCallBack( icdTable ) != ERROR_SUCCESS) }
{
DBGPRINT( "Warning: WGL_SetContextCallBack failed!" );
}
return TRUE; return TRUE;
} }
@ -713,34 +826,52 @@ rosglRealizeLayerPalette( HDC hdc, int iLayerPlane, BOOL bRealize )
int int
APIENTRY APIENTRY
rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart, rosglSetLayerPaletteEntries( HDC hdc, int iLayerPlane, int iStart,
int cEntries, CONST COLORREF *pcr ) int cEntries, CONST COLORREF *pcr )
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return 0; return 0;
} }
/* FUNCTION: Set pixelformat of given DC
* ARGUMENTS: [IN] hdc Handle to DC for which to set the format
* [IN] iFormat Index of the pixelformat to set
* [IN] pfd Not sure what this is for
* RETURNS: TRUE on success, FALSE on failure
*/
BOOL BOOL
WINAPI WINAPI
rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd ) rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
{ {
GLDRIVERDATA *icd; GLDRIVERDATA *icd;
GLDCDATA *dcdata;
icd = OPENGL32_LoadICDForHDC( hdc ); DBGTRACE( "Called!" );
/* load ICD */
icd = ROSGL_ICDForHDC( hdc );
if (icd == NULL) if (icd == NULL)
{
DBGPRINT( "Warning: ICDForHDC() failed" );
return FALSE; return FALSE;
}
/* call ICD */
if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd )) if (!icd->DrvSetPixelFormat( hdc, iFormat, pfd ))
{ {
DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)", DBGPRINT( "Warning: DrvSetPixelFormat(format=%d) failed (%d)",
iFormat, GetLastError() ); iFormat, GetLastError() );
OPENGL32_UnloadICD( icd );
return FALSE; return FALSE;
} }
OPENGL32_processdata.cachedHdc = hdc; /* store format in private DC data */
OPENGL32_processdata.cachedFormat = iFormat; dcdata = ROSGL_GetPrivateDCData( hdc );
OPENGL32_UnloadICD( icd ); if (dcdata == NULL)
{
DBGPRINT( "Error: ROSGL_GetPrivateDCData() failed!" );
return FALSE;
}
dcdata->pixel_format = iFormat;
return TRUE; return TRUE;
} }
@ -749,7 +880,7 @@ rosglSetPixelFormat( HDC hdc, int iFormat, CONST PIXELFORMATDESCRIPTOR *pfd )
/* FUNCTION: Enable display-list sharing between multiple GLRCs /* FUNCTION: Enable display-list sharing between multiple GLRCs
* ARGUMENTS: [IN] hglrc1 GLRC number 1 * ARGUMENTS: [IN] hglrc1 GLRC number 1
* [IN] hglrc2 GLRC number 2 * [IN] hglrc2 GLRC number 2
* RETURNS: TRUR on success, FALSE on failure * RETURNS: TRUE on success, FALSE on failure
*/ */
BOOL BOOL
APIENTRY APIENTRY
@ -759,12 +890,12 @@ rosglShareLists( HGLRC hglrc1, HGLRC hglrc2 )
GLRC *glrc2 = (GLRC *)hglrc2; GLRC *glrc2 = (GLRC *)hglrc2;
/* check glrcs */ /* check glrcs */
if (!WGL_ContainsContext( glrc1 )) if (!ROSGL_ContainsContext( glrc1 ))
{ {
DBGPRINT( "Error: hglrc1 not found!" ); DBGPRINT( "Error: hglrc1 not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
} }
if (!WGL_ContainsContext( glrc2 )) if (!ROSGL_ContainsContext( glrc2 ))
{ {
DBGPRINT( "Error: hglrc2 not found!" ); DBGPRINT( "Error: hglrc2 not found!" );
return FALSE; /* FIXME: SetLastError() */ return FALSE; /* FIXME: SetLastError() */
@ -790,16 +921,14 @@ BOOL
APIENTRY APIENTRY
rosglSwapBuffers( HDC hdc ) rosglSwapBuffers( HDC hdc )
{ {
GLDRIVERDATA *icd = OPENGL32_LoadICDForHDC( hdc ); GLDRIVERDATA *icd = ROSGL_ICDForHDC( hdc );
if (icd != NULL) if (icd != NULL)
{ {
if (!icd->DrvSwapBuffers( hdc )) if (!icd->DrvSwapBuffers( hdc ))
{ {
DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() ); DBGPRINT( "Error: DrvSwapBuffers failed (%d)", GetLastError() );
OPENGL32_UnloadICD( icd );
return FALSE; return FALSE;
} }
OPENGL32_UnloadICD( icd );
return TRUE; return TRUE;
} }
@ -838,8 +967,8 @@ rosglUseFontBitmapsW( HDC hdc, DWORD first, DWORD count, DWORD listBase )
BOOL BOOL
APIENTRY APIENTRY
rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase, rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
FLOAT deviation, FLOAT extrusion, int format, FLOAT deviation, FLOAT extrusion, int format,
LPGLYPHMETRICSFLOAT lpgmf ) GLYPHMETRICSFLOAT *pgmf )
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return FALSE; return FALSE;
@ -849,8 +978,8 @@ rosglUseFontOutlinesA( HDC hdc, DWORD first, DWORD count, DWORD listBase,
BOOL BOOL
APIENTRY APIENTRY
rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase, rosglUseFontOutlinesW( HDC hdc, DWORD first, DWORD count, DWORD listBase,
FLOAT deviation, FLOAT extrusion, int format, FLOAT deviation, FLOAT extrusion, int format,
LPGLYPHMETRICSFLOAT lpgmf ) GLYPHMETRICSFLOAT *pgmf )
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
return FALSE; return FALSE;