Author: jgardou
Date: Mon Jul 28 13:03:10 2014
New Revision: 63747

URL: http://svn.reactos.org/svn/reactos?rev=63747&view=rev
Log:
[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!)

Modified:
    trunk/reactos/dll/opengl/opengl32/dllmain.c
    trunk/reactos/dll/opengl/opengl32/icdload.c
    trunk/reactos/dll/opengl/opengl32/opengl32.h
    trunk/reactos/dll/opengl/opengl32/wgl.c

Modified: trunk/reactos/dll/opengl/opengl32/dllmain.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/dllmain.c?rev=63747&r1=63746&r2=63747&view=diff
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/dllmain.c [iso-8859-1] Mon Jul 28 
13:03:10 2014
@@ -19,16 +19,15 @@
 #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 @@
             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);
+                ThreadData = TlsGetValue(OglTlsIndex);
+                if(ThreadData)
+                    HeapFree(GetProcessHeap(), 0, ThreadData);
+#endif
+            }
+#ifdef OPENGL32_USE_TLS
             TlsFree(OglTlsIndex);
-#else
-            NtCurrentTeb->glTable = NULL;
-#endif // defined(OPENGL32_USE_TLS)
+#endif
             break;
     }
 
     return TRUE;
-}
+}

Modified: trunk/reactos/dll/opengl/opengl32/icdload.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/icdload.c?rev=63747&r1=63746&r2=63747&view=diff
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/icdload.c [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/icdload.c [iso-8859-1] Mon Jul 28 
13:03:10 2014
@@ -36,6 +36,11 @@
 {
     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 @@
     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 @@
     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);
+    }
+}

Modified: trunk/reactos/dll/opengl/opengl32/opengl32.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/opengl32.h?rev=63747&r1=63746&r2=63747&view=diff
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/opengl32.h        [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/opengl32.h        [iso-8859-1] Mon Jul 28 
13:03:10 2014
@@ -21,10 +21,55 @@
 
 #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;
@@ -58,6 +103,10 @@
     /* Linked list */
     struct wgl_dc_data* next;
 };
+
+/* Clean up functions */
+void IntDeleteAllContexts(void);
+void IntDeleteAllICDs(void);
 
 #ifdef OPENGL32_USE_TLS
 extern DWORD OglTlsIndex;

Modified: trunk/reactos/dll/opengl/opengl32/wgl.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/opengl32/wgl.c?rev=63747&r1=63746&r2=63747&view=diff
==============================================================================
--- trunk/reactos/dll/opengl/opengl32/wgl.c     [iso-8859-1] (original)
+++ trunk/reactos/dll/opengl/opengl32/wgl.c     [iso-8859-1] Mon Jul 28 
13:03:10 2014
@@ -13,6 +13,8 @@
 
 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
@@ -139,7 +141,11 @@
     /* 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 @@
     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 @@
         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 @@
     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 @@
         sw_DeleteContext(context->dhglrc);
     
     context->magic = 0;
+    RemoveEntryList(&context->ListEntry);
     HeapFree(GetProcessHeap(), 0, context);
     
     return TRUE;
@@ -902,3 +915,18 @@
 {
     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;
+    }
+}


Reply via email to