#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));
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;
-}
\ No newline at end of file
+}
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)
{
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);
FreeLibrary(data->hModule);
HeapFree(GetProcessHeap(), 0, data);
return NULL;
-}
\ No newline at end of file
+}
+
+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);
+ }
+}
#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;
struct wgl_dc_data* next;
};
+/* Clean up functions */
+void IntDeleteAllContexts(void);
+void IntDeleteAllICDs(void);
+
#ifdef OPENGL32_USE_TLS
extern DWORD OglTlsIndex;
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*
/* 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;
}
if (!count) return 0;
best_format = 0;
- best.dwFlags = 0;
+ best.dwFlags = PFD_GENERIC_FORMAT;
best.cAlphaBits = -1;
best.cColorBits = -1;
best.cDepthBits = -1;
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;
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;
sw_DeleteContext(context->dhglrc);
context->magic = 0;
+ RemoveEntryList(&context->ListEntry);
HeapFree(GetProcessHeap(), 0, context);
return TRUE;
{
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;
+ }
+}