mirror of
https://github.com/reactos/reactos.git
synced 2024-07-05 12:15:46 +00:00
[OPENGL32]
- Free resources when unloading the DLL - avoid potential crash in wglDescribePixelFormat - Prefer HW accelerated pixel formats in wglChoosePixelFormat - Try forwarding ICD functions to win32k when relevant (untested!) svn path=/trunk/; revision=63747
This commit is contained in:
parent
84fa6f66f3
commit
b6f852e3a4
|
@ -19,16 +19,15 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
|
||||||
#endif
|
#endif
|
||||||
switch ( Reason )
|
switch ( Reason )
|
||||||
{
|
{
|
||||||
/* The DLL is loading due to process
|
|
||||||
* initialization or a call to LoadLibrary.
|
|
||||||
*/
|
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
#ifdef OPENGL32_USE_TLS
|
#ifdef OPENGL32_USE_TLS
|
||||||
OglTlsIndex = TlsAlloc();
|
OglTlsIndex = TlsAlloc();
|
||||||
if(OglTlsIndex == TLS_OUT_OF_INDEXES)
|
if(OglTlsIndex == TLS_OUT_OF_INDEXES)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
/* Fall through */
|
/* Initialize Context list */
|
||||||
|
InitializeListHead(&ContextListHead);
|
||||||
|
/* no break */
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
#ifdef OPENGL32_USE_TLS
|
#ifdef OPENGL32_USE_TLS
|
||||||
ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ThreadData));
|
ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ThreadData));
|
||||||
|
@ -45,26 +44,34 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
|
/* Set NULL context for this thread */
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
#ifdef OPENGL32_USE_TLS
|
#ifdef OPENGL32_USE_TLS
|
||||||
ThreadData = TlsGetValue(OglTlsIndex);
|
ThreadData = TlsGetValue(OglTlsIndex);
|
||||||
if(ThreadData)
|
if(ThreadData)
|
||||||
HeapFree(GetProcessHeap(), 0, ThreadData);
|
HeapFree(GetProcessHeap(), 0, ThreadData);
|
||||||
#else
|
#else
|
||||||
NtCurrentTeb->glTable = NULL;
|
NtCurrentTeb()->glTable = NULL;
|
||||||
#endif // defined(OPENGL32_USE_TLS)
|
#endif // defined(OPENGL32_USE_TLS)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
|
if (!Reserved)
|
||||||
|
{
|
||||||
|
/* The process is not shutting down: release everything */
|
||||||
|
wglMakeCurrent(NULL, NULL);
|
||||||
|
IntDeleteAllContexts();
|
||||||
|
IntDeleteAllICDs();
|
||||||
#ifdef OPENGL32_USE_TLS
|
#ifdef OPENGL32_USE_TLS
|
||||||
ThreadData = TlsGetValue(OglTlsIndex);
|
ThreadData = TlsGetValue(OglTlsIndex);
|
||||||
if(ThreadData)
|
if(ThreadData)
|
||||||
HeapFree(GetProcessHeap(), 0, ThreadData);
|
HeapFree(GetProcessHeap(), 0, ThreadData);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef OPENGL32_USE_TLS
|
||||||
TlsFree(OglTlsIndex);
|
TlsFree(OglTlsIndex);
|
||||||
#else
|
#endif
|
||||||
NtCurrentTeb->glTable = NULL;
|
|
||||||
#endif // defined(OPENGL32_USE_TLS)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,11 @@ static DHGLRC wglGetDHGLRC(struct wgl_context* context)
|
||||||
return context->dhglrc;
|
return context->dhglrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* GDI entry points (win32k) */
|
||||||
|
extern INT APIENTRY GdiDescribePixelFormat(HDC hdc, INT ipfd, UINT cjpfd, PPIXELFORMATDESCRIPTOR ppfd);
|
||||||
|
extern BOOL APIENTRY GdiSetPixelFormat(HDC hdc, INT ipfd);
|
||||||
|
extern BOOL APIENTRY GdiSwapBuffers(HDC hdc);
|
||||||
|
|
||||||
/* Retrieves the ICD data (driver version + relevant DLL entry points) for a device context */
|
/* Retrieves the ICD data (driver version + relevant DLL entry points) for a device context */
|
||||||
struct ICD_Data* IntGetIcdData(HDC hdc)
|
struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
{
|
{
|
||||||
|
@ -245,6 +250,17 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||||
DRV_LOAD(DrvSwapLayerBuffers);
|
DRV_LOAD(DrvSwapLayerBuffers);
|
||||||
#undef DRV_LOAD
|
#undef DRV_LOAD
|
||||||
|
|
||||||
|
/* Let's see if GDI should handle this instead of the ICD DLL */
|
||||||
|
// FIXME: maybe there is a better way
|
||||||
|
if (GdiDescribePixelFormat(hdc, 0, 0, NULL) != 0)
|
||||||
|
{
|
||||||
|
/* GDI knows what to do with that. Override */
|
||||||
|
TRACE("Forwarding WGL calls to win32k!\n");
|
||||||
|
data->DrvDescribePixelFormat = GdiDescribePixelFormat;
|
||||||
|
data->DrvSetPixelFormat = GdiSetPixelFormat;
|
||||||
|
data->DrvSwapBuffers = GdiSwapBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy the DriverName */
|
/* Copy the DriverName */
|
||||||
wcscpy(data->DriverName, DrvInfo.DriverName);
|
wcscpy(data->DriverName, DrvInfo.DriverName);
|
||||||
|
|
||||||
|
@ -265,3 +281,19 @@ fail:
|
||||||
HeapFree(GetProcessHeap(), 0, data);
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IntDeleteAllICDs(void)
|
||||||
|
{
|
||||||
|
struct ICD_Data* data;
|
||||||
|
|
||||||
|
EnterCriticalSection(&icdload_cs);
|
||||||
|
|
||||||
|
while (ICD_Data_List != NULL)
|
||||||
|
{
|
||||||
|
data = ICD_Data_List;
|
||||||
|
ICD_Data_List = data->next;
|
||||||
|
|
||||||
|
FreeLibrary(data->hModule);
|
||||||
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,11 +21,56 @@
|
||||||
|
|
||||||
#include "icd.h"
|
#include "icd.h"
|
||||||
|
|
||||||
|
/* *$%$£^§! headers inclusion */
|
||||||
|
static __inline
|
||||||
|
BOOLEAN
|
||||||
|
RemoveEntryList(
|
||||||
|
_In_ PLIST_ENTRY Entry)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY OldFlink;
|
||||||
|
PLIST_ENTRY OldBlink;
|
||||||
|
|
||||||
|
OldFlink = Entry->Flink;
|
||||||
|
OldBlink = Entry->Blink;
|
||||||
|
OldFlink->Blink = OldBlink;
|
||||||
|
OldBlink->Flink = OldFlink;
|
||||||
|
return (OldFlink == OldBlink);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline
|
||||||
|
VOID
|
||||||
|
InsertTailList(
|
||||||
|
_In_ PLIST_ENTRY ListHead,
|
||||||
|
_In_ PLIST_ENTRY Entry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY OldBlink;
|
||||||
|
OldBlink = ListHead->Blink;
|
||||||
|
Entry->Flink = ListHead;
|
||||||
|
Entry->Blink = OldBlink;
|
||||||
|
OldBlink->Flink = Entry;
|
||||||
|
ListHead->Blink = Entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __inline
|
||||||
|
VOID
|
||||||
|
InitializeListHead(
|
||||||
|
_Inout_ PLIST_ENTRY ListHead
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ListHead->Flink = ListHead->Blink = ListHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern LIST_ENTRY ContextListHead;
|
||||||
|
|
||||||
struct wgl_context
|
struct wgl_context
|
||||||
{
|
{
|
||||||
DWORD magic;
|
DWORD magic;
|
||||||
volatile LONG lock;
|
volatile LONG lock;
|
||||||
|
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
DHGLRC dhglrc;
|
DHGLRC dhglrc;
|
||||||
struct ICD_Data* icd_data;
|
struct ICD_Data* icd_data;
|
||||||
INT pixelformat;
|
INT pixelformat;
|
||||||
|
@ -59,6 +104,10 @@ struct wgl_dc_data
|
||||||
struct wgl_dc_data* next;
|
struct wgl_dc_data* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Clean up functions */
|
||||||
|
void IntDeleteAllContexts(void);
|
||||||
|
void IntDeleteAllICDs(void);
|
||||||
|
|
||||||
#ifdef OPENGL32_USE_TLS
|
#ifdef OPENGL32_USE_TLS
|
||||||
extern DWORD OglTlsIndex;
|
extern DWORD OglTlsIndex;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl);
|
||||||
static CRITICAL_SECTION dc_data_cs = {NULL, -1, 0, 0, 0, 0};
|
static CRITICAL_SECTION dc_data_cs = {NULL, -1, 0, 0, 0, 0};
|
||||||
static struct wgl_dc_data* dc_data_list = NULL;
|
static struct wgl_dc_data* dc_data_list = NULL;
|
||||||
|
|
||||||
|
LIST_ENTRY ContextListHead;
|
||||||
|
|
||||||
/* FIXME: suboptimal */
|
/* FIXME: suboptimal */
|
||||||
static
|
static
|
||||||
struct wgl_dc_data*
|
struct wgl_dc_data*
|
||||||
|
@ -139,7 +141,11 @@ INT WINAPI wglDescribePixelFormat(HDC hdc, INT format, UINT size, PIXELFORMATDES
|
||||||
/* Query ICD if needed */
|
/* Query ICD if needed */
|
||||||
if(format <= dc_data->nb_icd_formats)
|
if(format <= dc_data->nb_icd_formats)
|
||||||
{
|
{
|
||||||
if(!dc_data->icd_data->DrvDescribePixelFormat(hdc, format, size, descr))
|
struct ICD_Data* icd_data = dc_data->icd_data;
|
||||||
|
/* SetPixelFormat may have NULLified this */
|
||||||
|
if (!icd_data)
|
||||||
|
icd_data = IntGetIcdData(hdc);
|
||||||
|
if(!icd_data->DrvDescribePixelFormat(hdc, format, size, descr))
|
||||||
{
|
{
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +180,7 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
|
||||||
if (!count) return 0;
|
if (!count) return 0;
|
||||||
|
|
||||||
best_format = 0;
|
best_format = 0;
|
||||||
best.dwFlags = 0;
|
best.dwFlags = PFD_GENERIC_FORMAT;
|
||||||
best.cAlphaBits = -1;
|
best.cAlphaBits = -1;
|
||||||
best.cColorBits = -1;
|
best.cColorBits = -1;
|
||||||
best.cDepthBits = -1;
|
best.cDepthBits = -1;
|
||||||
|
@ -329,6 +335,9 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
found:
|
found:
|
||||||
|
/* Prefer HW accelerated formats */
|
||||||
|
if ((format.dwFlags & PFD_GENERIC_FORMAT) && !(best.dwFlags & PFD_GENERIC_FORMAT))
|
||||||
|
continue;
|
||||||
best_format = i;
|
best_format = i;
|
||||||
best = format;
|
best = format;
|
||||||
bestDBuffer = format.dwFlags & PFD_DOUBLEBUFFER;
|
bestDBuffer = format.dwFlags & PFD_DOUBLEBUFFER;
|
||||||
|
@ -422,6 +431,9 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
|
||||||
context->pixelformat = dc_data->pixelformat;
|
context->pixelformat = dc_data->pixelformat;
|
||||||
context->thread_id = 0;
|
context->thread_id = 0;
|
||||||
|
|
||||||
|
/* Insert into the list */
|
||||||
|
InsertTailList(&ContextListHead, &context->ListEntry);
|
||||||
|
|
||||||
context->magic = 'GLRC';
|
context->magic = 'GLRC';
|
||||||
TRACE("Success!\n");
|
TRACE("Success!\n");
|
||||||
return (HGLRC)context;
|
return (HGLRC)context;
|
||||||
|
@ -525,6 +537,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
|
||||||
sw_DeleteContext(context->dhglrc);
|
sw_DeleteContext(context->dhglrc);
|
||||||
|
|
||||||
context->magic = 0;
|
context->magic = 0;
|
||||||
|
RemoveEntryList(&context->ListEntry);
|
||||||
HeapFree(GetProcessHeap(), 0, context);
|
HeapFree(GetProcessHeap(), 0, context);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -902,3 +915,18 @@ DWORD WINAPI wglSwapMultipleBuffers(UINT count, CONST WGLSWAP * toSwap)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clean up on DLL unload */
|
||||||
|
void
|
||||||
|
IntDeleteAllContexts(void)
|
||||||
|
{
|
||||||
|
struct wgl_context* context;
|
||||||
|
LIST_ENTRY* Entry = ContextListHead.Flink;
|
||||||
|
|
||||||
|
while (Entry != &ContextListHead)
|
||||||
|
{
|
||||||
|
context = CONTAINING_RECORD(Entry, struct wgl_context, ListEntry);
|
||||||
|
wglDeleteContext((HGLRC)context);
|
||||||
|
Entry = ContextListHead.Flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue