From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/Makefile.in | 4 +- dlls/opengl32/make_opengl | 16 +++-- dlls/opengl32/unix_thunks.c | 8 ++- dlls/opengl32/unix_wgl.c | 130 +++++++++++++++++------------------- dlls/opengl32/unixlib.h | 6 +- dlls/opengl32/wgl.c | 22 ++++-- 6 files changed, 101 insertions(+), 85 deletions(-)
diff --git a/dlls/opengl32/Makefile.in b/dlls/opengl32/Makefile.in index 16f5ab17120..bd7ddd8d56f 100644 --- a/dlls/opengl32/Makefile.in +++ b/dlls/opengl32/Makefile.in @@ -1,10 +1,12 @@ MODULE = opengl32.dll +UNIXLIB = opengl32.so EXTRADEFS = -DWINE_NO_LONG_TYPES -D_OPENGL32_ IMPORTLIB = opengl32 IMPORTS = user32 gdi32 advapi32 win32u DELAYIMPORTS = glu32 +UNIX_LIBS = -lwin32u
-EXTRADLLFLAGS = -Wl,--image-base,0x7a800000 -mcygwin +EXTRADLLFLAGS = -Wl,--image-base,0x7a800000
C_SRCS = \ thunks.c \ diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 3b67d3d9f61..ad9def8dcec 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -815,6 +815,7 @@ foreach (sort keys %ext_functions)
print OUT "enum unix_funcs\n"; print OUT "{\n"; +print OUT " unix_thread_attach,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -846,11 +847,10 @@ print OUT " GLsizei length;\n"; print OUT " const GLchar *message;\n"; print OUT "};\n\n";
-print OUT "typedef NTSTATUS (*unixlib_function_t)( void *args );\n"; -print OUT "extern const unixlib_function_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN;\n"; -print OUT "#define UNIX_CALL( func, params ) __wine_unix_call_funcs[unix_ ## func]( params )\n"; +print OUT "extern unixlib_handle_t unixlib_handle DECLSPEC_HIDDEN;\n"; +print OUT "#define UNIX_CALL( func, params ) __wine_unix_call( unixlib_handle, unix_ ## func, params )\n\n";
-print OUT "\n#endif /* __WINE_OPENGL32_UNIXLIB_H */\n"; +print OUT "#endif /* __WINE_OPENGL32_UNIXLIB_H */\n"; close OUT;
# @@ -917,6 +917,10 @@ close OUT; open OUT, ">unix_thunks.c" or die "cannot create unix_thunks.c"; print OUT "/* Automatically generated from http://www.opengl.org/registry files; DO NOT EDIT! */\n\n";
+print OUT "#if 0\n"; +print OUT "#pragma makedep unix\n"; +print OUT "#endif\n\n"; + print OUT "#include <stdarg.h>\n"; print OUT "#include <stddef.h>\n\n";
@@ -929,6 +933,7 @@ print OUT "#include "wingdi.h"\n\n"; print OUT "#include "unixlib.h"\n"; print OUT "#include "unix_private.h"\n\n";
+print OUT "extern NTSTATUS thread_attach( void *args ) DECLSPEC_HIDDEN;\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -968,8 +973,9 @@ foreach (sort keys %ext_functions) print OUT generate_unix_thunk($_, $ext_functions{$_}, "ext"); }
-print OUT "const unixlib_function_t __wine_unix_call_funcs[] =\n"; +print OUT "const unixlib_entry_t __wine_unix_call_funcs[] =\n"; print OUT "{\n"; +print OUT " &thread_attach,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 1be25db9a5f..7511621cf67 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -1,5 +1,9 @@ /* Automatically generated from http://www.opengl.org/registry files; DO NOT EDIT! */
+#if 0 +#pragma makedep unix +#endif + #include <stdarg.h> #include <stddef.h>
@@ -12,6 +16,7 @@ #include "unixlib.h" #include "unix_private.h"
+extern NTSTATUS thread_attach( void *args ) DECLSPEC_HIDDEN; extern NTSTATUS wgl_wglCopyContext( void *args ) DECLSPEC_HIDDEN; extern NTSTATUS wgl_wglCreateContext( void *args ) DECLSPEC_HIDDEN; extern NTSTATUS wgl_wglDeleteContext( void *args ) DECLSPEC_HIDDEN; @@ -24141,8 +24146,9 @@ static NTSTATUS ext_wglSwapIntervalEXT( void *args ) return STATUS_SUCCESS; }
-const unixlib_function_t __wine_unix_call_funcs[] = +const unixlib_entry_t __wine_unix_call_funcs[] = { + &thread_attach, &wgl_wglCopyContext, &wgl_wglCreateContext, &wgl_wglDeleteContext, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index db025734b8c..7c6204d966d 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -18,11 +18,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#if 0 +#pragma makedep unix +#endif + #include "config.h"
#include <stdarg.h> #include <stdlib.h>
+#include <pthread.h> + #include "ntstatus.h" #define WIN32_NO_STATUS #include "windef.h" @@ -37,14 +43,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wgl);
-static CRITICAL_SECTION wgl_section; -static CRITICAL_SECTION_DEBUG critsect_debug = -{ - 0, 0, &wgl_section, - { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, - 0, 0, { (DWORD_PTR)(__FILE__ ": wgl_section") } -}; -static CRITICAL_SECTION wgl_section = { &critsect_debug, -1, 0, 0, 0, 0 }; +static pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER;
/* handle management */
@@ -154,7 +153,7 @@ static GLubyte *filter_extensions_list( const char *extensions, const char *disa const char *end; char *p, *str;
- p = str = HeapAlloc( GetProcessHeap(), 0, strlen( extensions ) + 2 ); + p = str = malloc( strlen( extensions ) + 2 ); if (!str) return NULL;
TRACE( "GL_EXTENSIONS:\n" ); @@ -200,7 +199,7 @@ static GLuint *filter_extensions_index( const char *disabled ) }
funcs->gl.p_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); - disabled_index = HeapAlloc( GetProcessHeap(), 0, extensions_count * sizeof(*disabled_index) ); + disabled_index = malloc( extensions_count * sizeof(*disabled_index) ); if (!disabled_index) return NULL;
TRACE( "GL_EXTENSIONS:\n" ); @@ -294,14 +293,6 @@ static ULONG query_reg_value( HKEY hkey, const WCHAR *name, KEY_VALUE_PARTIAL_IN return size - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); }
-static char *heap_strdup( const char *str ) -{ - int len = strlen( str ) + 1; - char *ret = HeapAlloc( GetProcessHeap(), 0, len ); - memcpy( ret, str, len ); - return ret; -} - /* build the extension string by filtering out the disabled extensions */ static BOOL filter_extensions( const char *extensions, GLubyte **exts_list, GLuint **disabled_exts ) { @@ -319,13 +310,12 @@ static BOOL filter_extensions( const char *extensions, GLubyte **exts_list, GLui KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer; static WCHAR disabled_extensionsW[] = {'D','i','s','a','b','l','e','d','E','x','t','e','n','s','i','o','n','s',0};
- if (query_reg_value( hkey, disabled_extensionsW, value, sizeof(buffer) )) str = heap_strdup( buffer ); + if (query_reg_value( hkey, disabled_extensionsW, value, sizeof(buffer) )) str = strdup( buffer ); NtClose( hkey ); } if (str) { - if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) - HeapFree( GetProcessHeap(), 0, str ); + if (InterlockedCompareExchangePointer( (void **)&disabled, str, NULL )) free( str ); } else disabled = ""; } @@ -445,12 +435,12 @@ static char *build_extension_list(void) wrap_glGetIntegerv( GL_NUM_EXTENSIONS, &extensions_count ); capacity = 128 * extensions_count;
- if (!(available_extensions = HeapAlloc( GetProcessHeap(), 0, capacity ))) return NULL; + if (!(available_extensions = malloc( capacity ))) return NULL; for (i = 0; i < extensions_count; ++i) { extension = (char *)wrap_glGetStringi( GL_EXTENSIONS, i ); capacity = max( capacity, len + strlen( extension ) + 2 ); - if (!(tmp = HeapReAlloc( GetProcessHeap(), 0, available_extensions, capacity ))) break; + if (!(tmp = realloc( available_extensions, capacity ))) break; available_extensions = tmp; len += sprintf( available_extensions + len, "%s ", extension ); } @@ -472,13 +462,13 @@ static BOOL is_extension_supported( const char *extension ) char *available_extensions = NULL; BOOL ret = FALSE;
- if (type == HANDLE_CONTEXT) available_extensions = heap_strdup( (const char *)wrap_glGetString( GL_EXTENSIONS ) ); + if (type == HANDLE_CONTEXT) available_extensions = strdup( (const char *)wrap_glGetString( GL_EXTENSIONS ) ); if (!available_extensions) available_extensions = build_extension_list();
if (!available_extensions) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" ); else ret = check_extension_support( extension, available_extensions );
- HeapFree( GetProcessHeap(), 0, available_extensions ); + free( available_extensions ); return ret; }
@@ -570,11 +560,10 @@ static HGLRC wrap_wglCreateContext( HDC hdc )
if (!funcs) return 0; if (!(drv_ctx = funcs->wgl.p_wglCreateContext( hdc ))) return 0; - if ((context = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context) ))) + if ((context = calloc( 1, sizeof(*context) ))) { context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) - HeapFree( GetProcessHeap(), 0, context ); + if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) free( context ); } if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); return ret; @@ -634,9 +623,9 @@ static BOOL wrap_wglDeleteContext( HGLRC hglrc ) } if (hglrc == NtCurrentTeb()->glCurrentRC) wrap_wglMakeCurrent( 0, 0 ); ptr->funcs->wgl.p_wglDeleteContext( ptr->u.context->drv_ctx ); - HeapFree( GetProcessHeap(), 0, ptr->u.context->disabled_exts ); - HeapFree( GetProcessHeap(), 0, ptr->u.context->extensions ); - HeapFree( GetProcessHeap(), 0, ptr->u.context ); + free( ptr->u.context->disabled_exts ); + free( ptr->u.context->extensions ); + free( ptr->u.context ); free_handle_ptr( ptr ); return TRUE; } @@ -683,7 +672,7 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a } if ((drv_ctx = funcs->ext.p_wglCreateContextAttribsARB( hdc, share_ptr ? share_ptr->u.context->drv_ctx : NULL, attribs ))) { - if ((context = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context) ))) + if ((context = calloc( 1, sizeof(*context) ))) { enum wgl_handle_type type = HANDLE_CONTEXT;
@@ -701,7 +690,7 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a }
context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( type, funcs, context ))) HeapFree( GetProcessHeap(), 0, context ); + if (!(ret = alloc_handle( type, funcs, context ))) free( context ); } if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); } @@ -817,16 +806,15 @@ static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GL .length = length, .message = message, }; - BOOL (WINAPI *callback)( struct wine_gl_debug_message_params *params, ULONG size ); - void **kernel_callback_table; + void *ret_ptr; + ULONG ret_len;
struct wgl_handle *ptr = (struct wgl_handle *)userParam; if (!(params.user_callback = ptr->u.context->debug_callback)) return; params.user_data = ptr->u.context->debug_user;
- kernel_callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; - callback = kernel_callback_table[NtUserCallOpenGLDebugMessageCallback]; - callback( ¶ms, sizeof(params) ); + KeUserModeCallback( NtUserCallOpenGLDebugMessageCallback, ¶ms, sizeof(params), + &ret_ptr, &ret_len ); }
static void WINAPI wrap_glDebugMessageCallback( GLDEBUGPROC callback, const void *userParam ) @@ -868,27 +856,27 @@ static void WINAPI wrap_glDebugMessageCallbackARB( GLDEBUGPROCARB callback, cons NTSTATUS wgl_wglCopyContext( void *args ) { struct wglCopyContext_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglCopyContext( params->hglrcSrc, params->hglrcDst, params->mask ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS wgl_wglCreateContext( void *args ) { struct wglCreateContext_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglCreateContext( params->hDc ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS wgl_wglDeleteContext( void *args ) { struct wglDeleteContext_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglDeleteContext( params->oldContext ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
@@ -902,18 +890,18 @@ NTSTATUS wgl_wglGetProcAddress( void *args ) NTSTATUS wgl_wglMakeCurrent( void *args ) { struct wglMakeCurrent_params *params = args; - if (params->newContext) EnterCriticalSection( &wgl_section ); + if (params->newContext) pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeCurrent( params->hDc, params->newContext ); - if (params->newContext) LeaveCriticalSection( &wgl_section ); + if (params->newContext) pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS wgl_wglShareLists( void *args ) { struct wglShareLists_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglShareLists( params->hrcSrvShare, params->hrcSrvSource ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
@@ -962,89 +950,95 @@ NTSTATUS ext_glGetStringi( void *args ) NTSTATUS ext_wglBindTexImageARB( void *args ) { struct wglBindTexImageARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglBindTexImageARB( params->hPbuffer, params->iBuffer ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglCreateContextAttribsARB( void *args ) { struct wglCreateContextAttribsARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglCreateContextAttribsARB( params->hDC, params->hShareContext, params->attribList ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglCreatePbufferARB( void *args ) { struct wglCreatePbufferARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglCreatePbufferARB( params->hDC, params->iPixelFormat, params->iWidth, params->iHeight, params->piAttribList ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglDestroyPbufferARB( void *args ) { struct wglDestroyPbufferARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglDestroyPbufferARB( params->hPbuffer ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglGetPbufferDCARB( void *args ) { struct wglGetPbufferDCARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglGetPbufferDCARB( params->hPbuffer ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglMakeContextCurrentARB( void *args ) { struct wglMakeContextCurrentARB_params *params = args; - if (params->hglrc) EnterCriticalSection( &wgl_section ); + if (params->hglrc) pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeContextCurrentARB( params->hDrawDC, params->hReadDC, params->hglrc ); - if (params->hglrc) LeaveCriticalSection( &wgl_section ); + if (params->hglrc) pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglQueryPbufferARB( void *args ) { struct wglQueryPbufferARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglQueryPbufferARB( params->hPbuffer, params->iAttribute, params->piValue ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglReleasePbufferDCARB( void *args ) { struct wglReleasePbufferDCARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglReleasePbufferDCARB( params->hPbuffer, params->hDC ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglReleaseTexImageARB( void *args ) { struct wglReleaseTexImageARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglReleaseTexImageARB( params->hPbuffer, params->iBuffer ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; }
NTSTATUS ext_wglSetPbufferAttribARB( void *args ) { struct wglSetPbufferAttribARB_params *params = args; - EnterCriticalSection( &wgl_section ); + pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglSetPbufferAttribARB( params->hPbuffer, params->piAttribList ); - LeaveCriticalSection( &wgl_section ); + pthread_mutex_unlock( &wgl_lock ); + return STATUS_SUCCESS; +} + +NTSTATUS WINAPI thread_attach( void *args ) +{ + NtCurrentTeb()->glTable = &null_opengl_funcs; return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 68e66b47a3a..b76858a2e13 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -22293,6 +22293,7 @@ struct wglSwapIntervalEXT_params
enum unix_funcs { + unix_thread_attach, unix_wglCopyContext, unix_wglCreateContext, unix_wglDeleteContext, @@ -25349,8 +25350,7 @@ struct wine_gl_debug_message_params const GLchar *message; };
-typedef NTSTATUS (*unixlib_function_t)( void *args ); -extern const unixlib_function_t __wine_unix_call_funcs[] DECLSPEC_HIDDEN; -#define UNIX_CALL( func, params ) __wine_unix_call_funcs[unix_ ## func]( params ) +extern unixlib_handle_t unixlib_handle DECLSPEC_HIDDEN; +#define UNIX_CALL( func, params ) __wine_unix_call( unixlib_handle, unix_ ## func, params )
#endif /* __WINE_OPENGL32_UNIXLIB_H */ diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 76ce3437a97..3d547783f31 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -18,8 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "config.h" - #include <stdarg.h> #include <stdlib.h> #include <math.h> @@ -40,6 +38,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl); WINE_DECLARE_DEBUG_CHANNEL(fps);
+unixlib_handle_t unixlib_handle; + static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
/*********************************************************************** @@ -865,25 +865,33 @@ static BOOL WINAPI call_opengl_debug_message_callback( struct wine_gl_debug_mess return TRUE; }
-extern struct opengl_funcs null_opengl_funcs DECLSPEC_HIDDEN; - /*********************************************************************** * OpenGL initialisation routine */ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { void **kernel_callback_table; + NTSTATUS status;
switch(reason) { case DLL_PROCESS_ATTACH: - NtCurrentTeb()->glTable = &null_opengl_funcs; + if ((status = NtQueryVirtualMemory( GetCurrentProcess(), hinst, MemoryWineUnixFuncs, + &unixlib_handle, sizeof(unixlib_handle), NULL ))) + { + ERR( "Failed to load unixlib, status %#x\n", status ); + return FALSE; + }
kernel_callback_table = NtCurrentTeb()->Peb->KernelCallbackTable; kernel_callback_table[NtUserCallOpenGLDebugMessageCallback] = call_opengl_debug_message_callback; - break; + /* fallthrough */ case DLL_THREAD_ATTACH: - NtCurrentTeb()->glTable = &null_opengl_funcs; + if ((status = UNIX_CALL( thread_attach, NULL ))) + { + WARN( "Failed to initialize thread, status %#x\n", status ); + return FALSE; + } break; } return TRUE;