mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +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
4 changed files with 133 additions and 17 deletions
|
@ -19,16 +19,15 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
|
|||
#endif
|
||||
switch ( Reason )
|
||||
{
|
||||
/* The DLL is loading due to process
|
||||
* initialization or a call to LoadLibrary.
|
||||
*/
|
||||
case DLL_PROCESS_ATTACH:
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
OglTlsIndex = TlsAlloc();
|
||||
if(OglTlsIndex == TLS_OUT_OF_INDEXES)
|
||||
return FALSE;
|
||||
#endif
|
||||
/* Fall through */
|
||||
/* Initialize Context list */
|
||||
InitializeListHead(&ContextListHead);
|
||||
/* no break */
|
||||
case DLL_THREAD_ATTACH:
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
ThreadData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ThreadData));
|
||||
|
@ -45,28 +44,36 @@ DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
|
|||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
/* Set NULL context for this thread */
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
/* Clean up */
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
ThreadData = TlsGetValue(OglTlsIndex);
|
||||
if(ThreadData)
|
||||
HeapFree(GetProcessHeap(), 0, ThreadData);
|
||||
#else
|
||||
NtCurrentTeb->glTable = NULL;
|
||||
NtCurrentTeb()->glTable = NULL;
|
||||
#endif // defined(OPENGL32_USE_TLS)
|
||||
break;
|
||||
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
/* Clean up */
|
||||
if (!Reserved)
|
||||
{
|
||||
/* The process is not shutting down: release everything */
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
IntDeleteAllContexts();
|
||||
IntDeleteAllICDs();
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
ThreadData = TlsGetValue(OglTlsIndex);
|
||||
if(ThreadData)
|
||||
HeapFree(GetProcessHeap(), 0, ThreadData);
|
||||
#endif
|
||||
}
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
ThreadData = TlsGetValue(OglTlsIndex);
|
||||
if(ThreadData)
|
||||
HeapFree(GetProcessHeap(), 0, ThreadData);
|
||||
TlsFree(OglTlsIndex);
|
||||
#else
|
||||
NtCurrentTeb->glTable = NULL;
|
||||
#endif // defined(OPENGL32_USE_TLS)
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,11 @@ static DHGLRC wglGetDHGLRC(struct wgl_context* context)
|
|||
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 */
|
||||
struct ICD_Data* IntGetIcdData(HDC hdc)
|
||||
{
|
||||
|
@ -245,6 +250,17 @@ struct ICD_Data* IntGetIcdData(HDC hdc)
|
|||
DRV_LOAD(DrvSwapLayerBuffers);
|
||||
#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 */
|
||||
wcscpy(data->DriverName, DrvInfo.DriverName);
|
||||
|
||||
|
@ -264,4 +280,20 @@ fail:
|
|||
FreeLibrary(data->hModule);
|
||||
HeapFree(GetProcessHeap(), 0, data);
|
||||
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"
|
||||
|
||||
/* *$%$£^§! 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
|
||||
{
|
||||
DWORD magic;
|
||||
volatile LONG lock;
|
||||
|
||||
LIST_ENTRY ListEntry;
|
||||
|
||||
DHGLRC dhglrc;
|
||||
struct ICD_Data* icd_data;
|
||||
INT pixelformat;
|
||||
|
@ -59,6 +104,10 @@ struct wgl_dc_data
|
|||
struct wgl_dc_data* next;
|
||||
};
|
||||
|
||||
/* Clean up functions */
|
||||
void IntDeleteAllContexts(void);
|
||||
void IntDeleteAllICDs(void);
|
||||
|
||||
#ifdef OPENGL32_USE_TLS
|
||||
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 struct wgl_dc_data* dc_data_list = NULL;
|
||||
|
||||
LIST_ENTRY ContextListHead;
|
||||
|
||||
/* FIXME: suboptimal */
|
||||
static
|
||||
struct wgl_dc_data*
|
||||
|
@ -139,7 +141,11 @@ INT WINAPI wglDescribePixelFormat(HDC hdc, INT format, UINT size, PIXELFORMATDES
|
|||
/* Query ICD if needed */
|
||||
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;
|
||||
}
|
||||
|
@ -174,7 +180,7 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
|
|||
if (!count) return 0;
|
||||
|
||||
best_format = 0;
|
||||
best.dwFlags = 0;
|
||||
best.dwFlags = PFD_GENERIC_FORMAT;
|
||||
best.cAlphaBits = -1;
|
||||
best.cColorBits = -1;
|
||||
best.cDepthBits = -1;
|
||||
|
@ -329,6 +335,9 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
|
|||
continue;
|
||||
|
||||
found:
|
||||
/* Prefer HW accelerated formats */
|
||||
if ((format.dwFlags & PFD_GENERIC_FORMAT) && !(best.dwFlags & PFD_GENERIC_FORMAT))
|
||||
continue;
|
||||
best_format = i;
|
||||
best = format;
|
||||
bestDBuffer = format.dwFlags & PFD_DOUBLEBUFFER;
|
||||
|
@ -422,6 +431,9 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
|
|||
context->pixelformat = dc_data->pixelformat;
|
||||
context->thread_id = 0;
|
||||
|
||||
/* Insert into the list */
|
||||
InsertTailList(&ContextListHead, &context->ListEntry);
|
||||
|
||||
context->magic = 'GLRC';
|
||||
TRACE("Success!\n");
|
||||
return (HGLRC)context;
|
||||
|
@ -525,6 +537,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
|
|||
sw_DeleteContext(context->dhglrc);
|
||||
|
||||
context->magic = 0;
|
||||
RemoveEntryList(&context->ListEntry);
|
||||
HeapFree(GetProcessHeap(), 0, context);
|
||||
|
||||
return TRUE;
|
||||
|
@ -902,3 +915,18 @@ DWORD WINAPI wglSwapMultipleBuffers(UINT count, CONST WGLSWAP * toSwap)
|
|||
{
|
||||
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