Alexandre Julliard : opengl32: Add a mechanism for managing different types of OpenGL handles.

Alexandre Julliard julliard at winehq.org
Fri Jul 20 15:29:58 CDT 2012


Module: wine
Branch: master
Commit: 98bd066c952c4d54a44c6da18521a0b6363f4a81
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=98bd066c952c4d54a44c6da18521a0b6363f4a81

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Jul 20 12:27:19 2012 +0200

opengl32: Add a mechanism for managing different types of OpenGL handles.

---

 dlls/opengl32/wgl.c |   80 ++++++++++++++++++++++++++++----------------------
 1 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c
index 85eaf22..b06847c 100644
--- a/dlls/opengl32/wgl.c
+++ b/dlls/opengl32/wgl.c
@@ -78,12 +78,22 @@ extern BOOL WINAPI GdiSwapBuffers( HDC hdc );
 
 #define MAX_WGL_HANDLES 1024
 
+enum wgl_handle_type
+{
+    HANDLE_CONTEXT = 0 << 12,
+    HANDLE_TYPE_MASK = 15 << 12
+};
+
 struct wgl_handle
 {
     UINT                 handle;
     DWORD                tid;
-    struct wgl_context  *context;
     struct opengl_funcs *funcs;
+    union
+    {
+        struct wgl_context *context;  /* for HANDLE_CONTEXT */
+        struct wgl_handle  *next;     /* for free handles */
+    } u;
 };
 
 static struct wgl_handle wgl_handles[MAX_WGL_HANDLES];
@@ -106,24 +116,24 @@ static inline struct opengl_funcs *get_dc_funcs( HDC hdc )
     return funcs;
 }
 
-static inline HGLRC next_handle( struct wgl_handle *ptr )
+static inline HANDLE next_handle( struct wgl_handle *ptr, enum wgl_handle_type type )
 {
     WORD generation = HIWORD( ptr->handle ) + 1;
     if (!generation) generation++;
-    ptr->handle = MAKELONG( ptr - wgl_handles, generation );
+    ptr->handle = MAKELONG( ptr - wgl_handles, generation ) | type;
     return ULongToHandle( ptr->handle );
 }
 
-/* the current handle is assumed valid and doesn't need locking */
-static inline struct wgl_handle *get_current_handle_ptr(void)
+/* the current context is assumed valid and doesn't need locking */
+static inline struct wgl_handle *get_current_context_ptr(void)
 {
     if (!NtCurrentTeb()->glCurrentRC) return NULL;
-    return &wgl_handles[LOWORD(NtCurrentTeb()->glCurrentRC)];
+    return &wgl_handles[LOWORD(NtCurrentTeb()->glCurrentRC) & ~HANDLE_TYPE_MASK];
 }
 
-static struct wgl_handle *get_handle_ptr( HGLRC handle )
+static struct wgl_handle *get_handle_ptr( HANDLE handle, enum wgl_handle_type type )
 {
-    unsigned int index = LOWORD( handle );
+    unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK;
 
     EnterCriticalSection( &wgl_section );
     if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle)
@@ -139,22 +149,22 @@ static void release_handle_ptr( struct wgl_handle *ptr )
     if (ptr) LeaveCriticalSection( &wgl_section );
 }
 
-static HGLRC alloc_handle( struct wgl_context *context, struct opengl_funcs *funcs )
+static HANDLE alloc_handle( enum wgl_handle_type type, struct opengl_funcs *funcs, void *user_ptr )
 {
-    HGLRC handle = 0;
+    HANDLE handle = 0;
     struct wgl_handle *ptr = NULL;
 
     EnterCriticalSection( &wgl_section );
     if ((ptr = next_free))
-        next_free = (struct wgl_handle *)next_free->context;
+        next_free = next_free->u.next;
     else if (handle_count < MAX_WGL_HANDLES)
         ptr = &wgl_handles[handle_count++];
 
     if (ptr)
     {
-        ptr->context = context;
         ptr->funcs = funcs;
-        handle = next_handle( ptr );
+        ptr->u.context = user_ptr;
+        handle = next_handle( ptr, type );
     }
     else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
     LeaveCriticalSection( &wgl_section );
@@ -164,7 +174,7 @@ static HGLRC alloc_handle( struct wgl_context *context, struct opengl_funcs *fun
 static void free_handle_ptr( struct wgl_handle *ptr )
 {
     ptr->handle |= 0xffff;
-    ptr->context = (struct wgl_context *)next_free;
+    ptr->u.next = next_free;
     ptr->funcs = NULL;
     next_free = ptr;
     LeaveCriticalSection( &wgl_section );
@@ -187,11 +197,11 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
     struct wgl_handle *src, *dst;
     BOOL ret = FALSE;
 
-    if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
-    if ((dst = get_handle_ptr( hglrcDst )))
+    if (!(src = get_handle_ptr( hglrcSrc, HANDLE_CONTEXT ))) return FALSE;
+    if ((dst = get_handle_ptr( hglrcDst, HANDLE_CONTEXT )))
     {
         if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE );
-        else ret = src->funcs->wgl.p_wglCopyContext( src->context, dst->context, mask );
+        else ret = src->funcs->wgl.p_wglCopyContext( src->u.context, dst->u.context, mask );
     }
     release_handle_ptr( dst );
     release_handle_ptr( src );
@@ -203,7 +213,7 @@ BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
  */
 BOOL WINAPI wglDeleteContext(HGLRC hglrc)
 {
-    struct wgl_handle *ptr = get_handle_ptr( hglrc );
+    struct wgl_handle *ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT );
 
     if (!ptr) return FALSE;
 
@@ -214,7 +224,7 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
         return FALSE;
     }
     if (hglrc == NtCurrentTeb()->glCurrentRC) wglMakeCurrent( 0, 0 );
-    ptr->funcs->wgl.p_wglDeleteContext( ptr->context );
+    ptr->funcs->wgl.p_wglDeleteContext( ptr->u.context );
     free_handle_ptr( ptr );
     return TRUE;
 }
@@ -225,14 +235,14 @@ BOOL WINAPI wglDeleteContext(HGLRC hglrc)
 BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc)
 {
     BOOL ret = TRUE;
-    struct wgl_handle *ptr, *prev = get_current_handle_ptr();
+    struct wgl_handle *ptr, *prev = get_current_context_ptr();
 
     if (hglrc)
     {
-        if (!(ptr = get_handle_ptr( hglrc ))) return FALSE;
+        if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE;
         if (!ptr->tid || ptr->tid == GetCurrentThreadId())
         {
-            ret = ptr->funcs->wgl.p_wglMakeCurrent( hdc, ptr->context );
+            ret = ptr->funcs->wgl.p_wglMakeCurrent( hdc, ptr->u.context );
             if (ret)
             {
                 if (prev) prev->tid = 0;
@@ -276,11 +286,11 @@ HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attrib
     struct opengl_funcs *funcs = get_dc_funcs( hdc );
 
     if (!funcs || !funcs->ext.p_wglCreateContextAttribsARB) return 0;
-    if (share && !(share_ptr = get_handle_ptr( share ))) return 0;
-    if ((context = funcs->ext.p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->context : NULL,
+    if (share && !(share_ptr = get_handle_ptr( share, HANDLE_CONTEXT ))) return 0;
+    if ((context = funcs->ext.p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->u.context : NULL,
                                                             attribs )))
     {
-        ret = alloc_handle( context, funcs );
+        ret = alloc_handle( HANDLE_CONTEXT, funcs, context );
         if (!ret) funcs->wgl.p_wglDeleteContext( context );
     }
     release_handle_ptr( share_ptr );
@@ -296,15 +306,15 @@ HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attrib
 BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc )
 {
     BOOL ret = TRUE;
-    struct wgl_handle *ptr, *prev = get_current_handle_ptr();
+    struct wgl_handle *ptr, *prev = get_current_context_ptr();
 
     if (hglrc)
     {
-        if (!(ptr = get_handle_ptr( hglrc ))) return FALSE;
+        if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE;
         if (!ptr->tid || ptr->tid == GetCurrentThreadId())
         {
             ret = (ptr->funcs->ext.p_wglMakeContextCurrentARB &&
-                   ptr->funcs->ext.p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->context ));
+                   ptr->funcs->ext.p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->u.context ));
             if (ret)
             {
                 if (prev) prev->tid = 0;
@@ -351,11 +361,11 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
     BOOL ret = FALSE;
     struct wgl_handle *src, *dst;
 
-    if (!(src = get_handle_ptr( hglrcSrc ))) return FALSE;
-    if ((dst = get_handle_ptr( hglrcDst )))
+    if (!(src = get_handle_ptr( hglrcSrc, HANDLE_CONTEXT ))) return FALSE;
+    if ((dst = get_handle_ptr( hglrcDst, HANDLE_CONTEXT )))
     {
         if (src->funcs != dst->funcs) SetLastError( ERROR_INVALID_HANDLE );
-        else ret = src->funcs->wgl.p_wglShareLists( src->context, dst->context );
+        else ret = src->funcs->wgl.p_wglShareLists( src->u.context, dst->u.context );
     }
     release_handle_ptr( dst );
     release_handle_ptr( src );
@@ -367,9 +377,9 @@ BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst)
  */
 HDC WINAPI wglGetCurrentDC(void)
 {
-    struct wgl_handle *context = get_current_handle_ptr();
+    struct wgl_handle *context = get_current_context_ptr();
     if (!context) return 0;
-    return context->funcs->wgl.p_wglGetCurrentDC( context->context );
+    return context->funcs->wgl.p_wglGetCurrentDC( context->u.context );
 }
 
 /***********************************************************************
@@ -383,7 +393,7 @@ HGLRC WINAPI wglCreateContext(HDC hdc)
 
     if (!funcs) return 0;
     if (!(context = funcs->wgl.p_wglCreateContext( hdc ))) return 0;
-    ret = alloc_handle( context, funcs );
+    ret = alloc_handle( HANDLE_CONTEXT, funcs, context );
     if (!ret) funcs->wgl.p_wglDeleteContext( context );
     return ret;
 }
@@ -696,7 +706,7 @@ PROC WINAPI wglGetProcAddress(LPCSTR lpszProc)
   void *local_func;
   OpenGL_extension  ext;
   const OpenGL_extension *ext_ret;
-  struct wgl_handle *context = get_current_handle_ptr();
+  struct wgl_handle *context = get_current_context_ptr();
 
   TRACE("(%s)\n", lpszProc);
 




More information about the wine-cvs mailing list