From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/Makefile.in | 1 + dlls/opengl32/make_opengl | 14 + dlls/opengl32/opengl_ext.h | 56 ++++ dlls/opengl32/unix_wgl.c | 459 +++++++++++++++++++++++++++++ dlls/opengl32/unixlib.h | 14 + dlls/opengl32/wgl.c | 588 +------------------------------------ 6 files changed, 550 insertions(+), 582 deletions(-) create mode 100644 dlls/opengl32/unix_wgl.c
diff --git a/dlls/opengl32/Makefile.in b/dlls/opengl32/Makefile.in index 380a686f261..16f5ab17120 100644 --- a/dlls/opengl32/Makefile.in +++ b/dlls/opengl32/Makefile.in @@ -9,6 +9,7 @@ EXTRADLLFLAGS = -Wl,--image-base,0x7a800000 -mcygwin C_SRCS = \ thunks.c \ unix_thunks.c \ + unix_wgl.c \ wgl.c
RC_SRCS = version.rc diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 6c40c51c3e0..f178ba462d0 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -837,6 +837,20 @@ foreach (sort keys %ext_functions) } print OUT "};\n\n";
+print OUT "typedef void (WINAPI *gl_debug_cb)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *);\n"; +print OUT "struct wine_gl_debug_message_params\n"; +print OUT "{\n"; +print OUT " gl_debug_cb user_callback;\n"; +print OUT " const void *user_data;\n"; +print OUT "\n"; +print OUT " GLenum source;\n"; +print OUT " GLenum type;\n"; +print OUT " GLuint id;\n"; +print OUT " GLenum severity;\n"; +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"; diff --git a/dlls/opengl32/opengl_ext.h b/dlls/opengl32/opengl_ext.h index 7873c974cc7..2a579e142b6 100644 --- a/dlls/opengl32/opengl_ext.h +++ b/dlls/opengl32/opengl_ext.h @@ -19,9 +19,14 @@ #ifndef __DLLS_OPENGL32_OPENGL_EXT_H #define __DLLS_OPENGL32_OPENGL_EXT_H
+#include <stdarg.h> +#include <stddef.h> + #include "windef.h" #include "winbase.h" +#include "winternl.h" #include "wingdi.h" + #include "wine/wgl.h" #include "wine/wgl_driver.h"
@@ -43,6 +48,57 @@ static inline struct opengl_funcs *get_dc_funcs( HDC hdc ) return funcs; }
+#define MAX_WGL_HANDLES 1024 + +/* handle management */ + +enum wgl_handle_type +{ + HANDLE_PBUFFER = 0 << 12, + HANDLE_CONTEXT = 1 << 12, + HANDLE_CONTEXT_V3 = 3 << 12, + HANDLE_TYPE_MASK = 15 << 12 +}; + +struct opengl_context +{ + DWORD tid; /* thread that the context is current in */ + HDC draw_dc; /* current drawing DC */ + HDC read_dc; /* current reading DC */ + void (CALLBACK *debug_callback)( GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void * ); /* debug callback */ + const void *debug_user; /* debug user parameter */ + GLubyte *extensions; /* extension string */ + GLuint *disabled_exts; /* indices of disabled extensions */ + struct wgl_context *drv_ctx; /* driver context */ +}; + +struct wgl_handle +{ + UINT handle; + struct opengl_funcs *funcs; + union + { + struct opengl_context *context; /* for HANDLE_CONTEXT */ + struct wgl_pbuffer *pbuffer; /* for HANDLE_PBUFFER */ + struct wgl_handle *next; /* for free handles */ + } u; +}; + +extern struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; + +/* 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) & ~HANDLE_TYPE_MASK]; +} + +static inline enum wgl_handle_type get_current_context_type(void) +{ + if (!NtCurrentTeb()->glCurrentRC) return HANDLE_CONTEXT; + return LOWORD(NtCurrentTeb()->glCurrentRC) & HANDLE_TYPE_MASK; +} + extern int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd );
#endif /* __DLLS_OPENGL32_OPENGL_EXT_H */ diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c new file mode 100644 index 00000000000..70ee0a5cdab --- /dev/null +++ b/dlls/opengl32/unix_wgl.c @@ -0,0 +1,459 @@ +/* Window-specific OpenGL functions implementation. + * + * Copyright (c) 1999 Lionel Ulmer + * Copyright (c) 2005 Raphael Junqueira + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include <stdarg.h> +#include <stdlib.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "ntuser.h" + +#include "opengl_ext.h" + +#include "unixlib.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wgl); + +struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; +static struct wgl_handle *next_free; +static unsigned int handle_count; + +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 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 ) | type; + return ULongToHandle( ptr->handle ); +} + +static struct wgl_handle *get_handle_ptr( HANDLE handle, enum wgl_handle_type type ) +{ + unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK; + + EnterCriticalSection( &wgl_section ); + if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle) + return &wgl_handles[index]; + + LeaveCriticalSection( &wgl_section ); + SetLastError( ERROR_INVALID_HANDLE ); + return NULL; +} + +static void release_handle_ptr( struct wgl_handle *ptr ) +{ + if (ptr) LeaveCriticalSection( &wgl_section ); +} + +static HANDLE alloc_handle( enum wgl_handle_type type, struct opengl_funcs *funcs, void *user_ptr ) +{ + HANDLE handle = 0; + struct wgl_handle *ptr = NULL; + + EnterCriticalSection( &wgl_section ); + if ((ptr = next_free)) + next_free = next_free->u.next; + else if (handle_count < MAX_WGL_HANDLES) + ptr = &wgl_handles[handle_count++]; + + if (ptr) + { + ptr->funcs = funcs; + ptr->u.context = user_ptr; + handle = next_handle( ptr, type ); + } + else SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + LeaveCriticalSection( &wgl_section ); + return handle; +} + +static void free_handle_ptr( struct wgl_handle *ptr ) +{ + ptr->handle |= 0xffff; + ptr->u.next = next_free; + ptr->funcs = NULL; + next_free = ptr; + LeaveCriticalSection( &wgl_section ); +} + +BOOL WINAPI wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) +{ + struct wgl_handle *src, *dst; + BOOL ret = FALSE; + + 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->u.context->drv_ctx, dst->u.context->drv_ctx, mask ); + } + release_handle_ptr( dst ); + release_handle_ptr( src ); + return ret; +} + +HGLRC WINAPI wglCreateContext( HDC hdc ) +{ + HGLRC ret = 0; + struct wgl_context *drv_ctx; + struct opengl_context *context; + struct opengl_funcs *funcs = get_dc_funcs( hdc ); + + if (!funcs) return 0; + if (!(drv_ctx = funcs->wgl.p_wglCreateContext( hdc ))) return 0; + if ((context = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context) ))) + { + context->drv_ctx = drv_ctx; + if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) + HeapFree( GetProcessHeap(), 0, context ); + } + if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); + return ret; +} + +BOOL WINAPI wglDeleteContext( HGLRC hglrc ) +{ + struct wgl_handle *ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ); + + if (!ptr) return FALSE; + + if (ptr->u.context->tid && ptr->u.context->tid != GetCurrentThreadId()) + { + SetLastError( ERROR_BUSY ); + release_handle_ptr( ptr ); + return FALSE; + } + if (hglrc == NtCurrentTeb()->glCurrentRC) 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_handle_ptr( ptr ); + return TRUE; +} + +BOOL WINAPI wglMakeCurrent( HDC hdc, HGLRC hglrc ) +{ + BOOL ret = TRUE; + struct wgl_handle *ptr, *prev = get_current_context_ptr(); + + if (hglrc) + { + if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE; + if (!ptr->u.context->tid || ptr->u.context->tid == GetCurrentThreadId()) + { + ret = ptr->funcs->wgl.p_wglMakeCurrent( hdc, ptr->u.context->drv_ctx ); + if (ret) + { + if (prev) prev->u.context->tid = 0; + ptr->u.context->tid = GetCurrentThreadId(); + ptr->u.context->draw_dc = hdc; + ptr->u.context->read_dc = hdc; + NtCurrentTeb()->glCurrentRC = hglrc; + NtCurrentTeb()->glTable = ptr->funcs; + } + } + else + { + SetLastError( ERROR_BUSY ); + ret = FALSE; + } + release_handle_ptr( ptr ); + } + else if (prev) + { + if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE; + prev->u.context->tid = 0; + NtCurrentTeb()->glCurrentRC = 0; + NtCurrentTeb()->glTable = &null_opengl_funcs; + } + else if (!hdc) + { + SetLastError( ERROR_INVALID_HANDLE ); + ret = FALSE; + } + return ret; +} + +BOOL WINAPI wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) +{ + BOOL ret = FALSE; + struct wgl_handle *src, *dst; + + 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->u.context->drv_ctx, dst->u.context->drv_ctx ); + } + release_handle_ptr( dst ); + release_handle_ptr( src ); + return ret; +} + +BOOL WINAPI wglBindTexImageARB( HPBUFFERARB handle, int buffer ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + BOOL ret; + + if (!ptr) return FALSE; + ret = ptr->funcs->ext.p_wglBindTexImageARB( ptr->u.pbuffer, buffer ); + release_handle_ptr( ptr ); + return ret; +} + +HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs ) +{ + HGLRC ret = 0; + struct wgl_context *drv_ctx; + struct wgl_handle *share_ptr = NULL; + struct opengl_context *context; + struct opengl_funcs *funcs = get_dc_funcs( hdc ); + + if (!funcs) + { + SetLastError( ERROR_DC_NOT_FOUND ); + return 0; + } + if (!funcs->ext.p_wglCreateContextAttribsARB) return 0; + if (share && !(share_ptr = get_handle_ptr( share, HANDLE_CONTEXT ))) + { + SetLastError( ERROR_INVALID_OPERATION ); + return 0; + } + 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) ))) + { + enum wgl_handle_type type = HANDLE_CONTEXT; + + if (attribs) + { + while (*attribs) + { + if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) + { + if (attribs[1] >= 3) type = HANDLE_CONTEXT_V3; + break; + } + attribs += 2; + } + } + + context->drv_ctx = drv_ctx; + if (!(ret = alloc_handle( type, funcs, context ))) HeapFree( GetProcessHeap(), 0, context ); + } + if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); + } + + release_handle_ptr( share_ptr ); + return ret; +} + +HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs ) +{ + HPBUFFERARB ret; + struct wgl_pbuffer *pbuffer; + struct opengl_funcs *funcs = get_dc_funcs( hdc ); + + if (!funcs || !funcs->ext.p_wglCreatePbufferARB) return 0; + if (!(pbuffer = funcs->ext.p_wglCreatePbufferARB( hdc, format, width, height, attribs ))) return 0; + ret = alloc_handle( HANDLE_PBUFFER, funcs, pbuffer ); + if (!ret) funcs->ext.p_wglDestroyPbufferARB( pbuffer ); + return ret; +} + +BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + + if (!ptr) return FALSE; + ptr->funcs->ext.p_wglDestroyPbufferARB( ptr->u.pbuffer ); + free_handle_ptr( ptr ); + return TRUE; +} + +HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB handle ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + HDC ret; + + if (!ptr) return 0; + ret = ptr->funcs->ext.p_wglGetPbufferDCARB( ptr->u.pbuffer ); + release_handle_ptr( ptr ); + return ret; +} + +BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) +{ + BOOL ret = TRUE; + struct wgl_handle *ptr, *prev = get_current_context_ptr(); + + if (hglrc) + { + if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE; + if (!ptr->u.context->tid || ptr->u.context->tid == GetCurrentThreadId()) + { + ret = (ptr->funcs->ext.p_wglMakeContextCurrentARB && + ptr->funcs->ext.p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ptr->u.context->drv_ctx )); + if (ret) + { + if (prev) prev->u.context->tid = 0; + ptr->u.context->tid = GetCurrentThreadId(); + ptr->u.context->draw_dc = draw_hdc; + ptr->u.context->read_dc = read_hdc; + NtCurrentTeb()->glCurrentRC = hglrc; + NtCurrentTeb()->glTable = ptr->funcs; + } + } + else + { + SetLastError( ERROR_BUSY ); + ret = FALSE; + } + release_handle_ptr( ptr ); + } + else if (prev) + { + if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE; + prev->u.context->tid = 0; + NtCurrentTeb()->glCurrentRC = 0; + NtCurrentTeb()->glTable = &null_opengl_funcs; + } + return ret; +} + +BOOL WINAPI wglQueryPbufferARB( HPBUFFERARB handle, int attrib, int *value ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + BOOL ret; + + if (!ptr) return FALSE; + ret = ptr->funcs->ext.p_wglQueryPbufferARB( ptr->u.pbuffer, attrib, value ); + release_handle_ptr( ptr ); + return ret; +} + +int WINAPI wglReleasePbufferDCARB( HPBUFFERARB handle, HDC hdc ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + BOOL ret; + + if (!ptr) return FALSE; + ret = ptr->funcs->ext.p_wglReleasePbufferDCARB( ptr->u.pbuffer, hdc ); + release_handle_ptr( ptr ); + return ret; +} + +BOOL WINAPI wglReleaseTexImageARB( HPBUFFERARB handle, int buffer ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + BOOL ret; + + if (!ptr) return FALSE; + ret = ptr->funcs->ext.p_wglReleaseTexImageARB( ptr->u.pbuffer, buffer ); + release_handle_ptr( ptr ); + return ret; +} + +BOOL WINAPI wglSetPbufferAttribARB( HPBUFFERARB handle, const int *attribs ) +{ + struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); + BOOL ret; + + if (!ptr) return FALSE; + ret = ptr->funcs->ext.p_wglSetPbufferAttribARB( ptr->u.pbuffer, attribs ); + release_handle_ptr( ptr ); + return ret; +} + +static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar *message, const void *userParam ) +{ + struct wine_gl_debug_message_params params = + { + .source = source, + .type = type, + .id = id, + .severity = severity, + .length = length, + .message = message, + }; + BOOL (WINAPI *callback)( struct wine_gl_debug_message_params *params, ULONG size ); + void **kernel_callback_table; + + 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) ); +} + +void WINAPI glDebugMessageCallback( GLDEBUGPROC callback, const void *userParam ) +{ + struct wgl_handle *ptr = get_current_context_ptr(); + const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; + + TRACE( "(%p, %p)\n", callback, userParam ); + + ptr->u.context->debug_callback = callback; + ptr->u.context->debug_user = userParam; + funcs->ext.p_glDebugMessageCallback( gl_debug_message_callback, ptr ); +} + +void WINAPI glDebugMessageCallbackAMD( GLDEBUGPROCAMD callback, void *userParam ) +{ + struct wgl_handle *ptr = get_current_context_ptr(); + const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; + + TRACE( "(%p, %p)\n", callback, userParam ); + + ptr->u.context->debug_callback = callback; + ptr->u.context->debug_user = userParam; + funcs->ext.p_glDebugMessageCallbackAMD( gl_debug_message_callback, ptr ); +} + +void WINAPI glDebugMessageCallbackARB( GLDEBUGPROCARB callback, const void *userParam ) +{ + struct wgl_handle *ptr = get_current_context_ptr(); + const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; + + TRACE( "(%p, %p)\n", callback, userParam ); + + ptr->u.context->debug_callback = callback; + ptr->u.context->debug_user = userParam; + funcs->ext.p_glDebugMessageCallbackARB( gl_debug_message_callback, ptr ); +} diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 88b744d0f10..68e66b47a3a 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -25335,6 +25335,20 @@ enum unix_funcs unix_wglSwapIntervalEXT, };
+typedef void (WINAPI *gl_debug_cb)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *); +struct wine_gl_debug_message_params +{ + gl_debug_cb user_callback; + const void *user_data; + + GLenum source; + GLenum type; + GLuint id; + GLenum severity; + GLsizei length; + 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 ) diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index cf0b8e0330f..d5b0a78b916 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -41,319 +41,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl); WINE_DECLARE_DEBUG_CHANNEL(fps);
-/* handle management */ - -#define MAX_WGL_HANDLES 1024 - -enum wgl_handle_type -{ - HANDLE_PBUFFER = 0 << 12, - HANDLE_CONTEXT = 1 << 12, - HANDLE_CONTEXT_V3 = 3 << 12, - HANDLE_TYPE_MASK = 15 << 12 -}; - -struct opengl_context -{ - DWORD tid; /* thread that the context is current in */ - HDC draw_dc; /* current drawing DC */ - HDC read_dc; /* current reading DC */ - void (CALLBACK *debug_callback)(GLenum, GLenum, GLuint, GLenum, - GLsizei, const GLchar *, const void *); /* debug callback */ - const void *debug_user; /* debug user parameter */ - GLubyte *extensions; /* extension string */ - GLuint *disabled_exts; /* indices of disabled extensions */ - struct wgl_context *drv_ctx; /* driver context */ -}; - -struct wgl_handle -{ - UINT handle; - struct opengl_funcs *funcs; - union - { - struct opengl_context *context; /* for HANDLE_CONTEXT */ - struct wgl_pbuffer *pbuffer; /* for HANDLE_PBUFFER */ - struct wgl_handle *next; /* for free handles */ - } u; -}; - -static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; -static struct wgl_handle *next_free; -static unsigned int handle_count; - -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 const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
-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 ) | type; - return ULongToHandle( ptr->handle ); -} - -/* 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) & ~HANDLE_TYPE_MASK]; -} - -static struct wgl_handle *get_handle_ptr( HANDLE handle, enum wgl_handle_type type ) -{ - unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK; - - EnterCriticalSection( &wgl_section ); - if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle) - return &wgl_handles[index]; - - LeaveCriticalSection( &wgl_section ); - SetLastError( ERROR_INVALID_HANDLE ); - return NULL; -} - -static void release_handle_ptr( struct wgl_handle *ptr ) -{ - if (ptr) LeaveCriticalSection( &wgl_section ); -} - -static HANDLE alloc_handle( enum wgl_handle_type type, struct opengl_funcs *funcs, void *user_ptr ) -{ - HANDLE handle = 0; - struct wgl_handle *ptr = NULL; - - EnterCriticalSection( &wgl_section ); - if ((ptr = next_free)) - next_free = next_free->u.next; - else if (handle_count < MAX_WGL_HANDLES) - ptr = &wgl_handles[handle_count++]; - - if (ptr) - { - ptr->funcs = funcs; - ptr->u.context = user_ptr; - handle = next_handle( ptr, type ); - } - else SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - LeaveCriticalSection( &wgl_section ); - return handle; -} - -static void free_handle_ptr( struct wgl_handle *ptr ) -{ - ptr->handle |= 0xffff; - ptr->u.next = next_free; - ptr->funcs = NULL; - next_free = ptr; - LeaveCriticalSection( &wgl_section ); -} - -static inline enum wgl_handle_type get_current_context_type(void) -{ - if (!NtCurrentTeb()->glCurrentRC) return HANDLE_CONTEXT; - return LOWORD(NtCurrentTeb()->glCurrentRC) & HANDLE_TYPE_MASK; -} - -/*********************************************************************** - * wglCopyContext (OPENGL32.@) - */ -BOOL WINAPI wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) -{ - struct wgl_handle *src, *dst; - BOOL ret = FALSE; - - 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->u.context->drv_ctx, - dst->u.context->drv_ctx, mask ); - } - release_handle_ptr( dst ); - release_handle_ptr( src ); - return ret; -} - -/*********************************************************************** - * wglDeleteContext (OPENGL32.@) - */ -BOOL WINAPI wglDeleteContext(HGLRC hglrc) -{ - struct wgl_handle *ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ); - - if (!ptr) return FALSE; - - if (ptr->u.context->tid && ptr->u.context->tid != GetCurrentThreadId()) - { - SetLastError( ERROR_BUSY ); - release_handle_ptr( ptr ); - return FALSE; - } - if (hglrc == NtCurrentTeb()->glCurrentRC) 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_handle_ptr( ptr ); - return TRUE; -} - -/*********************************************************************** - * wglMakeCurrent (OPENGL32.@) - */ -BOOL WINAPI wglMakeCurrent(HDC hdc, HGLRC hglrc) -{ - BOOL ret = TRUE; - struct wgl_handle *ptr, *prev = get_current_context_ptr(); - - if (hglrc) - { - if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE; - if (!ptr->u.context->tid || ptr->u.context->tid == GetCurrentThreadId()) - { - ret = ptr->funcs->wgl.p_wglMakeCurrent( hdc, ptr->u.context->drv_ctx ); - if (ret) - { - if (prev) prev->u.context->tid = 0; - ptr->u.context->tid = GetCurrentThreadId(); - ptr->u.context->draw_dc = hdc; - ptr->u.context->read_dc = hdc; - NtCurrentTeb()->glCurrentRC = hglrc; - NtCurrentTeb()->glTable = ptr->funcs; - } - } - else - { - SetLastError( ERROR_BUSY ); - ret = FALSE; - } - release_handle_ptr( ptr ); - } - else if (prev) - { - if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE; - prev->u.context->tid = 0; - NtCurrentTeb()->glCurrentRC = 0; - NtCurrentTeb()->glTable = &null_opengl_funcs; - } - else if (!hdc) - { - SetLastError( ERROR_INVALID_HANDLE ); - ret = FALSE; - } - return ret; -} - -/*********************************************************************** - * wglCreateContextAttribsARB - * - * Provided by the WGL_ARB_create_context extension. - */ -HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs ) -{ - HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct wgl_handle *share_ptr = NULL; - struct opengl_context *context; - struct opengl_funcs *funcs = get_dc_funcs( hdc ); - - if (!funcs) - { - SetLastError( ERROR_DC_NOT_FOUND ); - return 0; - } - if (!funcs->ext.p_wglCreateContextAttribsARB) return 0; - if (share && !(share_ptr = get_handle_ptr( share, HANDLE_CONTEXT ))) - { - SetLastError( ERROR_INVALID_OPERATION ); - return 0; - } - 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) ))) - { - enum wgl_handle_type type = HANDLE_CONTEXT; - - if (attribs) - { - while (*attribs) - { - if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) - { - if (attribs[1] >= 3) - type = HANDLE_CONTEXT_V3; - break; - } - attribs += 2; - } - } - - context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( type, funcs, context ))) - HeapFree( GetProcessHeap(), 0, context ); - } - if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); - } - release_handle_ptr( share_ptr ); - return ret; - -} - -/*********************************************************************** - * wglMakeContextCurrentARB - * - * Provided by the WGL_ARB_make_current_read extension. - */ -BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) -{ - BOOL ret = TRUE; - struct wgl_handle *ptr, *prev = get_current_context_ptr(); - - if (hglrc) - { - if (!(ptr = get_handle_ptr( hglrc, HANDLE_CONTEXT ))) return FALSE; - if (!ptr->u.context->tid || ptr->u.context->tid == GetCurrentThreadId()) - { - ret = (ptr->funcs->ext.p_wglMakeContextCurrentARB && - ptr->funcs->ext.p_wglMakeContextCurrentARB( draw_hdc, read_hdc, - ptr->u.context->drv_ctx )); - if (ret) - { - if (prev) prev->u.context->tid = 0; - ptr->u.context->tid = GetCurrentThreadId(); - ptr->u.context->draw_dc = draw_hdc; - ptr->u.context->read_dc = read_hdc; - NtCurrentTeb()->glCurrentRC = hglrc; - NtCurrentTeb()->glTable = ptr->funcs; - } - } - else - { - SetLastError( ERROR_BUSY ); - ret = FALSE; - } - release_handle_ptr( ptr ); - } - else if (prev) - { - if (!prev->funcs->wgl.p_wglMakeCurrent( 0, NULL )) return FALSE; - prev->u.context->tid = 0; - NtCurrentTeb()->glCurrentRC = 0; - NtCurrentTeb()->glTable = &null_opengl_funcs; - } - return ret; -} - /*********************************************************************** * wglGetCurrentReadDCARB * @@ -367,25 +56,6 @@ HDC WINAPI wglGetCurrentReadDCARB(void) return ptr->u.context->read_dc; }
-/*********************************************************************** - * wglShareLists (OPENGL32.@) - */ -BOOL WINAPI wglShareLists(HGLRC hglrcSrc, HGLRC hglrcDst) -{ - BOOL ret = FALSE; - struct wgl_handle *src, *dst; - - 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->u.context->drv_ctx, dst->u.context->drv_ctx ); - } - release_handle_ptr( dst ); - release_handle_ptr( src ); - return ret; -} - /*********************************************************************** * wglGetCurrentDC (OPENGL32.@) */ @@ -397,36 +67,6 @@ HDC WINAPI wglGetCurrentDC(void) return ptr->u.context->draw_dc; }
-/*********************************************************************** - * wgl_create_context wrapper for hooking - */ -static HGLRC wgl_create_context(HDC hdc) -{ - HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct opengl_context *context; - struct opengl_funcs *funcs = get_dc_funcs( hdc ); - - if (!funcs) return 0; - if (!(drv_ctx = funcs->wgl.p_wglCreateContext( hdc ))) return 0; - if ((context = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*context) ))) - { - context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) - HeapFree( GetProcessHeap(), 0, context ); - } - if (!ret) funcs->wgl.p_wglDeleteContext( drv_ctx ); - return ret; -} - -/*********************************************************************** - * wglCreateContext (OPENGL32.@) - */ -HGLRC WINAPI wglCreateContext(HDC hdc) -{ - return wgl_create_context(hdc); -} - /*********************************************************************** * wglGetCurrentContext (OPENGL32.@) */ @@ -658,16 +298,14 @@ BOOL WINAPI DECLSPEC_HOTPATCH wglSwapBuffers( HDC hdc ) /*********************************************************************** * wglCreateLayerContext (OPENGL32.@) */ -HGLRC WINAPI wglCreateLayerContext(HDC hdc, - int iLayerPlane) { - TRACE("(%p,%d)\n", hdc, iLayerPlane); +HGLRC WINAPI wglCreateLayerContext( HDC hdc, int iLayerPlane ) +{ + TRACE("(%p,%d)\n", hdc, iLayerPlane);
- if (iLayerPlane == 0) { - return wgl_create_context(hdc); - } - FIXME("no handler for layer %d\n", iLayerPlane); + if (iLayerPlane == 0) return wglCreateContext( hdc );
- return NULL; + FIXME("no handler for layer %d\n", iLayerPlane); + return NULL; }
/*********************************************************************** @@ -1096,135 +734,6 @@ BOOL WINAPI wglSwapLayerBuffers(HDC hdc, return TRUE; }
-/*********************************************************************** - * wglBindTexImageARB - * - * Provided by the WGL_ARB_render_texture extension. - */ -BOOL WINAPI wglBindTexImageARB( HPBUFFERARB handle, int buffer ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - BOOL ret; - - if (!ptr) return FALSE; - ret = ptr->funcs->ext.p_wglBindTexImageARB( ptr->u.pbuffer, buffer ); - release_handle_ptr( ptr ); - return ret; -} - -/*********************************************************************** - * wglReleaseTexImageARB - * - * Provided by the WGL_ARB_render_texture extension. - */ -BOOL WINAPI wglReleaseTexImageARB( HPBUFFERARB handle, int buffer ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - BOOL ret; - - if (!ptr) return FALSE; - ret = ptr->funcs->ext.p_wglReleaseTexImageARB( ptr->u.pbuffer, buffer ); - release_handle_ptr( ptr ); - return ret; -} - -/*********************************************************************** - * wglSetPbufferAttribARB - * - * Provided by the WGL_ARB_render_texture extension. - */ -BOOL WINAPI wglSetPbufferAttribARB( HPBUFFERARB handle, const int *attribs ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - BOOL ret; - - if (!ptr) return FALSE; - ret = ptr->funcs->ext.p_wglSetPbufferAttribARB( ptr->u.pbuffer, attribs ); - release_handle_ptr( ptr ); - return ret; -} - -/*********************************************************************** - * wglCreatePbufferARB - * - * Provided by the WGL_ARB_pbuffer extension. - */ -HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs ) -{ - HPBUFFERARB ret; - struct wgl_pbuffer *pbuffer; - struct opengl_funcs *funcs = get_dc_funcs( hdc ); - - if (!funcs || !funcs->ext.p_wglCreatePbufferARB) return 0; - if (!(pbuffer = funcs->ext.p_wglCreatePbufferARB( hdc, format, width, height, attribs ))) return 0; - ret = alloc_handle( HANDLE_PBUFFER, funcs, pbuffer ); - if (!ret) funcs->ext.p_wglDestroyPbufferARB( pbuffer ); - return ret; -} - -/*********************************************************************** - * wglGetPbufferDCARB - * - * Provided by the WGL_ARB_pbuffer extension. - */ -HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB handle ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - HDC ret; - - if (!ptr) return 0; - ret = ptr->funcs->ext.p_wglGetPbufferDCARB( ptr->u.pbuffer ); - release_handle_ptr( ptr ); - return ret; -} - -/*********************************************************************** - * wglReleasePbufferDCARB - * - * Provided by the WGL_ARB_pbuffer extension. - */ -int WINAPI wglReleasePbufferDCARB( HPBUFFERARB handle, HDC hdc ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - BOOL ret; - - if (!ptr) return FALSE; - ret = ptr->funcs->ext.p_wglReleasePbufferDCARB( ptr->u.pbuffer, hdc ); - release_handle_ptr( ptr ); - return ret; -} - -/*********************************************************************** - * wglDestroyPbufferARB - * - * Provided by the WGL_ARB_pbuffer extension. - */ -BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - - if (!ptr) return FALSE; - ptr->funcs->ext.p_wglDestroyPbufferARB( ptr->u.pbuffer ); - free_handle_ptr( ptr ); - return TRUE; -} - -/*********************************************************************** - * wglQueryPbufferARB - * - * Provided by the WGL_ARB_pbuffer extension. - */ -BOOL WINAPI wglQueryPbufferARB( HPBUFFERARB handle, int attrib, int *value ) -{ - struct wgl_handle *ptr = get_handle_ptr( handle, HANDLE_PBUFFER ); - BOOL ret; - - if (!ptr) return FALSE; - ret = ptr->funcs->ext.p_wglQueryPbufferARB( ptr->u.pbuffer, attrib, value ); - release_handle_ptr( ptr ); - return ret; -} - /*********************************************************************** * wglUseFontBitmaps_common */ @@ -1707,22 +1216,6 @@ const GLubyte * WINAPI glGetString( GLenum name ) return args.ret; }
-/* wrapper for glDebugMessageCallback* functions */ -typedef void (WINAPI *gl_debug_cb)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar *, const void *); - -struct wine_gl_debug_message_params -{ - gl_debug_cb user_callback; - const void *user_data; - - GLenum source; - GLenum type; - GLuint id; - GLenum severity; - GLsizei length; - const GLchar *message; -}; - static BOOL WINAPI call_opengl_debug_message_callback( struct wine_gl_debug_message_params *params, ULONG size ) { params->user_callback( params->source, params->type, params->id, params->severity, @@ -1730,75 +1223,6 @@ static BOOL WINAPI call_opengl_debug_message_callback( struct wine_gl_debug_mess return TRUE; }
-static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GLenum severity, - GLsizei length, const GLchar *message, const void *userParam ) -{ - struct wine_gl_debug_message_params params = - { - .source = source, - .type = type, - .id = id, - .severity = severity, - .length = length, - .message = message, - }; - void **kernel_callback_table; - BOOL (WINAPI *callback)( struct wine_gl_debug_message_params *params, ULONG size ); - - 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) ); -} - -/*********************************************************************** - * glDebugMessageCallback - */ -void WINAPI glDebugMessageCallback( GLDEBUGPROC callback, const void *userParam ) -{ - struct wgl_handle *ptr = get_current_context_ptr(); - const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; - - TRACE( "(%p, %p)\n", callback, userParam ); - - ptr->u.context->debug_callback = callback; - ptr->u.context->debug_user = userParam; - funcs->ext.p_glDebugMessageCallback( gl_debug_message_callback, ptr ); -} - -/*********************************************************************** - * glDebugMessageCallbackAMD - */ -void WINAPI glDebugMessageCallbackAMD( GLDEBUGPROCAMD callback, void *userParam ) -{ - struct wgl_handle *ptr = get_current_context_ptr(); - const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; - - TRACE( "(%p, %p)\n", callback, userParam ); - - ptr->u.context->debug_callback = callback; - ptr->u.context->debug_user = userParam; - funcs->ext.p_glDebugMessageCallbackAMD( gl_debug_message_callback, ptr ); -} - -/*********************************************************************** - * glDebugMessageCallbackARB - */ -void WINAPI glDebugMessageCallbackARB( GLDEBUGPROCARB callback, const void *userParam ) -{ - struct wgl_handle *ptr = get_current_context_ptr(); - const struct opengl_funcs *funcs = NtCurrentTeb()->glTable; - - TRACE( "(%p, %p)\n", callback, userParam ); - - ptr->u.context->debug_callback = callback; - ptr->u.context->debug_user = userParam; - funcs->ext.p_glDebugMessageCallbackARB( gl_debug_message_callback, ptr ); -} - /*********************************************************************** * OpenGL initialisation routine */