[PATCH 0/7] MR9953: opengl32: Move handle allocation to the PE side.
Introducing a proper separation of client side / unix side objects, similar to what is done in winevulkan, with client side wrappers which we can later use to store some client-specific information such as client extension list, some strings to avoid bogus wow64 string reuse, etc. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/opengl.c | 245 ++++++++++++++++++++++--------------------- 1 file changed, 127 insertions(+), 118 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index f5308314812..320dc571b82 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1438,9 +1438,130 @@ static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc ) return drawable; } +static void wgl_pbuffer_destroy( struct wgl_pbuffer *pbuffer ) +{ + opengl_drawable_release( pbuffer->drawable ); + NtGdiDeleteObjectApp( pbuffer->hdc ); + free( pbuffer ); +} + +static struct wgl_pbuffer *wgl_pbuffer_create( HDC hdc, int format, int width, int height, const int *attribs ) +{ + struct wgl_pbuffer *pbuffer; + UINT size, max_level = 0; + BOOL largest = FALSE; + + if (!(pbuffer = calloc( 1, sizeof(*pbuffer) )) || !(pbuffer->hdc = NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL ))) + { + RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); + free( pbuffer ); + return 0; + } + NtGdiSetPixelFormat( pbuffer->hdc, format ); + pbuffer->width = width; + pbuffer->height = height; + pbuffer->mipmap_level = -1; + + for (; attribs && attribs[0]; attribs += 2) + { + switch (attribs[0]) + { + case WGL_PBUFFER_LARGEST_ARB: + TRACE( "WGL_PBUFFER_LARGEST_ARB %#x\n", attribs[1] ); + largest = !!attribs[1]; + break; + + case WGL_TEXTURE_FORMAT_ARB: + TRACE( "WGL_TEXTURE_FORMAT_ARB %#x\n", attribs[1] ); + switch (attribs[1]) + { + case WGL_NO_TEXTURE_ARB: + pbuffer->texture_format = 0; + break; + case WGL_TEXTURE_RGB_ARB: + pbuffer->texture_format = GL_RGB; + break; + case WGL_TEXTURE_RGBA_ARB: + pbuffer->texture_format = GL_RGBA; + break; + /* WGL_FLOAT_COMPONENTS_NV */ + case WGL_TEXTURE_FLOAT_R_NV: + pbuffer->texture_format = GL_FLOAT_R_NV; + break; + case WGL_TEXTURE_FLOAT_RG_NV: + pbuffer->texture_format = GL_FLOAT_RG_NV; + break; + case WGL_TEXTURE_FLOAT_RGB_NV: + pbuffer->texture_format = GL_FLOAT_RGB_NV; + break; + case WGL_TEXTURE_FLOAT_RGBA_NV: + pbuffer->texture_format = GL_FLOAT_RGBA_NV; + break; + default: + FIXME( "Unknown texture format: %x\n", attribs[1] ); + goto failed; + } + break; + + case WGL_TEXTURE_TARGET_ARB: + TRACE( "WGL_TEXTURE_TARGET_ARB %#x\n", attribs[1] ); + switch (attribs[1]) + { + case WGL_NO_TEXTURE_ARB: + pbuffer->texture_target = 0; + break; + case WGL_TEXTURE_CUBE_MAP_ARB: + if (width != height) goto failed; + pbuffer->texture_target = GL_TEXTURE_CUBE_MAP; + break; + case WGL_TEXTURE_1D_ARB: + if (height != 1) goto failed; + pbuffer->texture_target = GL_TEXTURE_1D; + break; + case WGL_TEXTURE_2D_ARB: + pbuffer->texture_target = GL_TEXTURE_2D; + break; + case WGL_TEXTURE_RECTANGLE_NV: + pbuffer->texture_target = GL_TEXTURE_RECTANGLE_NV; + break; + default: + FIXME( "Unknown texture target: %x\n", attribs[1] ); + goto failed; + } + break; + + case WGL_MIPMAP_TEXTURE_ARB: + TRACE( "WGL_MIPMAP_TEXTURE_ARB %#x\n", attribs[1] ); + if (attribs[1]) + { + pbuffer->mipmap_level = max_level = 0; + for (size = min( width, height ) / 2; size; size /= 2) max_level++; + } + break; + + default: + WARN( "attribute %#x %#x not handled\n", attribs[0], attribs[1] ); + break; + } + } + + if (driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, + pbuffer->texture_target, max_level, &pbuffer->width, + &pbuffer->height, &pbuffer->drawable )) + { + set_dc_opengl_drawable( pbuffer->hdc, pbuffer->drawable ); + return pbuffer; + } + +failed: + RtlSetLastWin32Error( ERROR_INVALID_DATA ); + NtGdiDeleteObjectApp( pbuffer->hdc ); + free( pbuffer ); + return NULL; +} + static BOOL create_memory_pbuffer( HDC hdc ) { - const struct opengl_funcs *funcs = &display_funcs; dib_info dib = {.rect = {0, 0, 1, 1}}; BOOL ret = TRUE; BITMAPOBJ *bmp; @@ -1463,13 +1584,13 @@ static BOOL create_memory_pbuffer( HDC hdc ) int width = dib.rect.right - dib.rect.left, height = dib.rect.bottom - dib.rect.top; struct wgl_pbuffer *pbuffer; - if (!(pbuffer = funcs->p_wglCreatePbufferARB( hdc, format, width, height, NULL ))) + if (!(pbuffer = wgl_pbuffer_create( hdc, format, width, height, NULL ))) WARN( "Failed to create pbuffer for memory DC %p\n", hdc ); else { TRACE( "Created pbuffer %p for memory DC %p\n", pbuffer, hdc ); set_dc_opengl_drawable( hdc, pbuffer->drawable ); - funcs->p_wglDestroyPbufferARB( pbuffer ); + wgl_pbuffer_destroy( pbuffer ); } } @@ -1812,9 +1933,7 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int const int *attribs ) { const struct opengl_funcs *funcs = &display_funcs; - UINT total, onscreen, size, max_level = 0; - struct wgl_pbuffer *pbuffer; - BOOL largest = FALSE; + UINT total, onscreen; TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs ); @@ -1830,123 +1949,13 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int return NULL; } - if (!(pbuffer = calloc( 1, sizeof(*pbuffer) )) || !(pbuffer->hdc = NtGdiOpenDCW( NULL, NULL, NULL, 0, TRUE, NULL, NULL, NULL ))) - { - RtlSetLastWin32Error( ERROR_NO_SYSTEM_RESOURCES ); - free( pbuffer ); - return NULL; - } - NtGdiSetPixelFormat( pbuffer->hdc, format ); - pbuffer->width = width; - pbuffer->height = height; - pbuffer->mipmap_level = -1; - - for (; attribs && attribs[0]; attribs += 2) - { - switch (attribs[0]) - { - case WGL_PBUFFER_LARGEST_ARB: - TRACE( "WGL_PBUFFER_LARGEST_ARB %#x\n", attribs[1] ); - largest = !!attribs[1]; - break; - - case WGL_TEXTURE_FORMAT_ARB: - TRACE( "WGL_TEXTURE_FORMAT_ARB %#x\n", attribs[1] ); - switch (attribs[1]) - { - case WGL_NO_TEXTURE_ARB: - pbuffer->texture_format = 0; - break; - case WGL_TEXTURE_RGB_ARB: - pbuffer->texture_format = GL_RGB; - break; - case WGL_TEXTURE_RGBA_ARB: - pbuffer->texture_format = GL_RGBA; - break; - /* WGL_FLOAT_COMPONENTS_NV */ - case WGL_TEXTURE_FLOAT_R_NV: - pbuffer->texture_format = GL_FLOAT_R_NV; - break; - case WGL_TEXTURE_FLOAT_RG_NV: - pbuffer->texture_format = GL_FLOAT_RG_NV; - break; - case WGL_TEXTURE_FLOAT_RGB_NV: - pbuffer->texture_format = GL_FLOAT_RGB_NV; - break; - case WGL_TEXTURE_FLOAT_RGBA_NV: - pbuffer->texture_format = GL_FLOAT_RGBA_NV; - break; - default: - FIXME( "Unknown texture format: %x\n", attribs[1] ); - goto failed; - } - break; - - case WGL_TEXTURE_TARGET_ARB: - TRACE( "WGL_TEXTURE_TARGET_ARB %#x\n", attribs[1] ); - switch (attribs[1]) - { - case WGL_NO_TEXTURE_ARB: - pbuffer->texture_target = 0; - break; - case WGL_TEXTURE_CUBE_MAP_ARB: - if (width != height) goto failed; - pbuffer->texture_target = GL_TEXTURE_CUBE_MAP; - break; - case WGL_TEXTURE_1D_ARB: - if (height != 1) goto failed; - pbuffer->texture_target = GL_TEXTURE_1D; - break; - case WGL_TEXTURE_2D_ARB: - pbuffer->texture_target = GL_TEXTURE_2D; - break; - case WGL_TEXTURE_RECTANGLE_NV: - pbuffer->texture_target = GL_TEXTURE_RECTANGLE_NV; - break; - default: - FIXME( "Unknown texture target: %x\n", attribs[1] ); - goto failed; - } - break; - - case WGL_MIPMAP_TEXTURE_ARB: - TRACE( "WGL_MIPMAP_TEXTURE_ARB %#x\n", attribs[1] ); - if (attribs[1]) - { - pbuffer->mipmap_level = max_level = 0; - for (size = min( width, height ) / 2; size; size /= 2) max_level++; - } - break; - - default: - WARN( "attribute %#x %#x not handled\n", attribs[0], attribs[1] ); - break; - } - } - - if (driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, - pbuffer->texture_target, max_level, &pbuffer->width, - &pbuffer->height, &pbuffer->drawable )) - { - set_dc_opengl_drawable( pbuffer->hdc, pbuffer->drawable ); - return pbuffer; - } - -failed: - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - NtGdiDeleteObjectApp( pbuffer->hdc ); - free( pbuffer ); - return NULL; + return wgl_pbuffer_create( hdc, format, width, height, attribs ); } static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer ) { TRACE( "pbuffer %p\n", pbuffer ); - - opengl_drawable_release( pbuffer->drawable ); - NtGdiDeleteObjectApp( pbuffer->hdc ); - free( pbuffer ); - + wgl_pbuffer_destroy( pbuffer ); return GL_TRUE; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 31 ++++++++++++----------- include/wine/opengl_driver.h | 48 ++++++------------------------------ include/wine/wgl.h | 36 ++++++++++++++------------- 3 files changed, 43 insertions(+), 72 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index edb0c317292..1754ea4e971 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -416,13 +416,13 @@ sub get_func_trace($$$) sub get_func_args($$) { - my ($func, $convert_args) = @_; + my ($func, $unix) = @_; my $ret = ""; foreach my $arg (@{$func->[1]}) { my $ptype = get_arg_type( $arg ); my $pname = get_arg_name( $arg ); - $ret .= " " . ($convert_args ? ConvertType( $arg ) : $arg->textContent()) . ","; + $ret .= " " . ($unix ? ConvertType( $arg ) : $arg->textContent()) . ","; } $ret =~ s/,$/ /; $ret ||= "void"; @@ -431,8 +431,8 @@ sub get_func_args($$) sub get_func_ret($$) { - my ($func, $convert_args) = @_; - my $ret = $convert_args ? ConvertType( $func->[0] ) : $func->[0]->textContent(); + my ($func, $unix) = @_; + my $ret = $unix ? ConvertType( $func->[0] ) : $func->[0]->textContent(); $ret =~ s/ $//; return $ret; } @@ -1161,6 +1161,9 @@ print HEADER "#ifndef EGL_CAST\n"; print HEADER "#define EGL_CAST(t,x) ((t)(x))\n"; print HEADER "#endif\n\n"; +print HEADER "struct wgl_context;\n"; +print HEADER "struct wgl_pbuffer;\n"; + foreach (@gl_types) { my $type = $gl_types{$_}; @@ -1180,37 +1183,37 @@ print HEADER "\n"; print HEADER "#ifndef GL_NO_PROTOTYPES\n"; foreach (sort keys %norm_functions) { - my $decl_args = get_func_args( $norm_functions{$_}, 0 ); - my $func_ret = get_func_ret( $norm_functions{$_}, 0 ); + my $decl_args = get_func_args( $norm_functions{$_}, 1 ); + my $func_ret = get_func_ret( $norm_functions{$_}, 1 ); printf HEADER "%-10s GLAPIENTRY $_($decl_args);\n", $func_ret; } print HEADER "#endif\n\n"; foreach (sort keys %wgl_functions) { - my $decl_args = get_func_args( $wgl_functions{$_}, 0 ); - my $func_ret = get_func_ret( $wgl_functions{$_}, 0 ); + my $decl_args = get_func_args( $wgl_functions{$_}, 1 ); + my $func_ret = get_func_ret( $wgl_functions{$_}, 1 ); printf HEADER "typedef %-10s (GLAPIENTRY *PFN_$_)($decl_args);\n", $func_ret; } foreach (sort keys %egl_functions) { - my $decl_args = get_func_args( $egl_functions{$_}, 0 ); - my $func_ret = get_func_ret( $egl_functions{$_}, 0 ); + my $decl_args = get_func_args( $egl_functions{$_}, 1 ); + my $func_ret = get_func_ret( $egl_functions{$_}, 1 ); printf HEADER "typedef %-10s (GLAPIENTRY *PFN_$_)($decl_args);\n", $func_ret; } foreach (sort keys %norm_functions) { - my $decl_args = get_func_args( $norm_functions{$_}, 0 ); - my $func_ret = get_func_ret( $norm_functions{$_}, 0 ); + my $decl_args = get_func_args( $norm_functions{$_}, 1 ); + my $func_ret = get_func_ret( $norm_functions{$_}, 1 ); printf HEADER "typedef %-10s (GLAPIENTRY *PFN_$_)($decl_args);\n", $func_ret; } foreach (sort keys %ext_functions) { - my $decl_args = get_func_args( $ext_functions{$_}, 0 ); - my $func_ret = get_func_ret( $ext_functions{$_}, 0 ); + my $decl_args = get_func_args( $ext_functions{$_}, 1 ); + my $func_ret = get_func_ret( $ext_functions{$_}, 1 ); printf HEADER "typedef %-10s (GLAPIENTRY *PFN_$_)($decl_args);\n", $func_ret; } print HEADER "\n"; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 7ec2110fd35..d9f4da04953 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -67,8 +67,6 @@ struct wgl_pixel_format #define WINE_OPENGL_DRIVER_VERSION 37 struct opengl_drawable; -struct wgl_context; -struct wgl_pbuffer; struct wgl_context { @@ -83,52 +81,20 @@ struct wgl_context /* interface between opengl32 and win32u */ struct opengl_funcs { - BOOL (*p_query_renderer)( UINT attribute, void *value ); - BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); - BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void), UINT flags ); - BOOL (*p_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ); - struct wgl_context * (*p_wglCreateContext)( HDC hDc ); - BOOL (*p_wglDeleteContext)( struct wgl_context * oldContext ); - int (*p_wglGetPixelFormat)( HDC hdc ); - PROC (*p_wglGetProcAddress)( LPCSTR lpszProc ); - BOOL (*p_wglMakeCurrent)( HDC hDc, struct wgl_context * newContext ); - BOOL (*p_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); - BOOL (*p_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); - BOOL (*p_wglSwapBuffers)( HDC hdc ); - void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); - void * (*p_wglAllocateMemoryNV)( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); - BOOL (*p_wglBindTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); - BOOL (*p_wglChoosePixelFormatARB)( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); - struct wgl_context * (*p_wglCreateContextAttribsARB)( HDC hDC, struct wgl_context * hShareContext, const int *attribList ); - struct wgl_pbuffer * (*p_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); - BOOL (*p_wglDestroyPbufferARB)( struct wgl_pbuffer * hPbuffer ); - void (*p_wglFreeMemoryNV)( void *pointer ); - HDC (*p_wglGetCurrentReadDCARB)(void); - const char * (*p_wglGetExtensionsStringARB)( HDC hdc ); - const char * (*p_wglGetExtensionsStringEXT)(void); - HDC (*p_wglGetPbufferDCARB)( struct wgl_pbuffer * hPbuffer ); - BOOL (*p_wglGetPixelFormatAttribfvARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues ); - BOOL (*p_wglGetPixelFormatAttribivARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues ); - int (*p_wglGetSwapIntervalEXT)(void); - BOOL (*p_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, struct wgl_context * hglrc ); - BOOL (*p_wglQueryCurrentRendererIntegerWINE)( GLenum attribute, GLuint *value ); - const GLchar * (*p_wglQueryCurrentRendererStringWINE)( GLenum attribute ); - BOOL (*p_wglQueryPbufferARB)( struct wgl_pbuffer * hPbuffer, int iAttribute, int *piValue ); - BOOL (*p_wglQueryRendererIntegerWINE)( HDC dc, GLint renderer, GLenum attribute, GLuint *value ); - const GLchar * (*p_wglQueryRendererStringWINE)( HDC dc, GLint renderer, GLenum attribute ); - int (*p_wglReleasePbufferDCARB)( struct wgl_pbuffer * hPbuffer, HDC hDC ); - BOOL (*p_wglReleaseTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); - BOOL (*p_wglSetPbufferAttribARB)( struct wgl_pbuffer * hPbuffer, const int *piAttribList ); - BOOL (*p_wglSetPixelFormatWINE)( HDC hdc, int format ); - BOOL (*p_wglSwapIntervalEXT)( int interval ); #define USE_GL_FUNC(x) PFN_##x p_##x; + ALL_WGL_FUNCS + ALL_WGL_EXT_FUNCS ALL_EGL_FUNCS ALL_EGL_EXT_FUNCS ALL_GL_FUNCS ALL_GL_EXT_FUNCS #undef USE_GL_FUNC + void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); + BOOL (*p_query_renderer)( UINT attribute, void *value ); + BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void), UINT flags ); + BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); - void *egl_handle; + void *egl_handle; }; struct egl_platform diff --git a/include/wine/wgl.h b/include/wine/wgl.h index c9fbfdef254..a611ed25cff 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -24,6 +24,8 @@ #define EGL_CAST(t,x) ((t)(x)) #endif +struct wgl_context; +struct wgl_pbuffer; typedef void *EGLNativeDisplayType; typedef void *EGLNativePixmapType; typedef void *EGLNativeWindowType; @@ -6283,23 +6285,23 @@ void GLAPIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei heigh #endif typedef int (GLAPIENTRY *PFN_wglChoosePixelFormat)( HDC hDc, const PIXELFORMATDESCRIPTOR *pPfd ); -typedef BOOL (GLAPIENTRY *PFN_wglCopyContext)( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ); -typedef HGLRC (GLAPIENTRY *PFN_wglCreateContext)( HDC hDc ); -typedef HGLRC (GLAPIENTRY *PFN_wglCreateLayerContext)( HDC hDc, int level ); -typedef BOOL (GLAPIENTRY *PFN_wglDeleteContext)( HGLRC oldContext ); +typedef BOOL (GLAPIENTRY *PFN_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ); +typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateContext)( HDC hDc ); +typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateLayerContext)( HDC hDc, int level ); +typedef BOOL (GLAPIENTRY *PFN_wglDeleteContext)( struct wgl_context * oldContext ); typedef BOOL (GLAPIENTRY *PFN_wglDescribeLayerPlane)( HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, LAYERPLANEDESCRIPTOR *plpd ); typedef int (GLAPIENTRY *PFN_wglDescribePixelFormat)( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ); -typedef HGLRC (GLAPIENTRY *PFN_wglGetCurrentContext)(void); +typedef struct wgl_context * (GLAPIENTRY *PFN_wglGetCurrentContext)(void); typedef HDC (GLAPIENTRY *PFN_wglGetCurrentDC)(void); typedef PROC (GLAPIENTRY *PFN_wglGetDefaultProcAddress)( LPCSTR lpszProc ); typedef int (GLAPIENTRY *PFN_wglGetLayerPaletteEntries)( HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr ); typedef int (GLAPIENTRY *PFN_wglGetPixelFormat)( HDC hdc ); typedef PROC (GLAPIENTRY *PFN_wglGetProcAddress)( LPCSTR lpszProc ); -typedef BOOL (GLAPIENTRY *PFN_wglMakeCurrent)( HDC hDc, HGLRC newContext ); +typedef BOOL (GLAPIENTRY *PFN_wglMakeCurrent)( HDC hDc, struct wgl_context * newContext ); typedef BOOL (GLAPIENTRY *PFN_wglRealizeLayerPalette)( HDC hdc, int iLayerPlane, BOOL bRealize ); typedef int (GLAPIENTRY *PFN_wglSetLayerPaletteEntries)( HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr ); typedef BOOL (GLAPIENTRY *PFN_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); -typedef BOOL (GLAPIENTRY *PFN_wglShareLists)( HGLRC hrcSrvShare, HGLRC hrcSrvSource ); +typedef BOOL (GLAPIENTRY *PFN_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); typedef BOOL (GLAPIENTRY *PFN_wglSwapBuffers)( HDC hdc ); typedef BOOL (GLAPIENTRY *PFN_wglSwapLayerBuffers)( HDC hdc, UINT fuFlags ); typedef BOOL (GLAPIENTRY *PFN_wglUseFontBitmapsA)( HDC hDC, DWORD first, DWORD count, DWORD listBase ); @@ -9516,28 +9518,28 @@ typedef void (GLAPIENTRY *PFN_glWindowPos4svMESA)( const GLshort *v ); typedef void (GLAPIENTRY *PFN_glWindowRectanglesEXT)( GLenum mode, GLsizei count, const GLint *box ); typedef void (GLAPIENTRY *PFN_glWriteMaskEXT)( GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW ); typedef void * (GLAPIENTRY *PFN_wglAllocateMemoryNV)( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); -typedef BOOL (GLAPIENTRY *PFN_wglBindTexImageARB)( HPBUFFERARB hPbuffer, int iBuffer ); +typedef BOOL (GLAPIENTRY *PFN_wglBindTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); typedef BOOL (GLAPIENTRY *PFN_wglChoosePixelFormatARB)( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); -typedef HGLRC (GLAPIENTRY *PFN_wglCreateContextAttribsARB)( HDC hDC, HGLRC hShareContext, const int *attribList ); -typedef HPBUFFERARB (GLAPIENTRY *PFN_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); -typedef BOOL (GLAPIENTRY *PFN_wglDestroyPbufferARB)( HPBUFFERARB hPbuffer ); +typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateContextAttribsARB)( HDC hDC, struct wgl_context * hShareContext, const int *attribList ); +typedef struct wgl_pbuffer * (GLAPIENTRY *PFN_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); +typedef BOOL (GLAPIENTRY *PFN_wglDestroyPbufferARB)( struct wgl_pbuffer * hPbuffer ); typedef void (GLAPIENTRY *PFN_wglFreeMemoryNV)( void *pointer ); typedef HDC (GLAPIENTRY *PFN_wglGetCurrentReadDCARB)(void); typedef const char * (GLAPIENTRY *PFN_wglGetExtensionsStringARB)( HDC hdc ); typedef const char * (GLAPIENTRY *PFN_wglGetExtensionsStringEXT)(void); -typedef HDC (GLAPIENTRY *PFN_wglGetPbufferDCARB)( HPBUFFERARB hPbuffer ); +typedef HDC (GLAPIENTRY *PFN_wglGetPbufferDCARB)( struct wgl_pbuffer * hPbuffer ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribfvARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribivARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues ); typedef int (GLAPIENTRY *PFN_wglGetSwapIntervalEXT)(void); -typedef BOOL (GLAPIENTRY *PFN_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); +typedef BOOL (GLAPIENTRY *PFN_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, struct wgl_context * hglrc ); typedef BOOL (GLAPIENTRY *PFN_wglQueryCurrentRendererIntegerWINE)( GLenum attribute, GLuint *value ); typedef const GLchar * (GLAPIENTRY *PFN_wglQueryCurrentRendererStringWINE)( GLenum attribute ); -typedef BOOL (GLAPIENTRY *PFN_wglQueryPbufferARB)( HPBUFFERARB hPbuffer, int iAttribute, int *piValue ); +typedef BOOL (GLAPIENTRY *PFN_wglQueryPbufferARB)( struct wgl_pbuffer * hPbuffer, int iAttribute, int *piValue ); typedef BOOL (GLAPIENTRY *PFN_wglQueryRendererIntegerWINE)( HDC dc, GLint renderer, GLenum attribute, GLuint *value ); typedef const GLchar * (GLAPIENTRY *PFN_wglQueryRendererStringWINE)( HDC dc, GLint renderer, GLenum attribute ); -typedef int (GLAPIENTRY *PFN_wglReleasePbufferDCARB)( HPBUFFERARB hPbuffer, HDC hDC ); -typedef BOOL (GLAPIENTRY *PFN_wglReleaseTexImageARB)( HPBUFFERARB hPbuffer, int iBuffer ); -typedef BOOL (GLAPIENTRY *PFN_wglSetPbufferAttribARB)( HPBUFFERARB hPbuffer, const int *piAttribList ); +typedef int (GLAPIENTRY *PFN_wglReleasePbufferDCARB)( struct wgl_pbuffer * hPbuffer, HDC hDC ); +typedef BOOL (GLAPIENTRY *PFN_wglReleaseTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); +typedef BOOL (GLAPIENTRY *PFN_wglSetPbufferAttribARB)( struct wgl_pbuffer * hPbuffer, const int *piAttribList ); typedef BOOL (GLAPIENTRY *PFN_wglSetPixelFormatWINE)( HDC hdc, int format ); typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 44 ++++++++--- dlls/opengl32/private.h | 2 + dlls/opengl32/thunks.c | 38 ++++----- dlls/opengl32/unix_private.h | 6 ++ dlls/opengl32/unix_thunks.c | 100 +++++++++++------------- dlls/opengl32/unix_thunks.h | 8 -- dlls/opengl32/unix_wgl.c | 83 -------------------- dlls/opengl32/wgl.c | 147 +++++++++++++++++++++++++++++++++++ dlls/win32u/opengl.c | 67 +++++++++++----- include/wine/opengl_driver.h | 12 +++ include/wine/wgl.h | 17 ++-- 11 files changed, 315 insertions(+), 209 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 1754ea4e971..e592a97b7d5 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -129,7 +129,6 @@ my %arg_types = my %remap_types = ( "HGLRC" => "struct wgl_context *", - "HPBUFFERARB" => "struct wgl_pbuffer *", ); my %khronos_types = @@ -174,6 +173,8 @@ my %manual_win_thunks = "glGetString" => 1, "glGetStringi" => 1, "wglChoosePixelFormatARB" => 1, + "wglCreatePbufferARB" => 1, + "wglDestroyPbufferARB" => 1, "wglGetExtensionsStringARB" => 1, "wglGetExtensionsStringEXT" => 1, "wglGetPixelFormat" => 1, @@ -424,6 +425,7 @@ sub get_func_args($$) my $pname = get_arg_name( $arg ); $ret .= " " . ($unix ? ConvertType( $arg ) : $arg->textContent()) . ","; } + $ret .= " HPBUFFERARB client_pbuffer," if $unix && $func->[0] =~ /HPBUFFERARB/; $ret =~ s/,$/ /; $ret ||= "void"; return $ret; @@ -443,13 +445,14 @@ sub generate_unix_thunk($$$$) my $func_ret = get_func_ret( $func, 0 ); my $manual_wow64_wrapper = $is_wow64 && defined $manual_wow64_wrappers{$name}; my $need_wrap = $manual_wow64_wrapper || needs_wrapper( $name, $func ); - my $need_lock = $func_ret =~ /HGLRC|HPBUFFERARB/; + my $need_lock = $func_ret =~ /HGLRC/; my $need_funcs = !$need_wrap || ($prefix eq "ext" && $name !~ /^wgl/); my $teb = $is_wow64 ? "teb" : "params->teb"; my $ret_stat = "return STATUS_SUCCESS;"; my $invalidation = ""; my $input_conv = ""; my $output_conv = ""; + my $use_pbuffer = 0; my $call_args = ""; my $ret_expr = ""; my $use_dc = 0; @@ -458,7 +461,7 @@ sub generate_unix_thunk($$$$) foreach my $arg (@{$func->[1]}) { - $need_lock = 1 if $arg->textContent() =~ /HGLRC|HPBUFFERARB/; + $need_lock = 1 if $arg->textContent() =~ /HGLRC/; } $ret .= "static NTSTATUS "; @@ -468,6 +471,7 @@ sub generate_unix_thunk($$$$) # special case for functions that take an HDC as first parameter $use_dc = @{$func->[1]} && get_arg_type( ${$func->[1]}[0] ) eq "HDC" && $name !~ /wglMake(Context)?Current/; + $use_pbuffer = @{$func->[1]} && get_arg_type( ${$func->[1]}[0] ) eq "HPBUFFERARB"; $ret_expr = "params->ret = " if !is_void_func( $func ); $call_args .= " $teb," if $need_wrap; @@ -520,6 +524,7 @@ sub generate_unix_thunk($$$$) $need_lock = 1 if $arg_type =~ /GLsync/; } } + $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB/; if (!is_void_func($func)) { my $ret_type = get_arg_type( $func->[0] ); @@ -534,7 +539,7 @@ sub generate_unix_thunk($$$$) elsif ($ptype eq "PTR32") { $ret_expr .= "(UINT_PTR)"; - $need_manual_thunk = 1; + $need_manual_thunk = 1 if $func_ret !~ /HDC|HPBUFFERARB/; } } $ret .= " } *params = args;\n"; @@ -555,7 +560,7 @@ sub generate_unix_thunk($$$$) : " buffer = invalidate_buffer_target( $teb, params->target );\n"; $output_conv .= " if (buffer) free_buffer( funcs, buffer );\n"; } - $ret .= " TEB *teb = get_teb64( params->teb );\n" if $need_wrap || !$use_dc; + $ret .= " TEB *teb = get_teb64( params->teb );\n" if $need_wrap || (!$use_dc && !$use_pbuffer); } else { @@ -572,14 +577,17 @@ sub generate_unix_thunk($$$$) $call_args .= " params->$pname,"; } } + $call_args .= " params->ret," if $func_ret =~ /HPBUFFERARB/; $ret .= " struct $name\_params *params = args;\n"; } $ret .= $vars; - if ($use_dc) + if ($use_dc || $use_pbuffer) { my $param = "params->" . get_arg_name( ${$func->[1]}[0] ); $param = "ULongToPtr($param)" if $is_wow64; - $ret .= " const struct opengl_funcs *funcs = get_dc_funcs( $param );\n"; + $ret .= " const struct opengl_funcs *funcs = "; + $ret .= "get_dc_funcs( $param );\n" if $use_dc; + $ret .= "get_pbuffer_funcs( $param );\n" if $use_pbuffer; $ret .= " if (!funcs || !funcs->p_$name) return STATUS_NOT_IMPLEMENTED;\n"; } elsif ($need_funcs) @@ -661,17 +669,26 @@ sub generate_wrapper_declaration($$$) } $ret .= " " . $arg->textContent() . ","; } + $ret .= " HPBUFFERARB handle," if $ret_type =~ /HPBUFFERARB/; $ret =~ s/,$/ /; $ret .= ");\n"; return $ret; } +sub get_handle_function($) +{ + my $ptype = shift; + return "get_pbuffer_from_handle" if $ptype =~ /HPBUFFERARB/; + return 0; +} + sub generate_win_thunk($$) { my ($name, $func) = @_; my $decl_args = get_func_args( $func, 0 ); my $func_ret = get_func_ret( $func, 0 ); my $params = ""; + my $checks = ""; my $ret = ""; $ret .= "$func_ret WINAPI $name($decl_args)\n"; @@ -681,12 +698,22 @@ sub generate_win_thunk($$) foreach my $arg (@{$func->[1]}) { my $pname = get_arg_name( $arg ); - $params .= ", .$pname = $pname"; + my $ptype = get_arg_type( $arg ); + if (my $get_handle = get_handle_function( $ptype )) + { + my $retval = is_void_func($func) ? "return;" : "return 0;"; + $checks .= " if (!$get_handle( $pname, &args.$pname )) $retval\n"; + } + else + { + $params .= ", .$pname = $pname"; + } } $ret .= " = {$params }"; $ret .= ";\n"; $ret .= " NTSTATUS status;\n"; $ret .= " " . get_func_trace( $name, $func, 1 ) if $gen_traces; + $ret .= $checks; $ret .= " if ((status = UNIX_CALL( $name, &args ))) WARN( \"$name returned %#lx\\n\", status );\n"; $ret .= " return args.ret;\n" unless is_void_func($func); $ret .= "}\n"; @@ -1162,7 +1189,6 @@ print HEADER "#define EGL_CAST(t,x) ((t)(x))\n"; print HEADER "#endif\n\n"; print HEADER "struct wgl_context;\n"; -print HEADER "struct wgl_pbuffer;\n"; foreach (@gl_types) { diff --git a/dlls/opengl32/private.h b/dlls/opengl32/private.h index f40b6a2ba9a..3a1dc0cd433 100644 --- a/dlls/opengl32/private.h +++ b/dlls/opengl32/private.h @@ -27,9 +27,11 @@ #include "winbase.h" #include "winternl.h" #include "wingdi.h" +#include "wine/wgl.h" extern const void *extension_procs[]; extern int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ); +extern BOOL get_pbuffer_from_handle( HPBUFFERARB handle, HPBUFFERARB *obj ); #endif /* __WINE_OPENGL32_PRIVATE_H */ diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index fabe1da516b..bbf1070feab 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -24735,9 +24735,10 @@ static void * WINAPI wglAllocateMemoryNV( GLsizei size, GLfloat readfreq, GLfloa static BOOL WINAPI wglBindTexImageARB( HPBUFFERARB hPbuffer, int iBuffer ) { - struct wglBindTexImageARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer, .iBuffer = iBuffer }; + struct wglBindTexImageARB_params args = { .teb = NtCurrentTeb(), .iBuffer = iBuffer }; NTSTATUS status; TRACE( "hPbuffer %p, iBuffer %d\n", hPbuffer, iBuffer ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglBindTexImageARB, &args ))) WARN( "wglBindTexImageARB returned %#lx\n", status ); return args.ret; } @@ -24751,24 +24752,6 @@ static HGLRC WINAPI wglCreateContextAttribsARB( HDC hDC, HGLRC hShareContext, co return args.ret; } -static HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ) -{ - struct wglCreatePbufferARB_params args = { .teb = NtCurrentTeb(), .hDC = hDC, .iPixelFormat = iPixelFormat, .iWidth = iWidth, .iHeight = iHeight, .piAttribList = piAttribList }; - NTSTATUS status; - TRACE( "hDC %p, iPixelFormat %d, iWidth %d, iHeight %d, piAttribList %p\n", hDC, iPixelFormat, iWidth, iHeight, piAttribList ); - if ((status = UNIX_CALL( wglCreatePbufferARB, &args ))) WARN( "wglCreatePbufferARB returned %#lx\n", status ); - return args.ret; -} - -static BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB hPbuffer ) -{ - struct wglDestroyPbufferARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer }; - NTSTATUS status; - TRACE( "hPbuffer %p\n", hPbuffer ); - if ((status = UNIX_CALL( wglDestroyPbufferARB, &args ))) WARN( "wglDestroyPbufferARB returned %#lx\n", status ); - return args.ret; -} - static void WINAPI wglFreeMemoryNV( void *pointer ) { struct wglFreeMemoryNV_params args = { .teb = NtCurrentTeb(), .pointer = pointer }; @@ -24779,9 +24762,10 @@ static void WINAPI wglFreeMemoryNV( void *pointer ) static HDC WINAPI wglGetPbufferDCARB( HPBUFFERARB hPbuffer ) { - struct wglGetPbufferDCARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer }; + struct wglGetPbufferDCARB_params args = { .teb = NtCurrentTeb() }; NTSTATUS status; TRACE( "hPbuffer %p\n", hPbuffer ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglGetPbufferDCARB, &args ))) WARN( "wglGetPbufferDCARB returned %#lx\n", status ); return args.ret; } @@ -24815,9 +24799,10 @@ static BOOL WINAPI wglQueryCurrentRendererIntegerWINE( GLenum attribute, GLuint static BOOL WINAPI wglQueryPbufferARB( HPBUFFERARB hPbuffer, int iAttribute, int *piValue ) { - struct wglQueryPbufferARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer, .iAttribute = iAttribute, .piValue = piValue }; + struct wglQueryPbufferARB_params args = { .teb = NtCurrentTeb(), .iAttribute = iAttribute, .piValue = piValue }; NTSTATUS status; TRACE( "hPbuffer %p, iAttribute %d, piValue %p\n", hPbuffer, iAttribute, piValue ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglQueryPbufferARB, &args ))) WARN( "wglQueryPbufferARB returned %#lx\n", status ); return args.ret; } @@ -24833,27 +24818,30 @@ static BOOL WINAPI wglQueryRendererIntegerWINE( HDC dc, GLint renderer, GLenum a static int WINAPI wglReleasePbufferDCARB( HPBUFFERARB hPbuffer, HDC hDC ) { - struct wglReleasePbufferDCARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer, .hDC = hDC }; + struct wglReleasePbufferDCARB_params args = { .teb = NtCurrentTeb(), .hDC = hDC }; NTSTATUS status; TRACE( "hPbuffer %p, hDC %p\n", hPbuffer, hDC ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglReleasePbufferDCARB, &args ))) WARN( "wglReleasePbufferDCARB returned %#lx\n", status ); return args.ret; } static BOOL WINAPI wglReleaseTexImageARB( HPBUFFERARB hPbuffer, int iBuffer ) { - struct wglReleaseTexImageARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer, .iBuffer = iBuffer }; + struct wglReleaseTexImageARB_params args = { .teb = NtCurrentTeb(), .iBuffer = iBuffer }; NTSTATUS status; TRACE( "hPbuffer %p, iBuffer %d\n", hPbuffer, iBuffer ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglReleaseTexImageARB, &args ))) WARN( "wglReleaseTexImageARB returned %#lx\n", status ); return args.ret; } static BOOL WINAPI wglSetPbufferAttribARB( HPBUFFERARB hPbuffer, const int *piAttribList ) { - struct wglSetPbufferAttribARB_params args = { .teb = NtCurrentTeb(), .hPbuffer = hPbuffer, .piAttribList = piAttribList }; + struct wglSetPbufferAttribARB_params args = { .teb = NtCurrentTeb(), .piAttribList = piAttribList }; NTSTATUS status; TRACE( "hPbuffer %p, piAttribList %p\n", hPbuffer, piAttribList ); + if (!get_pbuffer_from_handle( hPbuffer, &args.hPbuffer )) return 0; if ((status = UNIX_CALL( wglSetPbufferAttribARB, &args ))) WARN( "wglSetPbufferAttribARB returned %#lx\n", status ); return args.ret; } @@ -24878,6 +24866,8 @@ static BOOL WINAPI wglSwapIntervalEXT( int interval ) extern const GLubyte * WINAPI glGetStringi( GLenum name, GLuint index ); extern BOOL WINAPI wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); +extern HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); +extern BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB hPbuffer ); extern HDC WINAPI wglGetCurrentReadDCARB(void); extern const char * WINAPI wglGetExtensionsStringARB( HDC hdc ); extern const char * WINAPI wglGetExtensionsStringEXT(void); diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index ffae783ead2..a42445a0983 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -57,6 +57,12 @@ static inline const struct opengl_funcs *get_dc_funcs( HDC hdc ) return &null_opengl_funcs; } +static inline const struct opengl_funcs *get_pbuffer_funcs( HPBUFFERARB client_pbuffer ) +{ + struct opengl_client_pbuffer *client = opengl_client_pbuffer_from_client( client_pbuffer ); + return client_pbuffer ? (struct opengl_funcs *)(UINT_PTR)client->unix_funcs : NULL; +} + #ifdef _WIN64 static inline void *copy_wow64_ptr32s( UINT_PTR address, ULONG count ) diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 5461b8e42a4..5ef8612bb9a 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -30299,9 +30299,9 @@ static NTSTATUS ext_wglAllocateMemoryNV( void *args ) static NTSTATUS ext_wglBindTexImageARB( void *args ) { struct wglBindTexImageARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglBindTexImageARB( params->teb, params->hPbuffer, params->iBuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglBindTexImageARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglBindTexImageARB( params->hPbuffer, params->iBuffer ); return STATUS_SUCCESS; } @@ -30330,18 +30330,16 @@ static NTSTATUS ext_wglCreatePbufferARB( void *args ) struct wglCreatePbufferARB_params *params = args; const struct opengl_funcs *funcs = get_dc_funcs( params->hDC ); if (!funcs || !funcs->p_wglCreatePbufferARB) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglCreatePbufferARB( params->teb, params->hDC, params->iPixelFormat, params->iWidth, params->iHeight, params->piAttribList ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = funcs->p_wglCreatePbufferARB( params->hDC, params->iPixelFormat, params->iWidth, params->iHeight, params->piAttribList, params->ret ); return STATUS_SUCCESS; } static NTSTATUS ext_wglDestroyPbufferARB( void *args ) { struct wglDestroyPbufferARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglDestroyPbufferARB( params->teb, params->hPbuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglDestroyPbufferARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglDestroyPbufferARB( params->hPbuffer ); return STATUS_SUCCESS; } @@ -30375,9 +30373,9 @@ static NTSTATUS ext_wglGetExtensionsStringEXT( void *args ) static NTSTATUS ext_wglGetPbufferDCARB( void *args ) { struct wglGetPbufferDCARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglGetPbufferDCARB( params->teb, params->hPbuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglGetPbufferDCARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglGetPbufferDCARB( params->hPbuffer ); return STATUS_SUCCESS; } @@ -30438,9 +30436,9 @@ static NTSTATUS ext_wglQueryCurrentRendererStringWINE( void *args ) static NTSTATUS ext_wglQueryPbufferARB( void *args ) { struct wglQueryPbufferARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglQueryPbufferARB( params->teb, params->hPbuffer, params->iAttribute, params->piValue ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglQueryPbufferARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglQueryPbufferARB( params->hPbuffer, params->iAttribute, params->piValue ); return STATUS_SUCCESS; } @@ -30465,27 +30463,27 @@ static NTSTATUS ext_wglQueryRendererStringWINE( void *args ) static NTSTATUS ext_wglReleasePbufferDCARB( void *args ) { struct wglReleasePbufferDCARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglReleasePbufferDCARB( params->teb, params->hPbuffer, params->hDC ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglReleasePbufferDCARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglReleasePbufferDCARB( params->hPbuffer, params->hDC ); return STATUS_SUCCESS; } static NTSTATUS ext_wglReleaseTexImageARB( void *args ) { struct wglReleaseTexImageARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglReleaseTexImageARB( params->teb, params->hPbuffer, params->iBuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglReleaseTexImageARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglReleaseTexImageARB( params->hPbuffer, params->iBuffer ); return STATUS_SUCCESS; } static NTSTATUS ext_wglSetPbufferAttribARB( void *args ) { struct wglSetPbufferAttribARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglSetPbufferAttribARB( params->teb, params->hPbuffer, params->piAttribList ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( params->hPbuffer ); + if (!funcs || !funcs->p_wglSetPbufferAttribARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglSetPbufferAttribARB( params->hPbuffer, params->piAttribList ); return STATUS_SUCCESS; } @@ -86491,10 +86489,9 @@ static NTSTATUS wow64_ext_wglBindTexImageARB( void *args ) int iBuffer; BOOL ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglBindTexImageARB( teb, ULongToPtr(params->hPbuffer), params->iBuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglBindTexImageARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglBindTexImageARB( ULongToPtr(params->hPbuffer), params->iBuffer ); return STATUS_SUCCESS; } @@ -86548,12 +86545,9 @@ static NTSTATUS wow64_ext_wglCreatePbufferARB( void *args ) PTR32 piAttribList; PTR32 ret; } *params = args; - TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = get_dc_funcs( ULongToPtr(params->hDC) ); if (!funcs || !funcs->p_wglCreatePbufferARB) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = (UINT_PTR)wrap_wglCreatePbufferARB( teb, ULongToPtr(params->hDC), params->iPixelFormat, params->iWidth, params->iHeight, ULongToPtr(params->piAttribList) ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = (UINT_PTR)funcs->p_wglCreatePbufferARB( ULongToPtr(params->hDC), params->iPixelFormat, params->iWidth, params->iHeight, ULongToPtr(params->piAttribList), UlongToHandle( params->ret ) ); return STATUS_SUCCESS; } @@ -86565,10 +86559,9 @@ static NTSTATUS wow64_ext_wglDestroyPbufferARB( void *args ) PTR32 hPbuffer; BOOL ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglDestroyPbufferARB( teb, ULongToPtr(params->hPbuffer) ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglDestroyPbufferARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglDestroyPbufferARB( ULongToPtr(params->hPbuffer) ); return STATUS_SUCCESS; } @@ -86624,10 +86617,9 @@ static NTSTATUS wow64_ext_wglGetPbufferDCARB( void *args ) PTR32 hPbuffer; PTR32 ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = (UINT_PTR)wrap_wglGetPbufferDCARB( teb, ULongToPtr(params->hPbuffer) ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglGetPbufferDCARB) return STATUS_NOT_IMPLEMENTED; + params->ret = (UINT_PTR)funcs->p_wglGetPbufferDCARB( ULongToPtr(params->hPbuffer) ); return STATUS_SUCCESS; } @@ -86742,10 +86734,9 @@ static NTSTATUS wow64_ext_wglQueryPbufferARB( void *args ) PTR32 piValue; BOOL ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglQueryPbufferARB( teb, ULongToPtr(params->hPbuffer), params->iAttribute, ULongToPtr(params->piValue) ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglQueryPbufferARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglQueryPbufferARB( ULongToPtr(params->hPbuffer), params->iAttribute, ULongToPtr(params->piValue) ); return STATUS_SUCCESS; } @@ -86792,10 +86783,9 @@ static NTSTATUS wow64_ext_wglReleasePbufferDCARB( void *args ) PTR32 hDC; int ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglReleasePbufferDCARB( teb, ULongToPtr(params->hPbuffer), ULongToPtr(params->hDC) ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglReleasePbufferDCARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglReleasePbufferDCARB( ULongToPtr(params->hPbuffer), ULongToPtr(params->hDC) ); return STATUS_SUCCESS; } @@ -86808,10 +86798,9 @@ static NTSTATUS wow64_ext_wglReleaseTexImageARB( void *args ) int iBuffer; BOOL ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglReleaseTexImageARB( teb, ULongToPtr(params->hPbuffer), params->iBuffer ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglReleaseTexImageARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglReleaseTexImageARB( ULongToPtr(params->hPbuffer), params->iBuffer ); return STATUS_SUCCESS; } @@ -86824,10 +86813,9 @@ static NTSTATUS wow64_ext_wglSetPbufferAttribARB( void *args ) PTR32 piAttribList; BOOL ret; } *params = args; - TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglSetPbufferAttribARB( teb, ULongToPtr(params->hPbuffer), ULongToPtr(params->piAttribList) ); - pthread_mutex_unlock( &wgl_lock ); + const struct opengl_funcs *funcs = get_pbuffer_funcs( ULongToPtr(params->hPbuffer) ); + if (!funcs || !funcs->p_wglSetPbufferAttribARB) return STATUS_NOT_IMPLEMENTED; + params->ret = funcs->p_wglSetPbufferAttribARB( ULongToPtr(params->hPbuffer), ULongToPtr(params->piAttribList) ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index 99ecd2ae6d6..2d42d73de03 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -37,16 +37,8 @@ extern void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ); extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); -extern BOOL wrap_wglBindTexImageARB( TEB *teb, HPBUFFERARB hPbuffer, int iBuffer ); extern HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hDC, HGLRC hShareContext, const int *attribList ); -extern HPBUFFERARB wrap_wglCreatePbufferARB( TEB *teb, HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); -extern BOOL wrap_wglDestroyPbufferARB( TEB *teb, HPBUFFERARB hPbuffer ); -extern HDC wrap_wglGetPbufferDCARB( TEB *teb, HPBUFFERARB hPbuffer ); extern BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); -extern BOOL wrap_wglQueryPbufferARB( TEB *teb, HPBUFFERARB hPbuffer, int iAttribute, int *piValue ); -extern int wrap_wglReleasePbufferDCARB( TEB *teb, HPBUFFERARB hPbuffer, HDC hDC ); -extern BOOL wrap_wglReleaseTexImageARB( TEB *teb, HPBUFFERARB hPbuffer, int iBuffer ); -extern BOOL wrap_wglSetPbufferAttribARB( TEB *teb, HPBUFFERARB hPbuffer, const int *piAttribList ); #ifdef _WIN64 extern void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLbitfield flags ); diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 4d98142a544..16ae78a963e 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -60,7 +60,6 @@ pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER; enum wgl_handle_type { - HANDLE_PBUFFER = 0 << 12, HANDLE_CONTEXT = 1 << 12, HANDLE_GLSYNC = 2 << 12, HANDLE_TYPE_MASK = 15 << 12, @@ -203,7 +202,6 @@ struct wgl_handle union { struct wgl_context *context; /* for HANDLE_CONTEXT */ - struct wgl_pbuffer *pbuffer; /* for HANDLE_PBUFFER */ GLsync sync; /* for HANDLE_GLSYNC */ struct wgl_handle *next; /* for free handles */ } u; @@ -458,14 +456,6 @@ static struct context *opengl_context_from_handle( TEB *teb, HGLRC handle, const return context_from_wgl_context( entry->u.context ); } -static struct wgl_pbuffer *wgl_pbuffer_from_handle( HPBUFFERARB handle, const struct opengl_funcs **funcs ) -{ - struct wgl_handle *entry; - if (!(entry = get_handle_ptr( handle ))) return NULL; - *funcs = entry->funcs; - return entry->u.pbuffer; -} - static HANDLE alloc_handle( enum wgl_handle_type type, const struct opengl_funcs *funcs, void *user_ptr ) { HANDLE handle = 0; @@ -1577,14 +1567,6 @@ BOOL wrap_wglShareLists( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst ) return ret; } -BOOL wrap_wglBindTexImageARB( TEB *teb, HPBUFFERARB handle, int buffer ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return FALSE; - return funcs->p_wglBindTexImageARB( pbuffer, buffer ); -} - HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int *attribs ) { HGLRC ret = 0; @@ -1640,39 +1622,6 @@ HGLRC wrap_wglCreateContext( TEB *teb, HDC hdc ) return wrap_wglCreateContextAttribsARB( teb, hdc, NULL, NULL ); } -HPBUFFERARB wrap_wglCreatePbufferARB( TEB *teb, HDC hdc, int format, int width, int height, const int *attribs ) -{ - HPBUFFERARB ret; - struct wgl_pbuffer *pbuffer; - const struct opengl_funcs *funcs = get_dc_funcs( hdc ); - - if (!funcs || !funcs->p_wglCreatePbufferARB) return 0; - if (!(pbuffer = funcs->p_wglCreatePbufferARB( hdc, format, width, height, attribs ))) return 0; - ret = alloc_handle( HANDLE_PBUFFER, funcs, pbuffer ); - if (!ret) funcs->p_wglDestroyPbufferARB( pbuffer ); - return ret; -} - -BOOL wrap_wglDestroyPbufferARB( TEB *teb, HPBUFFERARB handle ) -{ - struct wgl_pbuffer *pbuffer; - struct wgl_handle *ptr; - - if (!(ptr = get_handle_ptr( handle ))) return FALSE; - pbuffer = ptr->u.pbuffer; - ptr->funcs->p_wglDestroyPbufferARB( pbuffer ); - free_handle_ptr( ptr ); - return TRUE; -} - -HDC wrap_wglGetPbufferDCARB( TEB *teb, HPBUFFERARB handle ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return 0; - return funcs->p_wglGetPbufferDCARB( pbuffer ); -} - BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); @@ -1704,38 +1653,6 @@ BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC return TRUE; } -BOOL wrap_wglQueryPbufferARB( TEB *teb, HPBUFFERARB handle, int attrib, int *value ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return FALSE; - return funcs->p_wglQueryPbufferARB( pbuffer, attrib, value ); -} - -int wrap_wglReleasePbufferDCARB( TEB *teb, HPBUFFERARB handle, HDC hdc ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return FALSE; - return funcs->p_wglReleasePbufferDCARB( pbuffer, hdc ); -} - -BOOL wrap_wglReleaseTexImageARB( TEB *teb, HPBUFFERARB handle, int buffer ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return FALSE; - return funcs->p_wglReleaseTexImageARB( pbuffer, buffer ); -} - -BOOL wrap_wglSetPbufferAttribARB( TEB *teb, HPBUFFERARB handle, const int *attribs ) -{ - const struct opengl_funcs *funcs; - struct wgl_pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_from_handle( handle, &funcs ))) return FALSE; - return funcs->p_wglSetPbufferAttribARB( pbuffer, attribs ); -} - static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *user ) { diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index e18c5ee0563..40ebed8bebd 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -49,6 +49,15 @@ static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} }; #define WINE_GL_RESERVED_FORMATS_NUM 4 #define WINE_GL_RESERVED_FORMATS_ONSCREEN 5 +static CRITICAL_SECTION wgl_cs; +static CRITICAL_SECTION_DEBUG wgl_cs_debug = { + 0, 0, &wgl_cs, + { &wgl_cs_debug.ProcessLocksList, + &wgl_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": wgl_cs") } +}; +static CRITICAL_SECTION wgl_cs = { &wgl_cs_debug, -1, 0, 0, 0, 0 }; + #ifndef _WIN64 static char **wow64_strings; @@ -89,6 +98,144 @@ static void cleanup_wow64_strings(void) #endif +struct handle_entry +{ + UINT handle; + union + { + struct opengl_client_pbuffer *pbuffer; + struct handle_entry *next_free; + void *user_data; + }; +}; + +struct handle_table +{ + struct handle_entry handles[1024]; + struct handle_entry *next_free; + UINT count; +}; + +static struct handle_table pbuffers; + +static struct handle_entry *alloc_handle( struct handle_table *table, void *user_data ) +{ + struct handle_entry *ptr = NULL; + WORD generation; + + EnterCriticalSection( &wgl_cs ); + + if ((ptr = table->next_free)) table->next_free = ptr->next_free; + else if (table->count < ARRAY_SIZE(table->handles)) ptr = table->handles + table->count++; + else ptr = NULL; + + if (ptr) + { + if (!(generation = HIWORD( ptr->handle ) + 1)) generation++; + ptr->handle = MAKELONG( ptr - table->handles + 1, generation ); + ptr->user_data = user_data; + } + + LeaveCriticalSection( &wgl_cs ); + + if (!ptr) RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); + return ptr; +} + +static void free_handle( struct handle_table *table, struct handle_entry *ptr ) +{ + EnterCriticalSection( &wgl_cs ); + ptr->handle |= 0xffff; + ptr->next_free = table->next_free; + table->next_free = ptr; + LeaveCriticalSection( &wgl_cs ); +} + +static struct handle_entry *get_handle_ptr( struct handle_table *table, HANDLE handle ) +{ + WORD index = LOWORD( handle ) - 1; + struct handle_entry *ptr = table->handles + index; + + EnterCriticalSection( &wgl_cs ); + if (index >= table->count || ULongToHandle( ptr->handle ) != handle) ptr = NULL; + LeaveCriticalSection( &wgl_cs ); + + if (!ptr) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); + return ptr; +} + +static struct opengl_client_pbuffer *pbuffer_from_handle( HPBUFFERARB handle ) +{ + struct handle_entry *ptr; + if (!(ptr = get_handle_ptr( &pbuffers, handle ))) return NULL; + return ptr->pbuffer; +} + +BOOL get_pbuffer_from_handle( HPBUFFERARB handle, HPBUFFERARB *obj ) +{ + struct opengl_client_pbuffer *pbuffer = pbuffer_from_handle( handle ); + *obj = pbuffer ? &pbuffer->obj : NULL; + return pbuffer || !handle; +} + +static struct handle_entry *alloc_client_pbuffer(void) +{ + struct opengl_client_pbuffer *pbuffer; + struct handle_entry *ptr; + + if (!(pbuffer = calloc( 1, sizeof(*pbuffer) ))) return NULL; + if (!(ptr = alloc_handle( &pbuffers, pbuffer ))) + { + free( pbuffer ); + return NULL; + } + + return ptr; +} + +static void free_client_pbuffer( struct handle_entry *ptr ) +{ + struct opengl_client_pbuffer *pbuffer = ptr->pbuffer; + free_handle( &pbuffers, ptr ); + free( pbuffer ); +} + +HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs ) +{ + struct wglCreatePbufferARB_params args = { .teb = NtCurrentTeb(), .hDC = hdc, .iPixelFormat = format, .iWidth = width, .iHeight = height, .piAttribList = attribs }; + struct handle_entry *ptr; + NTSTATUS status; + + TRACE( "hdc %p, format %d, width %d, height %d, attribs %p\n", hdc, format, width, height, attribs ); + + if (!(ptr = alloc_client_pbuffer())) return 0; + args.ret = &ptr->pbuffer->obj; + + if ((status = UNIX_CALL( wglCreatePbufferARB, &args ))) WARN( "wglCreatePbufferARB returned %#lx\n", status ); + assert( args.ret == &ptr->pbuffer->obj || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_pbuffer( ptr ); + return NULL; +} + +BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle ) +{ + struct wglDestroyPbufferARB_params args = { .teb = NtCurrentTeb() }; + struct handle_entry *ptr; + NTSTATUS status; + + TRACE( "handle %p\n", handle ); + + if (!(ptr = get_handle_ptr( &pbuffers, handle ))) return FALSE; + args.hPbuffer = &ptr->pbuffer->obj; + + if ((status = UNIX_CALL( wglDestroyPbufferARB, &args ))) WARN( "wglDestroyPbufferARB returned %#lx\n", status ); + if (args.ret) free_client_pbuffer( ptr ); + + return args.ret; +} + /*********************************************************************** * wglGetCurrentReadDCARB * diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 320dc571b82..779c5bb2153 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -40,7 +40,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl); -struct wgl_pbuffer +struct pbuffer { struct opengl_drawable *drawable; @@ -53,6 +53,12 @@ struct wgl_pbuffer GLenum cube_face; }; +static struct pbuffer *pbuffer_from_client_pbuffer( HPBUFFERARB client_pbuffer ) +{ + struct opengl_client_pbuffer *client = opengl_client_pbuffer_from_client( client_pbuffer ); + return (struct pbuffer *)(UINT_PTR)client->unix_handle; +} + static const struct opengl_driver_funcs nulldrv_funcs, *driver_funcs = &nulldrv_funcs; static struct list devices_egl = LIST_INIT( devices_egl ); static struct egl_platform display_egl; @@ -1438,16 +1444,16 @@ static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc ) return drawable; } -static void wgl_pbuffer_destroy( struct wgl_pbuffer *pbuffer ) +static void pbuffer_destroy( struct pbuffer *pbuffer ) { opengl_drawable_release( pbuffer->drawable ); NtGdiDeleteObjectApp( pbuffer->hdc ); free( pbuffer ); } -static struct wgl_pbuffer *wgl_pbuffer_create( HDC hdc, int format, int width, int height, const int *attribs ) +static struct pbuffer *pbuffer_create( HDC hdc, int format, int width, int height, const int *attribs ) { - struct wgl_pbuffer *pbuffer; + struct pbuffer *pbuffer; UINT size, max_level = 0; BOOL largest = FALSE; @@ -1582,15 +1588,15 @@ static BOOL create_memory_pbuffer( HDC hdc ) if (ret) { int width = dib.rect.right - dib.rect.left, height = dib.rect.bottom - dib.rect.top; - struct wgl_pbuffer *pbuffer; + struct pbuffer *pbuffer; - if (!(pbuffer = wgl_pbuffer_create( hdc, format, width, height, NULL ))) + if (!(pbuffer = pbuffer_create( hdc, format, width, height, NULL ))) WARN( "Failed to create pbuffer for memory DC %p\n", hdc ); else { TRACE( "Created pbuffer %p for memory DC %p\n", pbuffer, hdc ); set_dc_opengl_drawable( hdc, pbuffer->drawable ); - wgl_pbuffer_destroy( pbuffer ); + pbuffer_destroy( pbuffer ); } } @@ -1929,10 +1935,18 @@ static BOOL win32u_wglMakeCurrent( HDC hdc, struct wgl_context *context ) return win32u_wglMakeContextCurrentARB( hdc, hdc, context ); } -static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int width, int height, - const int *attribs ) +static void opengl_client_pbuffer_init( HPBUFFERARB client_pbuffer, struct pbuffer *pbuffer, const struct opengl_funcs *funcs ) +{ + struct opengl_client_pbuffer *client = opengl_client_pbuffer_from_client( client_pbuffer ); + client->unix_handle = (UINT_PTR)pbuffer; + client->unix_funcs = (UINT_PTR)funcs; +} + +static HPBUFFERARB win32u_wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs, + HPBUFFERARB client_pbuffer ) { const struct opengl_funcs *funcs = &display_funcs; + struct pbuffer *pbuffer; UINT total, onscreen; TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs ); @@ -1941,32 +1955,38 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int if (format <= 0 || format > total) { RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); - return NULL; + return 0; } if (width <= 0 || height <= 0) { RtlSetLastWin32Error( ERROR_INVALID_DATA ); - return NULL; + return 0; } - return wgl_pbuffer_create( hdc, format, width, height, attribs ); + if (!(pbuffer = pbuffer_create( hdc, format, width, height, attribs ))) return 0; + opengl_client_pbuffer_init( client_pbuffer, pbuffer, funcs ); + return client_pbuffer; } -static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer ) +static BOOL win32u_wglDestroyPbufferARB( HPBUFFERARB client_pbuffer ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); TRACE( "pbuffer %p\n", pbuffer ); - wgl_pbuffer_destroy( pbuffer ); + pbuffer_destroy( pbuffer ); return GL_TRUE; } -static HDC win32u_wglGetPbufferDCARB( struct wgl_pbuffer *pbuffer ) +static HDC win32u_wglGetPbufferDCARB( HPBUFFERARB client_pbuffer ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); TRACE( "pbuffer %p\n", pbuffer ); return pbuffer->hdc; } -static int win32u_wglReleasePbufferDCARB( struct wgl_pbuffer *pbuffer, HDC hdc ) +static int win32u_wglReleasePbufferDCARB( HPBUFFERARB client_pbuffer, HDC hdc ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); + TRACE( "pbuffer %p, hdc %p\n", pbuffer, hdc ); if (hdc != pbuffer->hdc) @@ -1978,8 +1998,10 @@ static int win32u_wglReleasePbufferDCARB( struct wgl_pbuffer *pbuffer, HDC hdc ) return TRUE; } -static BOOL win32u_wglQueryPbufferARB( struct wgl_pbuffer *pbuffer, int attrib, int *value ) +static BOOL win32u_wglQueryPbufferARB( HPBUFFERARB client_pbuffer, int attrib, int *value ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); + TRACE( "pbuffer %p, attrib %#x, value %p\n", pbuffer, attrib, value ); switch (attrib) @@ -2072,9 +2094,10 @@ static GLenum binding_from_target( GLenum target ) return 0; } -static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) +static BOOL win32u_wglBindTexImageARB( HPBUFFERARB client_pbuffer, int buffer ) { const struct opengl_funcs *funcs = &display_funcs; + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); int prev_texture = 0, format = win32u_wglGetPixelFormat( pbuffer->hdc ); struct wgl_pixel_format desc; GLenum source; @@ -2147,8 +2170,10 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) return GL_TRUE; } -static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) +static BOOL win32u_wglReleaseTexImageARB( HPBUFFERARB client_pbuffer, int buffer ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); + TRACE( "pbuffer %p, buffer %d\n", pbuffer, buffer ); if (!pbuffer->texture_format) @@ -2160,8 +2185,10 @@ static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffe return !!driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->drawable, GL_NONE ); } -static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const int *attribs ) +static BOOL win32u_wglSetPbufferAttribARB( HPBUFFERARB client_pbuffer, const int *attribs ) { + struct pbuffer *pbuffer = pbuffer_from_client_pbuffer( client_pbuffer ); + TRACE( "pbuffer %p, attribs %p\n", pbuffer, attribs ); if (!pbuffer->texture_format) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index d9f4da04953..e545418258a 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -59,6 +59,18 @@ struct wgl_pixel_format int float_components; }; +struct opengl_client_pbuffer +{ + struct HPBUFFERARB__ obj; /* client object header */ + UINT64 unix_handle; + UINT64 unix_funcs; +}; + +static inline struct opengl_client_pbuffer *opengl_client_pbuffer_from_client( HPBUFFERARB client_pbuffer ) +{ + return CONTAINING_RECORD( client_pbuffer, struct opengl_client_pbuffer, obj ); +} + #ifdef WINE_UNIX_LIB #include "wine/gdi_driver.h" diff --git a/include/wine/wgl.h b/include/wine/wgl.h index a611ed25cff..90b7be366c4 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -25,7 +25,6 @@ #endif struct wgl_context; -struct wgl_pbuffer; typedef void *EGLNativeDisplayType; typedef void *EGLNativePixmapType; typedef void *EGLNativeWindowType; @@ -9518,28 +9517,28 @@ typedef void (GLAPIENTRY *PFN_glWindowPos4svMESA)( const GLshort *v ); typedef void (GLAPIENTRY *PFN_glWindowRectanglesEXT)( GLenum mode, GLsizei count, const GLint *box ); typedef void (GLAPIENTRY *PFN_glWriteMaskEXT)( GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW ); typedef void * (GLAPIENTRY *PFN_wglAllocateMemoryNV)( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); -typedef BOOL (GLAPIENTRY *PFN_wglBindTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); +typedef BOOL (GLAPIENTRY *PFN_wglBindTexImageARB)( HPBUFFERARB hPbuffer, int iBuffer ); typedef BOOL (GLAPIENTRY *PFN_wglChoosePixelFormatARB)( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateContextAttribsARB)( HDC hDC, struct wgl_context * hShareContext, const int *attribList ); -typedef struct wgl_pbuffer * (GLAPIENTRY *PFN_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); -typedef BOOL (GLAPIENTRY *PFN_wglDestroyPbufferARB)( struct wgl_pbuffer * hPbuffer ); +typedef HPBUFFERARB (GLAPIENTRY *PFN_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList, HPBUFFERARB client_pbuffer ); +typedef BOOL (GLAPIENTRY *PFN_wglDestroyPbufferARB)( HPBUFFERARB hPbuffer ); typedef void (GLAPIENTRY *PFN_wglFreeMemoryNV)( void *pointer ); typedef HDC (GLAPIENTRY *PFN_wglGetCurrentReadDCARB)(void); typedef const char * (GLAPIENTRY *PFN_wglGetExtensionsStringARB)( HDC hdc ); typedef const char * (GLAPIENTRY *PFN_wglGetExtensionsStringEXT)(void); -typedef HDC (GLAPIENTRY *PFN_wglGetPbufferDCARB)( struct wgl_pbuffer * hPbuffer ); +typedef HDC (GLAPIENTRY *PFN_wglGetPbufferDCARB)( HPBUFFERARB hPbuffer ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribfvARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribivARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues ); typedef int (GLAPIENTRY *PFN_wglGetSwapIntervalEXT)(void); typedef BOOL (GLAPIENTRY *PFN_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, struct wgl_context * hglrc ); typedef BOOL (GLAPIENTRY *PFN_wglQueryCurrentRendererIntegerWINE)( GLenum attribute, GLuint *value ); typedef const GLchar * (GLAPIENTRY *PFN_wglQueryCurrentRendererStringWINE)( GLenum attribute ); -typedef BOOL (GLAPIENTRY *PFN_wglQueryPbufferARB)( struct wgl_pbuffer * hPbuffer, int iAttribute, int *piValue ); +typedef BOOL (GLAPIENTRY *PFN_wglQueryPbufferARB)( HPBUFFERARB hPbuffer, int iAttribute, int *piValue ); typedef BOOL (GLAPIENTRY *PFN_wglQueryRendererIntegerWINE)( HDC dc, GLint renderer, GLenum attribute, GLuint *value ); typedef const GLchar * (GLAPIENTRY *PFN_wglQueryRendererStringWINE)( HDC dc, GLint renderer, GLenum attribute ); -typedef int (GLAPIENTRY *PFN_wglReleasePbufferDCARB)( struct wgl_pbuffer * hPbuffer, HDC hDC ); -typedef BOOL (GLAPIENTRY *PFN_wglReleaseTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer ); -typedef BOOL (GLAPIENTRY *PFN_wglSetPbufferAttribARB)( struct wgl_pbuffer * hPbuffer, const int *piAttribList ); +typedef int (GLAPIENTRY *PFN_wglReleasePbufferDCARB)( HPBUFFERARB hPbuffer, HDC hDC ); +typedef BOOL (GLAPIENTRY *PFN_wglReleaseTexImageARB)( HPBUFFERARB hPbuffer, int iBuffer ); +typedef BOOL (GLAPIENTRY *PFN_wglSetPbufferAttribARB)( HPBUFFERARB hPbuffer, const int *piAttribList ); typedef BOOL (GLAPIENTRY *PFN_wglSetPixelFormatWINE)( HDC hdc, int format ); typedef BOOL (GLAPIENTRY *PFN_wglSwapIntervalEXT)( int interval ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 52 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 16ae78a963e..acb71457bf5 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1583,36 +1583,40 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int RtlSetLastWin32Error( ERROR_INVALID_OPERATION ); return 0; } - if ((context = calloc( 1, sizeof(*context) ))) + if (!(context = calloc( 1, sizeof(*context) ))) { - context->hdc = hdc; - context->share = (HGLRC)-1; /* initial shared context */ - context->attribs = memdup_attribs( attribs ); - if (is_win64 && is_wow64()) + RtlSetLastWin32Error( ERROR_OUTOFMEMORY ); + return 0; + } + context->hdc = hdc; + context->share = (HGLRC)-1; /* initial shared context */ + context->attribs = memdup_attribs( attribs ); + + if (is_win64 && is_wow64()) + { + if (share_ctx) { - if (share_ctx) - { - context->buffers = share_ctx->buffers; - context->buffers->ref++; - } - else if (!(context->buffers = malloc( sizeof(*context->buffers )))) - { - free_context( context ); - return 0; - } - else - { - context->buffers->ref = 1; - context->buffers->vk_device = NULL; - rb_init( &context->buffers->map, compare_buffer_name ); - } + context->buffers = share_ctx->buffers; + context->buffers->ref++; } - if (!(funcs->p_wgl_context_reset( &context->base, hdc, share_ctx ? &share_ctx->base : NULL, attribs ))) free_context( context ); - else if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) + else if (!(context->buffers = malloc( sizeof(*context->buffers )))) { - funcs->p_wgl_context_reset( &context->base, NULL, NULL, NULL ); free_context( context ); + return 0; } + else + { + context->buffers->ref = 1; + context->buffers->vk_device = NULL; + rb_init( &context->buffers->map, compare_buffer_name ); + } + } + + if (!(funcs->p_wgl_context_reset( &context->base, hdc, share_ctx ? &share_ctx->base : NULL, attribs ))) free_context( context ); + else if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) + { + funcs->p_wgl_context_reset( &context->base, NULL, NULL, NULL ); + free_context( context ); } return ret; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 71 +++----- dlls/opengl32/private.h | 1 + dlls/opengl32/thunks.c | 55 +----- dlls/opengl32/unix_private.h | 6 + dlls/opengl32/unix_thunks.c | 58 +++--- dlls/opengl32/unix_thunks.h | 4 +- dlls/opengl32/unix_wgl.c | 334 ++++++++++++++++------------------- dlls/opengl32/wgl.c | 143 +++++++++++++++ dlls/win32u/opengl.c | 7 +- include/wine/opengl_driver.h | 31 +++- include/wine/wgl.h | 19 +- 11 files changed, 401 insertions(+), 328 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index e592a97b7d5..d71a715e008 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -126,11 +126,6 @@ my %arg_types = "FLOAT" => [ "float", "%f" ], ); -my %remap_types = - ( - "HGLRC" => "struct wgl_context *", - ); - my %khronos_types = ( "double" => "double DECLSPEC_ALIGN(8)", @@ -173,7 +168,10 @@ my %manual_win_thunks = "glGetString" => 1, "glGetStringi" => 1, "wglChoosePixelFormatARB" => 1, + "wglCreateContext" => 1, + "wglCreateContextAttribsARB" => 1, "wglCreatePbufferARB" => 1, + "wglDeleteContext" => 1, "wglDestroyPbufferARB" => 1, "wglGetExtensionsStringARB" => 1, "wglGetExtensionsStringEXT" => 1, @@ -181,6 +179,8 @@ my %manual_win_thunks = "wglGetPixelFormatAttribfvARB" => 1, "wglGetPixelFormatAttribivARB" => 1, "wglGetProcAddress" => 1, + "wglMakeContextCurrentARB" => 1, + "wglMakeCurrent" => 1, "wglQueryCurrentRendererStringWINE" => 1, "wglQueryRendererStringWINE" => 1, "wglSwapBuffers" => 1, @@ -206,16 +206,23 @@ my %manual_unix_thunks = "glGetFramebufferParameterivEXT" => 1, "glGetInteger64v" => 1, "glGetIntegerv" => 1, - "glGetUnsignedBytevEXT" => 1, "glGetString" => 1, "glGetStringi" => 1, + "glGetUnsignedBytevEXT" => 1, "glNamedFramebufferDrawBuffer" => 1, "glNamedFramebufferDrawBuffers" => 1, "glNamedFramebufferReadBuffer" => 1, "glReadBuffer" => 1, "glReadPixels" => 1, "glViewport" => 1, + "wglCopyContext" => 1, + "wglCreateContext" => 1, + "wglCreateContextAttribsARB" => 1, + "wglDeleteContext" => 1, "wglGetProcAddress" => 1, + "wglMakeContextCurrentARB" => 1, + "wglMakeCurrent" => 1, + "wglShareLists" => 1, "wglSwapBuffers" => 1, ); my %hide_default_fbo_thunks = @@ -374,12 +381,6 @@ sub ConvertType($) my $arg = shift; my $ret = $arg->textContent(); my @type = $arg->findnodes("./ptype"); - - if (@type) - { - my $type = $type[0]->textContent(); - $ret =~ s/$type/$remap_types{$type}/ if defined $remap_types{$type}; - } return $ret; } @@ -426,6 +427,7 @@ sub get_func_args($$) $ret .= " " . ($unix ? ConvertType( $arg ) : $arg->textContent()) . ","; } $ret .= " HPBUFFERARB client_pbuffer," if $unix && $func->[0] =~ /HPBUFFERARB/; + $ret .= " HGLRC client_context," if $unix && $func->[0] =~ /HGLRC/ && @{$func->[1]}; $ret =~ s/,$/ /; $ret ||= "void"; return $ret; @@ -445,7 +447,7 @@ sub generate_unix_thunk($$$$) my $func_ret = get_func_ret( $func, 0 ); my $manual_wow64_wrapper = $is_wow64 && defined $manual_wow64_wrappers{$name}; my $need_wrap = $manual_wow64_wrapper || needs_wrapper( $name, $func ); - my $need_lock = $func_ret =~ /HGLRC/; + my $need_lock = 0; my $need_funcs = !$need_wrap || ($prefix eq "ext" && $name !~ /^wgl/); my $teb = $is_wow64 ? "teb" : "params->teb"; my $ret_stat = "return STATUS_SUCCESS;"; @@ -453,17 +455,13 @@ sub generate_unix_thunk($$$$) my $input_conv = ""; my $output_conv = ""; my $use_pbuffer = 0; + my $use_context = 0; my $call_args = ""; my $ret_expr = ""; my $use_dc = 0; my $vars = ""; my $ret = ""; - foreach my $arg (@{$func->[1]}) - { - $need_lock = 1 if $arg->textContent() =~ /HGLRC/; - } - $ret .= "static NTSTATUS "; $ret .= "wow64_" if $is_wow64; $ret .= "$prefix\_$name( void *args )\n"; @@ -472,6 +470,7 @@ sub generate_unix_thunk($$$$) # special case for functions that take an HDC as first parameter $use_dc = @{$func->[1]} && get_arg_type( ${$func->[1]}[0] ) eq "HDC" && $name !~ /wglMake(Context)?Current/; $use_pbuffer = @{$func->[1]} && get_arg_type( ${$func->[1]}[0] ) eq "HPBUFFERARB"; + $use_context = @{$func->[1]} && get_arg_type( ${$func->[1]}[0] ) eq "HGLRC"; $ret_expr = "params->ret = " if !is_void_func( $func ); $call_args .= " $teb," if $need_wrap; @@ -524,7 +523,7 @@ sub generate_unix_thunk($$$$) $need_lock = 1 if $arg_type =~ /GLsync/; } } - $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB/; + $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB|HGLRC/; if (!is_void_func($func)) { my $ret_type = get_arg_type( $func->[0] ); @@ -539,7 +538,7 @@ sub generate_unix_thunk($$$$) elsif ($ptype eq "PTR32") { $ret_expr .= "(UINT_PTR)"; - $need_manual_thunk = 1 if $func_ret !~ /HDC|HPBUFFERARB/; + $need_manual_thunk = 1 if $func_ret !~ /HDC|HPBUFFERARB|HGLRC/; } } $ret .= " } *params = args;\n"; @@ -560,7 +559,7 @@ sub generate_unix_thunk($$$$) : " buffer = invalidate_buffer_target( $teb, params->target );\n"; $output_conv .= " if (buffer) free_buffer( funcs, buffer );\n"; } - $ret .= " TEB *teb = get_teb64( params->teb );\n" if $need_wrap || (!$use_dc && !$use_pbuffer); + $ret .= " TEB *teb = get_teb64( params->teb );\n" if $need_wrap || (!$use_dc && !$use_pbuffer && !$use_context); } else { @@ -568,26 +567,20 @@ sub generate_unix_thunk($$$$) { my $ptype = get_arg_type( $arg ); my $pname = get_arg_name( $arg ); - if (!$need_wrap && defined $remap_types{$ptype}) - { - $call_args .= " ($remap_types{$ptype})params->$pname,"; - } - else - { - $call_args .= " params->$pname,"; - } + $call_args .= " params->$pname,"; } - $call_args .= " params->ret," if $func_ret =~ /HPBUFFERARB/; + $call_args .= " params->ret," if $func_ret =~ /HPBUFFERARB|HGLRC/; $ret .= " struct $name\_params *params = args;\n"; } $ret .= $vars; - if ($use_dc || $use_pbuffer) + if ($use_dc || $use_pbuffer || $use_context) { my $param = "params->" . get_arg_name( ${$func->[1]}[0] ); $param = "ULongToPtr($param)" if $is_wow64; $ret .= " const struct opengl_funcs *funcs = "; $ret .= "get_dc_funcs( $param );\n" if $use_dc; $ret .= "get_pbuffer_funcs( $param );\n" if $use_pbuffer; + $ret .= "get_context_funcs( $param );\n" if $use_context; $ret .= " if (!funcs || !funcs->p_$name) return STATUS_NOT_IMPLEMENTED;\n"; } elsif ($need_funcs) @@ -618,7 +611,6 @@ sub generate_unix_thunk($$$$) } else { - $ret .= "($func_ret)" if defined $remap_types{$func_ret}; $ret .= "funcs->p_$name($call_args);\n"; } $ret .= " pthread_mutex_unlock( &wgl_lock );\n" if $need_lock; @@ -670,6 +662,7 @@ sub generate_wrapper_declaration($$$) $ret .= " " . $arg->textContent() . ","; } $ret .= " HPBUFFERARB handle," if $ret_type =~ /HPBUFFERARB/; + $ret .= " HGLRC handle," if $ret_type =~ /HGLRC/; $ret =~ s/,$/ /; $ret .= ");\n"; return $ret; @@ -679,6 +672,7 @@ sub get_handle_function($) { my $ptype = shift; return "get_pbuffer_from_handle" if $ptype =~ /HPBUFFERARB/; + return "get_context_from_handle" if $ptype =~ /HGLRC/; return 0; } @@ -979,19 +973,8 @@ sub is_supported_extension($) sub needs_wrapper($$) { my ($name, $func) = @_; - return 0 if defined $manual_win_functions{$name}; return 1 if defined $manual_unix_thunks{$name}; - - # check if return value needs special handling - (my $type = $func->[0]->textContent()) =~ s/ $//; - return 1 if defined $remap_types{$type}; - # check if one of the arguments needs special handling - foreach (@{$func->[1]}) - { - $type = get_arg_type( $_ ); - return 1 if defined $remap_types{$type}; - } return 0; } @@ -1188,8 +1171,6 @@ print HEADER "#ifndef EGL_CAST\n"; print HEADER "#define EGL_CAST(t,x) ((t)(x))\n"; print HEADER "#endif\n\n"; -print HEADER "struct wgl_context;\n"; - foreach (@gl_types) { my $type = $gl_types{$_}; diff --git a/dlls/opengl32/private.h b/dlls/opengl32/private.h index 3a1dc0cd433..5ee9a0fce2d 100644 --- a/dlls/opengl32/private.h +++ b/dlls/opengl32/private.h @@ -33,5 +33,6 @@ extern const void *extension_procs[]; extern int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ); extern BOOL get_pbuffer_from_handle( HPBUFFERARB handle, HPBUFFERARB *obj ); +extern BOOL get_context_from_handle( HGLRC handle, HGLRC *obj ); #endif /* __WINE_OPENGL32_PRIVATE_H */ diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index bbf1070feab..437ae70fe9c 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -18,40 +18,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(opengl); BOOL WINAPI wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) { - struct wglCopyContext_params args = { .teb = NtCurrentTeb(), .hglrcSrc = hglrcSrc, .hglrcDst = hglrcDst, .mask = mask }; + struct wglCopyContext_params args = { .teb = NtCurrentTeb(), .mask = mask }; NTSTATUS status; TRACE( "hglrcSrc %p, hglrcDst %p, mask %u\n", hglrcSrc, hglrcDst, mask ); + if (!get_context_from_handle( hglrcSrc, &args.hglrcSrc )) return 0; + if (!get_context_from_handle( hglrcDst, &args.hglrcDst )) return 0; if ((status = UNIX_CALL( wglCopyContext, &args ))) WARN( "wglCopyContext returned %#lx\n", status ); return args.ret; } -HGLRC WINAPI wglCreateContext( HDC hDc ) -{ - struct wglCreateContext_params args = { .teb = NtCurrentTeb(), .hDc = hDc }; - NTSTATUS status; - TRACE( "hDc %p\n", hDc ); - if ((status = UNIX_CALL( wglCreateContext, &args ))) WARN( "wglCreateContext returned %#lx\n", status ); - return args.ret; -} - -BOOL WINAPI wglDeleteContext( HGLRC oldContext ) -{ - struct wglDeleteContext_params args = { .teb = NtCurrentTeb(), .oldContext = oldContext }; - NTSTATUS status; - TRACE( "oldContext %p\n", oldContext ); - if ((status = UNIX_CALL( wglDeleteContext, &args ))) WARN( "wglDeleteContext returned %#lx\n", status ); - return args.ret; -} - -BOOL WINAPI wglMakeCurrent( HDC hDc, HGLRC newContext ) -{ - struct wglMakeCurrent_params args = { .teb = NtCurrentTeb(), .hDc = hDc, .newContext = newContext }; - NTSTATUS status; - TRACE( "hDc %p, newContext %p\n", hDc, newContext ); - if ((status = UNIX_CALL( wglMakeCurrent, &args ))) WARN( "wglMakeCurrent returned %#lx\n", status ); - return args.ret; -} - BOOL WINAPI wglSetPixelFormat( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ) { struct wglSetPixelFormat_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .ipfd = ipfd, .ppfd = ppfd }; @@ -63,9 +38,11 @@ BOOL WINAPI wglSetPixelFormat( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *p BOOL WINAPI wglShareLists( HGLRC hrcSrvShare, HGLRC hrcSrvSource ) { - struct wglShareLists_params args = { .teb = NtCurrentTeb(), .hrcSrvShare = hrcSrvShare, .hrcSrvSource = hrcSrvSource }; + struct wglShareLists_params args = { .teb = NtCurrentTeb() }; NTSTATUS status; TRACE( "hrcSrvShare %p, hrcSrvSource %p\n", hrcSrvShare, hrcSrvSource ); + if (!get_context_from_handle( hrcSrvShare, &args.hrcSrvShare )) return 0; + if (!get_context_from_handle( hrcSrvSource, &args.hrcSrvSource )) return 0; if ((status = UNIX_CALL( wglShareLists, &args ))) WARN( "wglShareLists returned %#lx\n", status ); return args.ret; } @@ -24743,15 +24720,6 @@ static BOOL WINAPI wglBindTexImageARB( HPBUFFERARB hPbuffer, int iBuffer ) return args.ret; } -static HGLRC WINAPI wglCreateContextAttribsARB( HDC hDC, HGLRC hShareContext, const int *attribList ) -{ - struct wglCreateContextAttribsARB_params args = { .teb = NtCurrentTeb(), .hDC = hDC, .hShareContext = hShareContext, .attribList = attribList }; - NTSTATUS status; - TRACE( "hDC %p, hShareContext %p, attribList %p\n", hDC, hShareContext, attribList ); - if ((status = UNIX_CALL( wglCreateContextAttribsARB, &args ))) WARN( "wglCreateContextAttribsARB returned %#lx\n", status ); - return args.ret; -} - static void WINAPI wglFreeMemoryNV( void *pointer ) { struct wglFreeMemoryNV_params args = { .teb = NtCurrentTeb(), .pointer = pointer }; @@ -24779,15 +24747,6 @@ static int WINAPI wglGetSwapIntervalEXT(void) return args.ret; } -static BOOL WINAPI wglMakeContextCurrentARB( HDC hDrawDC, HDC hReadDC, HGLRC hglrc ) -{ - struct wglMakeContextCurrentARB_params args = { .teb = NtCurrentTeb(), .hDrawDC = hDrawDC, .hReadDC = hReadDC, .hglrc = hglrc }; - NTSTATUS status; - TRACE( "hDrawDC %p, hReadDC %p, hglrc %p\n", hDrawDC, hReadDC, hglrc ); - if ((status = UNIX_CALL( wglMakeContextCurrentARB, &args ))) WARN( "wglMakeContextCurrentARB returned %#lx\n", status ); - return args.ret; -} - static BOOL WINAPI wglQueryCurrentRendererIntegerWINE( GLenum attribute, GLuint *value ) { struct wglQueryCurrentRendererIntegerWINE_params args = { .teb = NtCurrentTeb(), .attribute = attribute, .value = value }; @@ -24866,6 +24825,7 @@ static BOOL WINAPI wglSwapIntervalEXT( int interval ) extern const GLubyte * WINAPI glGetStringi( GLenum name, GLuint index ); extern BOOL WINAPI wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); +extern HGLRC WINAPI wglCreateContextAttribsARB( HDC hDC, HGLRC hShareContext, const int *attribList ); extern HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); extern BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB hPbuffer ); extern HDC WINAPI wglGetCurrentReadDCARB(void); @@ -24873,6 +24833,7 @@ extern const char * WINAPI wglGetExtensionsStringARB( HDC hdc ); extern const char * WINAPI wglGetExtensionsStringEXT(void); extern BOOL WINAPI wglGetPixelFormatAttribfvARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues ); extern BOOL WINAPI wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues ); +extern BOOL WINAPI wglMakeContextCurrentARB( HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); extern const GLchar * WINAPI wglQueryCurrentRendererStringWINE( GLenum attribute ); extern const GLchar * WINAPI wglQueryRendererStringWINE( HDC dc, GLint renderer, GLenum attribute ); const void *extension_procs[] = diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index a42445a0983..e1076fe7831 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -63,6 +63,12 @@ static inline const struct opengl_funcs *get_pbuffer_funcs( HPBUFFERARB client_p return client_pbuffer ? (struct opengl_funcs *)(UINT_PTR)client->unix_funcs : NULL; } +static inline const struct opengl_funcs *get_context_funcs( HGLRC client_context ) +{ + struct opengl_client_context *client = opengl_client_context_from_client( client_context ); + return client_context ? (struct opengl_funcs *)(UINT_PTR)client->unix_funcs : NULL; +} + #ifdef _WIN64 static inline void *copy_wow64_ptr32s( UINT_PTR address, ULONG count ) diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 5ef8612bb9a..41ce0f2d5e1 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -26,9 +26,9 @@ static GLboolean const_true = 1; static NTSTATUS wgl_wglCopyContext( void *args ) { struct wglCopyContext_params *params = args; - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( params->hglrcSrc ); + if (!funcs || !funcs->p_wglCopyContext) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglCopyContext( params->teb, params->hglrcSrc, params->hglrcDst, params->mask ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -37,18 +37,16 @@ static NTSTATUS wgl_wglCreateContext( void *args ) struct wglCreateContext_params *params = args; const struct opengl_funcs *funcs = get_dc_funcs( params->hDc ); if (!funcs || !funcs->p_wglCreateContext) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglCreateContext( params->teb, params->hDc ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = wrap_wglCreateContext( params->teb, params->hDc, params->ret ); return STATUS_SUCCESS; } static NTSTATUS wgl_wglDeleteContext( void *args ) { struct wglDeleteContext_params *params = args; - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( params->oldContext ); + if (!funcs || !funcs->p_wglDeleteContext) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglDeleteContext( params->teb, params->oldContext ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -71,9 +69,7 @@ static NTSTATUS wgl_wglGetProcAddress( void *args ) static NTSTATUS wgl_wglMakeCurrent( void *args ) { struct wglMakeCurrent_params *params = args; - pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeCurrent( params->teb, params->hDc, params->newContext ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -89,9 +85,9 @@ static NTSTATUS wgl_wglSetPixelFormat( void *args ) static NTSTATUS wgl_wglShareLists( void *args ) { struct wglShareLists_params *params = args; - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( params->hrcSrvShare ); + if (!funcs || !funcs->p_wglShareLists) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglShareLists( params->teb, params->hrcSrvShare, params->hrcSrvSource ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -30319,9 +30315,7 @@ static NTSTATUS ext_wglCreateContextAttribsARB( void *args ) struct wglCreateContextAttribsARB_params *params = args; const struct opengl_funcs *funcs = get_dc_funcs( params->hDC ); if (!funcs || !funcs->p_wglCreateContextAttribsARB) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = wrap_wglCreateContextAttribsARB( params->teb, params->hDC, params->hShareContext, params->attribList ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = wrap_wglCreateContextAttribsARB( params->teb, params->hDC, params->hShareContext, params->attribList, params->ret ); return STATUS_SUCCESS; } @@ -30409,9 +30403,7 @@ static NTSTATUS ext_wglGetSwapIntervalEXT( void *args ) static NTSTATUS ext_wglMakeContextCurrentARB( void *args ) { struct wglMakeContextCurrentARB_params *params = args; - pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeContextCurrentARB( params->teb, params->hDrawDC, params->hReadDC, params->hglrc ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -33630,9 +33622,9 @@ static NTSTATUS wow64_wgl_wglCopyContext( void *args ) BOOL ret; } *params = args; TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( ULongToPtr(params->hglrcSrc) ); + if (!funcs || !funcs->p_wglCopyContext) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglCopyContext( teb, ULongToPtr(params->hglrcSrc), ULongToPtr(params->hglrcDst), params->mask ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -33647,9 +33639,7 @@ static NTSTATUS wow64_wgl_wglCreateContext( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = get_dc_funcs( ULongToPtr(params->hDc) ); if (!funcs || !funcs->p_wglCreateContext) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = (UINT_PTR)wrap_wglCreateContext( teb, ULongToPtr(params->hDc) ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = (UINT_PTR)wrap_wglCreateContext( teb, ULongToPtr(params->hDc), UlongToHandle( params->ret ) ); return STATUS_SUCCESS; } @@ -33662,9 +33652,9 @@ static NTSTATUS wow64_wgl_wglDeleteContext( void *args ) BOOL ret; } *params = args; TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( ULongToPtr(params->oldContext) ); + if (!funcs || !funcs->p_wglDeleteContext) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglDeleteContext( teb, ULongToPtr(params->oldContext) ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -33705,9 +33695,7 @@ static NTSTATUS wow64_wgl_wglMakeCurrent( void *args ) BOOL ret; } *params = args; TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeCurrent( teb, ULongToPtr(params->hDc), ULongToPtr(params->newContext) ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -33737,9 +33725,9 @@ static NTSTATUS wow64_wgl_wglShareLists( void *args ) BOOL ret; } *params = args; TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); + const struct opengl_funcs *funcs = get_context_funcs( ULongToPtr(params->hrcSrvShare) ); + if (!funcs || !funcs->p_wglShareLists) return STATUS_NOT_IMPLEMENTED; params->ret = wrap_wglShareLists( teb, ULongToPtr(params->hrcSrvShare), ULongToPtr(params->hrcSrvSource) ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -86527,9 +86515,7 @@ static NTSTATUS wow64_ext_wglCreateContextAttribsARB( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = get_dc_funcs( ULongToPtr(params->hDC) ); if (!funcs || !funcs->p_wglCreateContextAttribsARB) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = (UINT_PTR)wrap_wglCreateContextAttribsARB( teb, ULongToPtr(params->hDC), ULongToPtr(params->hShareContext), ULongToPtr(params->attribList) ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = (UINT_PTR)wrap_wglCreateContextAttribsARB( teb, ULongToPtr(params->hDC), ULongToPtr(params->hShareContext), ULongToPtr(params->attribList), UlongToHandle( params->ret ) ); return STATUS_SUCCESS; } @@ -86686,9 +86672,7 @@ static NTSTATUS wow64_ext_wglMakeContextCurrentARB( void *args ) BOOL ret; } *params = args; TEB *teb = get_teb64( params->teb ); - pthread_mutex_lock( &wgl_lock ); params->ret = wrap_wglMakeContextCurrentARB( teb, ULongToPtr(params->hDrawDC), ULongToPtr(params->hReadDC), ULongToPtr(params->hglrc) ); - pthread_mutex_unlock( &wgl_lock ); return STATUS_SUCCESS; } @@ -89960,17 +89944,17 @@ C_ASSERT(ARRAYSIZE(__wine_unix_call_wow64_funcs) == funcs_count); #endif -static BOOL null_wglCopyContext( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ) +static BOOL null_wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) { WARN( "unsupported\n" ); return 0; } -static struct wgl_context * null_wglCreateContext( HDC hDc ) +static HGLRC null_wglCreateContext( HDC hDc, HGLRC client_context ) { WARN( "unsupported\n" ); return 0; } -static BOOL null_wglDeleteContext( struct wgl_context * oldContext ) +static BOOL null_wglDeleteContext( HGLRC oldContext ) { WARN( "unsupported\n" ); return 0; @@ -89986,7 +89970,7 @@ static PROC null_wglGetProcAddress( LPCSTR lpszProc ) WARN( "unsupported\n" ); return 0; } -static BOOL null_wglMakeCurrent( HDC hDc, struct wgl_context * newContext ) +static BOOL null_wglMakeCurrent( HDC hDc, HGLRC newContext ) { WARN( "unsupported\n" ); return 0; @@ -89996,7 +89980,7 @@ static BOOL null_wglSetPixelFormat( HDC hdc, int ipfd, const PIXELFORMATDESCRIPT WARN( "unsupported\n" ); return 0; } -static BOOL null_wglShareLists( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ) +static BOOL null_wglShareLists( HGLRC hrcSrvShare, HGLRC hrcSrvSource ) { WARN( "unsupported\n" ); return 0; diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index 2d42d73de03..e23c9e9e5bd 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -3,7 +3,7 @@ typedef ULONG PTR32; extern BOOL wrap_wglCopyContext( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ); -extern HGLRC wrap_wglCreateContext( TEB *teb, HDC hDc ); +extern HGLRC wrap_wglCreateContext( TEB *teb, HDC hDc, HGLRC handle ); extern BOOL wrap_wglDeleteContext( TEB *teb, HGLRC oldContext ); extern PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR lpszProc ); extern BOOL wrap_wglMakeCurrent( TEB *teb, HDC hDc, HGLRC newContext ); @@ -37,7 +37,7 @@ extern void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ); extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); -extern HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hDC, HGLRC hShareContext, const int *attribList ); +extern HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hDC, HGLRC hShareContext, const int *attribList, HGLRC handle ); extern BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); #ifdef _WIN64 diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index acb71457bf5..17994a2c324 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -60,7 +60,6 @@ pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER; enum wgl_handle_type { - HANDLE_CONTEXT = 1 << 12, HANDLE_GLSYNC = 2 << 12, HANDLE_TYPE_MASK = 15 << 12, }; @@ -132,6 +131,7 @@ struct context struct wgl_context base; HDC hdc; /* context creation DC */ + HGLRC client; /* client-side context handle */ HGLRC share; /* context to be shared with */ int *attribs; /* creation attributes */ DWORD tid; /* thread that the context is current in */ @@ -195,23 +195,6 @@ struct vk_device PFN_vkUnmapMemory2KHR p_vkUnmapMemory2KHR; }; -struct wgl_handle -{ - UINT handle; - const struct opengl_funcs *funcs; - union - { - struct wgl_context *context; /* for HANDLE_CONTEXT */ - GLsync sync; /* for HANDLE_GLSYNC */ - struct wgl_handle *next; /* for free handles */ - } u; -}; - -#define MAX_WGL_HANDLES 1024 -static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; -static struct wgl_handle *next_free; -static unsigned int handle_count; - static ULONG_PTR zero_bits; static const struct vulkan_funcs *vk_funcs; @@ -226,39 +209,24 @@ static int vk_device_cmp( const void *key, const struct rb_entry *entry ) struct rb_tree vk_devices = { vk_device_cmp }; -static struct context *context_from_wgl_context( struct wgl_context *context ) +static void opengl_client_context_init( HGLRC client_context, struct context *context, const struct opengl_funcs *funcs ) { - return CONTAINING_RECORD( context, struct context, base ); + struct opengl_client_context *client = opengl_client_context_from_client( client_context ); + client->unix_handle = (UINT_PTR)context; + client->unix_funcs = (UINT_PTR)funcs; } /* the current context is assumed valid and doesn't need locking */ static struct context *get_current_context( TEB *teb, struct opengl_drawable **draw, struct opengl_drawable **read ) { - struct wgl_context *context; - if (!teb->glCurrentRC) return NULL; - if (!(context = wgl_handles[LOWORD(teb->glCurrentRC) & ~HANDLE_TYPE_MASK].u.context)) return NULL; - if (draw) *draw = context->draw; - if (read) *read = context->read; - return context_from_wgl_context( context ); -} - -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 ); -} + struct wgl_context *base; + struct context *context; -static struct wgl_handle *get_handle_ptr( HANDLE handle ) -{ - unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK; - - if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle) - return &wgl_handles[index]; - - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return NULL; + if (!(base = teb->glContext)) return NULL; + context = CONTAINING_RECORD( base, struct context, base ); + if (draw) *draw = context->base.draw; + if (read) *read = context->base.read; + return context; } struct context_attribute_desc @@ -301,28 +269,28 @@ void set_context_attribute( TEB *teb, GLenum name, const void *value, size_t siz else if (size && size != context_attributes[name].size) ERR( "Invalid state attrib %#x parameter size %#zx\n", name, size ); else memcpy( (char *)ctx + context_attributes[name].offset, value, context_attributes[name].size ); - if (bit == -1 && ctx->used != -1) WARN( "Unsupported attribute on context %p/%p\n", teb->glCurrentRC, ctx ); + if (bit == -1 && ctx->used != -1) WARN( "Unsupported attribute on context %p\n", ctx ); ctx->used |= bit; } -static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, HGLRC dst_handle, struct context *dst, - HGLRC src_handle, struct context *src, GLbitfield mask ) +static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context *dst, + HGLRC client_src, struct context *src, GLbitfield mask ) { + struct context *old_ctx = CONTAINING_RECORD( teb->glContext, struct context, base ); HDC draw_hdc = teb->glReserved1[0], read_hdc = teb->glReserved1[1]; - struct context *old_ctx = get_current_context( teb, NULL, NULL ); - const struct opengl_funcs *old_funcs = teb->glTable; + const struct opengl_funcs *old_funcs = teb->glTable, *funcs; - if (dst == old_ctx) + if (dst == old_ctx || !(funcs = get_context_funcs( client_dst ))) { RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } if (!mask) return TRUE; - if (src->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", src_handle, src ); - if (src != dst && dst->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", dst_handle, dst ); + if (src->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", client_src, src ); + if (src != dst && dst->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", client_dst, dst ); - funcs->p_wglMakeCurrent( dst->hdc, &dst->base ); + funcs->p_wglMakeCurrent( dst->hdc, client_dst ); if (mask & GL_COLOR_BUFFER_BIT) { @@ -371,8 +339,8 @@ static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, dst->used |= (src->used & mask); if (!old_ctx) funcs->p_wglMakeCurrent( NULL, NULL ); - else if (!old_funcs->p_wglMakeContextCurrentARB) old_funcs->p_wglMakeCurrent( draw_hdc, &old_ctx->base ); - else old_funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, &old_ctx->base ); + else if (!old_funcs->p_wglMakeContextCurrentARB) old_funcs->p_wglMakeCurrent( draw_hdc, old_ctx->client ); + else old_funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, old_ctx->client ); return dst->used != -1 && src->used != -1; } @@ -420,82 +388,44 @@ static void release_buffers( const struct opengl_funcs *funcs, struct buffers *b free( buffers ); } -static struct context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs ); +static struct context *context_from_client_context( HGLRC client_context ) +{ + struct wgl_context *base = opengl_context_from_handle( client_context ); + return base ? CONTAINING_RECORD( base, struct context, base ) : NULL; +} + +static struct context *get_updated_context( TEB *teb, HGLRC client_context ); -/* update handle context if it has been re-shared with another one */ -static void update_handle_context( TEB *teb, HGLRC handle, struct wgl_handle *ptr ) +/* update context if it has been re-shared with another one */ +static struct context *update_context( TEB *teb, HGLRC client_context, struct context *ctx ) { - struct context *ctx = context_from_wgl_context( ptr->u.context ), *shared; - const struct opengl_funcs *funcs = ptr->funcs, *share_funcs; + const struct opengl_funcs *funcs = get_context_funcs( client_context ); + struct context *share; - if (ctx->tid) return; /* currently in use */ - if (ctx->share == (HGLRC)-1) return; /* not re-shared */ + if (ctx->tid) return ctx; /* currently in use */ + if (ctx->share == (HGLRC)-1) return ctx; /* not re-shared */ - shared = ctx->share ? opengl_context_from_handle( teb, ctx->share, &share_funcs ) : NULL; - if (!funcs->p_wgl_context_reset( &ctx->base, ctx->hdc, shared ? &shared->base : NULL, ctx->attribs )) + share = ctx->share ? get_updated_context( teb, ctx->share ) : NULL; + if (!funcs->p_wgl_context_reset( &ctx->base, ctx->hdc, share ? &share->base : NULL, ctx->attribs )) { WARN( "Failed to re-create context for wglShareLists\n" ); - return; + return ctx; } - if (shared && shared->buffers) + if (share && share->buffers) { release_buffers( funcs, ctx->buffers ); - ctx->buffers = shared->buffers; + ctx->buffers = share->buffers; ctx->buffers->ref++; } ctx->share = (HGLRC)-1; /* initial shared context */ - copy_context_attributes( teb, funcs, handle, ctx, handle, ctx, ctx->used ); + copy_context_attributes( teb, client_context, ctx, client_context, ctx, ctx->used ); + return ctx; } -static struct context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs ) +static struct context *get_updated_context( TEB *teb, HGLRC client_context ) { - struct wgl_handle *entry; - if (!(entry = get_handle_ptr( handle ))) return NULL; - update_handle_context( teb, handle, entry ); - *funcs = entry->funcs; - return context_from_wgl_context( entry->u.context ); -} - -static HANDLE alloc_handle( enum wgl_handle_type type, const struct opengl_funcs *funcs, void *user_ptr ) -{ - HANDLE handle = 0; - struct wgl_handle *ptr = NULL; - - 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 RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); - 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; -} - -static void update_teb32_context( TEB *teb ) -{ -#ifdef _WIN64 - TEB32 *teb32; - - if (!teb->WowTebOffset) return; - teb32 = (TEB32 *)((char *)teb + teb->WowTebOffset); - - teb32->glCurrentRC = (UINT_PTR)teb->glCurrentRC; - teb32->glReserved1[0] = (UINT_PTR)teb->glReserved1[0]; - teb32->glReserved1[1] = (UINT_PTR)teb->glReserved1[1]; -#endif + struct context *context = context_from_client_context( client_context ); + return client_context ? update_context( teb, client_context, context ) : NULL; } static int *memdup_attribs( const int *attribs ) @@ -1032,15 +962,14 @@ PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR name ) return (void *)(UINT_PTR)(found - extension_registry); } -BOOL wrap_wglCopyContext( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) +BOOL wrap_wglCopyContext( TEB *teb, HGLRC client_src, HGLRC client_dst, UINT mask ) { - const struct opengl_funcs *src_funcs, *dst_funcs; struct context *src, *dst; BOOL ret = FALSE; - if (!(src = opengl_context_from_handle( teb, hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = opengl_context_from_handle( teb, hglrcDst, &dst_funcs ))) return FALSE; - else ret = copy_context_attributes( teb, dst_funcs, hglrcDst, dst, hglrcSrc, src, mask ); + if (!(src = get_updated_context( teb, client_src ))) return FALSE; + if (!(dst = get_updated_context( teb, client_dst ))) return FALSE; + else ret = copy_context_attributes( teb, client_dst, dst, client_src, src, mask ); return ret; } @@ -1235,7 +1164,7 @@ static BOOL initialize_vk_device( TEB *teb, struct context *ctx ) } static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HDC draw_hdc, HDC read_hdc, - HGLRC hglrc, struct context *ctx ) + HGLRC client_context, struct context *ctx ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); size_t size = ARRAYSIZE(legacy_extensions) - 1, count = 0; @@ -1247,7 +1176,6 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD ctx->tid = tid; teb->glReserved1[0] = draw_hdc; teb->glReserved1[1] = read_hdc; - teb->glCurrentRC = hglrc; teb->glTable = (void *)funcs; pop_default_fbo( teb ); @@ -1350,30 +1278,30 @@ static void make_context_current( TEB *teb, const struct opengl_funcs *funcs, HD if (TRACE_ON(opengl)) for (i = 0; i < count; i++) TRACE( "++ %s\n", extensions[i] ); } -BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) +BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC client_context ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct context *ctx, *prev = get_current_context( teb, NULL, NULL ); - const struct opengl_funcs *funcs = teb->glTable; - if (hglrc) + if (client_context) { - if (!(ctx = opengl_context_from_handle( teb, hglrc, &funcs ))) return FALSE; + const struct opengl_funcs *funcs = get_context_funcs( client_context ); + if (!(ctx = get_updated_context( teb, client_context ))) return FALSE; if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; } - if (!funcs->p_wglMakeCurrent( hdc, &ctx->base )) return FALSE; + if (!funcs->p_wglMakeCurrent( hdc, client_context )) return FALSE; if (prev) prev->tid = 0; - make_context_current( teb, funcs, hdc, hdc, hglrc, ctx ); + make_context_current( teb, funcs, hdc, hdc, client_context, ctx ); } else if (prev) { + const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; - teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; } else if (!hdc) @@ -1381,7 +1309,6 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } - update_teb32_context( teb ); return TRUE; } @@ -1394,23 +1321,19 @@ static void free_context( struct context *ctx ) free( ctx ); } -BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) +BOOL wrap_wglDeleteContext( TEB *teb, HGLRC client_context ) { - struct wgl_handle *ptr; - struct context *ctx; - DWORD tid = HandleToULong(teb->ClientId.UniqueThread); + const struct opengl_funcs *funcs = get_context_funcs( client_context ); + struct context *ctx = context_from_client_context( client_context ); - if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; - ctx = context_from_wgl_context( ptr->u.context ); - if (ctx->tid && ctx->tid != tid) + if (ctx->tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; } - if (hglrc == teb->glCurrentRC) wrap_wglMakeCurrent( teb, 0, 0 ); - ptr->funcs->p_wgl_context_reset( &ctx->base, NULL, NULL, NULL ); + + funcs->p_wgl_context_reset( &ctx->base, NULL, NULL, NULL ); free_context( ctx ); - free_handle_ptr( ptr ); return TRUE; } @@ -1552,51 +1475,41 @@ BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) return ret; } -BOOL wrap_wglShareLists( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst ) +BOOL wrap_wglShareLists( TEB *teb, HGLRC client_src, HGLRC client_dst ) { - const struct opengl_funcs *src_funcs, *dst_funcs; + const struct opengl_funcs *src_funcs = get_context_funcs( client_src ), *dst_funcs = get_context_funcs( client_dst ); struct context *src, *dst; BOOL ret = FALSE; - if (!(src = opengl_context_from_handle( teb, hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = opengl_context_from_handle( teb, hglrcDst, &dst_funcs ))) return FALSE; + if (!(src = context_from_client_context( client_src ))) return FALSE; + if (!(dst = context_from_client_context( client_dst ))) return FALSE; if (src_funcs != dst_funcs) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - else if ((ret = dst->used != -1)) dst->share = hglrcSrc; - else FIXME( "Unsupported attributes on context %p/%p\n", hglrcDst, dst ); + else if ((ret = dst->used != -1)) dst->share = client_src; + else FIXME( "Unsupported attributes on context %p/%p\n", client_dst, dst ); return ret; } -HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int *attribs ) +HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, const int *attribs, HGLRC client_context ) { - HGLRC ret = 0; - struct context *context, *share_ctx = NULL; - const struct opengl_funcs *funcs = get_dc_funcs( hdc ), *share_funcs; + const struct opengl_funcs *funcs = get_dc_funcs( hdc ); + struct context *context, *shared = get_updated_context( teb, client_shared ); - if (!funcs) - { - RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); - return 0; - } - if (share && !(share_ctx = opengl_context_from_handle( teb, share, &share_funcs ))) - { - RtlSetLastWin32Error( ERROR_INVALID_OPERATION ); - return 0; - } if (!(context = calloc( 1, sizeof(*context) ))) { RtlSetLastWin32Error( ERROR_OUTOFMEMORY ); return 0; } + context->base.client_context = client_context; context->hdc = hdc; context->share = (HGLRC)-1; /* initial shared context */ context->attribs = memdup_attribs( attribs ); if (is_win64 && is_wow64()) { - if (share_ctx) + if (shared) { - context->buffers = share_ctx->buffers; + context->buffers = shared->buffers; context->buffers->ref++; } else if (!(context->buffers = malloc( sizeof(*context->buffers )))) @@ -1612,29 +1525,31 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int } } - if (!(funcs->p_wgl_context_reset( &context->base, hdc, share_ctx ? &share_ctx->base : NULL, attribs ))) free_context( context ); - else if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) + if (!(funcs->p_wgl_context_reset( &context->base, hdc, shared ? &shared->base : NULL, attribs ))) { - funcs->p_wgl_context_reset( &context->base, NULL, NULL, NULL ); free_context( context ); + return 0; } - return ret; + + context->client = client_context; + opengl_client_context_init( client_context, context, funcs ); + return client_context; } -HGLRC wrap_wglCreateContext( TEB *teb, HDC hdc ) +HGLRC wrap_wglCreateContext( TEB *teb, HDC hdc, HGLRC client_context ) { - return wrap_wglCreateContextAttribsARB( teb, hdc, NULL, NULL ); + return wrap_wglCreateContextAttribsARB( teb, hdc, NULL, NULL, client_context ); } -BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) +BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC client_context ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct context *ctx, *prev = get_current_context( teb, NULL, NULL ); - const struct opengl_funcs *funcs = teb->glTable; - if (hglrc) + if (client_context) { - if (!(ctx = opengl_context_from_handle( teb, hglrc, &funcs ))) return FALSE; + const struct opengl_funcs *funcs = get_context_funcs( client_context ); + if (!(ctx = get_updated_context( teb, client_context ))) return FALSE; if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); @@ -1642,18 +1557,17 @@ BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC } if (!funcs->p_wglMakeContextCurrentARB) return FALSE; - if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, &ctx->base )) return FALSE; + if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, client_context )) return FALSE; if (prev) prev->tid = 0; - make_context_current( teb, funcs, draw_hdc, read_hdc, hglrc, ctx ); + make_context_current( teb, funcs, draw_hdc, read_hdc, client_context, ctx ); } else if (prev) { + const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; - teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; } - update_teb32_context( teb ); return TRUE; } @@ -2047,8 +1961,8 @@ void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint fbo, GLenum pname, GL GLenum wrap_glGetError( TEB *teb ) { const struct opengl_funcs *funcs = teb->glTable; - GLenum error, wrapped; struct wgl_context *ctx; + GLenum error, wrapped; if (!(ctx = &get_current_context( teb, NULL, NULL )->base)) return GL_INVALID_OPERATION; error = funcs->p_glGetError(); @@ -2155,6 +2069,70 @@ NTSTATUS return_wow64_string( const void *str, PTR32 *wow64_str ) return STATUS_BUFFER_TOO_SMALL; } +struct wgl_handle +{ + UINT handle; + const struct opengl_funcs *funcs; + union + { + GLsync sync; /* for HANDLE_GLSYNC */ + struct wgl_handle *next; /* for free handles */ + void *data; + } u; +}; + +#define MAX_WGL_HANDLES 1024 +static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; +static struct wgl_handle *next_free; +static unsigned int handle_count; + +static 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 HANDLE alloc_handle( enum wgl_handle_type type, const struct opengl_funcs *funcs, void *user_ptr ) +{ + HANDLE handle = 0; + struct wgl_handle *ptr = NULL; + + 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.data = user_ptr; + handle = next_handle( ptr, type ); + } + else RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); + 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; +} + +static struct wgl_handle *get_handle_ptr( HANDLE handle ) +{ + unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK; + + if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle) + return &wgl_handles[index]; + + RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); + return NULL; +} + static struct wgl_handle *get_sync_ptr( TEB *teb, GLsync sync ) { struct wgl_handle *handle = get_handle_ptr( sync ); diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 40ebed8bebd..de39feb3405 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -103,6 +103,7 @@ struct handle_entry UINT handle; union { + struct opengl_client_context *context; struct opengl_client_pbuffer *pbuffer; struct handle_entry *next_free; void *user_data; @@ -117,6 +118,7 @@ struct handle_table }; static struct handle_table pbuffers; +static struct handle_table contexts; static struct handle_entry *alloc_handle( struct handle_table *table, void *user_data ) { @@ -236,6 +238,147 @@ BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle ) return args.ret; } +static struct opengl_client_context *opengl_client_context_from_handle( HGLRC handle ) +{ + struct handle_entry *ptr; + if (!(ptr = get_handle_ptr( &contexts, handle ))) return NULL; + return ptr->context; +} + +BOOL get_context_from_handle( HGLRC handle, HGLRC *obj ) +{ + struct opengl_client_context *context = opengl_client_context_from_handle( handle ); + *obj = context ? &context->obj : NULL; + return context || !handle; +} + +static struct handle_entry *alloc_client_context(void) +{ + struct opengl_client_context *context; + struct handle_entry *ptr; + + if (!(context = calloc( 1, sizeof(*context) ))) return NULL; + if (!(ptr = alloc_handle( &contexts, context ))) + { + free( context ); + return NULL; + } + + return ptr; +} + +static void free_client_context( struct handle_entry *ptr ) +{ + struct opengl_client_context *context = ptr->context; + free_handle( &contexts, ptr ); + free( context ); +} + +HGLRC WINAPI wglCreateContext( HDC hdc ) +{ + struct wglCreateContext_params args = { .teb = NtCurrentTeb(), .hDc = hdc }; + struct handle_entry *ptr; + NTSTATUS status; + + TRACE( "hdc %p\n", hdc ); + + if (!(ptr = alloc_client_context())) return NULL; + args.ret = &ptr->context->obj; + + if ((status = UNIX_CALL( wglCreateContext, &args ))) WARN( "wglCreateContext returned %#lx\n", status ); + assert( args.ret == &ptr->context->obj || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_context( ptr ); + return NULL; +} + +HGLRC WINAPI wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs ) +{ + struct wglCreateContextAttribsARB_params args = { .teb = NtCurrentTeb(), .hDC = hdc, .attribList = attribs }; + struct handle_entry *ptr; + NTSTATUS status; + + TRACE( "hdc %p, share %p, attribs %p\n", hdc, share, attribs ); + + if (!get_context_from_handle( share, &args.hShareContext )) + { + SetLastError( ERROR_INVALID_OPERATION ); + return NULL; + } + if (!(ptr = alloc_client_context())) return NULL; + args.ret = &ptr->context->obj; + + if ((status = UNIX_CALL( wglCreateContextAttribsARB, &args ))) WARN( "wglCreateContextAttribsARB returned %#lx\n", status ); + assert( args.ret == &ptr->context->obj || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_context( ptr ); + return NULL; +} + +BOOL WINAPI wglDeleteContext( HGLRC handle ) +{ + TEB *teb = NtCurrentTeb(); + struct wglDeleteContext_params args = {.teb = teb}; + struct handle_entry *ptr; + NTSTATUS status; + + TRACE( "handle %p\n", handle ); + + if (!(ptr = get_handle_ptr( &contexts, handle ))) return FALSE; + args.oldContext = &ptr->context->obj; + + if (handle && handle == teb->glCurrentRC) wglMakeCurrent( NULL, NULL ); + if ((status = UNIX_CALL( wglDeleteContext, &args ))) WARN( "wglDeleteContext returned %#lx\n", status ); + if (status || !args.ret) return FALSE; + + if (handle == teb->glCurrentRC) + { + teb->glCurrentRC = 0; + teb->glReserved1[0] = 0; + teb->glReserved1[1] = 0; + } + free_client_context( ptr ); + return TRUE; +} + +BOOL WINAPI wglMakeCurrent( HDC hdc, HGLRC handle ) +{ + TEB *teb = NtCurrentTeb(); + struct wglMakeCurrent_params args = { .teb = teb, .hDc = hdc }; + NTSTATUS status; + + TRACE( "hdc %p, newContext %p\n", hdc, handle ); + + if (!get_context_from_handle( handle, &args.newContext )) return FALSE; + if ((status = UNIX_CALL( wglMakeCurrent, &args ))) WARN( "wglMakeCurrent returned %#lx\n", status ); + if (status || !args.ret) return FALSE; + + teb->glCurrentRC = handle; + teb->glReserved1[0] = hdc; + teb->glReserved1[1] = hdc; + return TRUE; +} + +BOOL WINAPI wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC handle ) +{ + TEB *teb = NtCurrentTeb(); + struct wglMakeContextCurrentARB_params args = { .teb = teb, .hDrawDC = draw_hdc, .hReadDC = read_hdc }; + NTSTATUS status; + + TRACE( "draw_hdc %p, read_hdc %p, handle %p\n", draw_hdc, read_hdc, handle ); + + if (!get_context_from_handle( handle, &args.hglrc )) return FALSE; + if ((status = UNIX_CALL( wglMakeContextCurrentARB, &args ))) WARN( "wglMakeContextCurrentARB returned %#lx\n", status ); + if (status || !args.ret) return FALSE; + + teb->glCurrentRC = handle; + teb->glReserved1[0] = draw_hdc; + teb->glReserved1[1] = read_hdc; + return TRUE; +} + /*********************************************************************** * wglGetCurrentReadDCARB * diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 779c5bb2153..c41d36f808e 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1882,8 +1882,9 @@ static void pop_internal_context( struct wgl_context *context ) driver_funcs->p_make_current( context->draw, context->read, context->driver_private ); } -static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context ) +static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC client_context ) { + struct wgl_context *context = opengl_context_from_handle( client_context ); struct wgl_context *prev_context = NtCurrentTeb()->glContext; BOOL created; int format; @@ -1930,9 +1931,9 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return TRUE; } -static BOOL win32u_wglMakeCurrent( HDC hdc, struct wgl_context *context ) +static BOOL win32u_wglMakeCurrent( HDC hdc, HGLRC client_context ) { - return win32u_wglMakeContextCurrentARB( hdc, hdc, context ); + return win32u_wglMakeContextCurrentARB( hdc, hdc, client_context ); } static void opengl_client_pbuffer_init( HPBUFFERARB client_pbuffer, struct pbuffer *pbuffer, const struct opengl_funcs *funcs ) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index e545418258a..47c5195091f 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -59,6 +59,18 @@ struct wgl_pixel_format int float_components; }; +struct opengl_client_context +{ + struct HGLRC__ obj; /* client object header */ + UINT64 unix_handle; + UINT64 unix_funcs; +}; + +static inline struct opengl_client_context *opengl_client_context_from_client( HGLRC client_context ) +{ + return CONTAINING_RECORD( client_context, struct opengl_client_context, obj ); +} + struct opengl_client_pbuffer { struct HPBUFFERARB__ obj; /* client object header */ @@ -82,14 +94,21 @@ struct opengl_drawable; struct wgl_context { - void *driver_private; /* driver context / private data */ - void *internal_context; /* driver context for win32u internal use */ - int format; /* pixel format of the context */ - struct opengl_drawable *draw; /* currently bound draw surface */ - struct opengl_drawable *read; /* currently bound read surface */ - GLenum error; /* wrapped GL error */ + HGLRC client_context; /* client side context pointer */ + void *driver_private; /* driver context / private data */ + void *internal_context; /* driver context for win32u internal use */ + int format; /* pixel format of the context */ + struct opengl_drawable *draw; /* currently bound draw surface */ + struct opengl_drawable *read; /* currently bound read surface */ + GLenum error; /* wrapped GL error */ }; +static inline struct wgl_context *opengl_context_from_handle( HGLRC client_context ) +{ + struct opengl_client_context *client = opengl_client_context_from_client( client_context ); + return client_context ? (struct wgl_context *)(UINT_PTR)client->unix_handle : NULL; +} + /* interface between opengl32 and win32u */ struct opengl_funcs { diff --git a/include/wine/wgl.h b/include/wine/wgl.h index 90b7be366c4..2c456d1dd8a 100644 --- a/include/wine/wgl.h +++ b/include/wine/wgl.h @@ -24,7 +24,6 @@ #define EGL_CAST(t,x) ((t)(x)) #endif -struct wgl_context; typedef void *EGLNativeDisplayType; typedef void *EGLNativePixmapType; typedef void *EGLNativeWindowType; @@ -6284,23 +6283,23 @@ void GLAPIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei heigh #endif typedef int (GLAPIENTRY *PFN_wglChoosePixelFormat)( HDC hDc, const PIXELFORMATDESCRIPTOR *pPfd ); -typedef BOOL (GLAPIENTRY *PFN_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ); -typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateContext)( HDC hDc ); -typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateLayerContext)( HDC hDc, int level ); -typedef BOOL (GLAPIENTRY *PFN_wglDeleteContext)( struct wgl_context * oldContext ); +typedef BOOL (GLAPIENTRY *PFN_wglCopyContext)( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ); +typedef HGLRC (GLAPIENTRY *PFN_wglCreateContext)( HDC hDc, HGLRC client_context ); +typedef HGLRC (GLAPIENTRY *PFN_wglCreateLayerContext)( HDC hDc, int level, HGLRC client_context ); +typedef BOOL (GLAPIENTRY *PFN_wglDeleteContext)( HGLRC oldContext ); typedef BOOL (GLAPIENTRY *PFN_wglDescribeLayerPlane)( HDC hDc, int pixelFormat, int layerPlane, UINT nBytes, LAYERPLANEDESCRIPTOR *plpd ); typedef int (GLAPIENTRY *PFN_wglDescribePixelFormat)( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ); -typedef struct wgl_context * (GLAPIENTRY *PFN_wglGetCurrentContext)(void); +typedef HGLRC (GLAPIENTRY *PFN_wglGetCurrentContext)(void); typedef HDC (GLAPIENTRY *PFN_wglGetCurrentDC)(void); typedef PROC (GLAPIENTRY *PFN_wglGetDefaultProcAddress)( LPCSTR lpszProc ); typedef int (GLAPIENTRY *PFN_wglGetLayerPaletteEntries)( HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr ); typedef int (GLAPIENTRY *PFN_wglGetPixelFormat)( HDC hdc ); typedef PROC (GLAPIENTRY *PFN_wglGetProcAddress)( LPCSTR lpszProc ); -typedef BOOL (GLAPIENTRY *PFN_wglMakeCurrent)( HDC hDc, struct wgl_context * newContext ); +typedef BOOL (GLAPIENTRY *PFN_wglMakeCurrent)( HDC hDc, HGLRC newContext ); typedef BOOL (GLAPIENTRY *PFN_wglRealizeLayerPalette)( HDC hdc, int iLayerPlane, BOOL bRealize ); typedef int (GLAPIENTRY *PFN_wglSetLayerPaletteEntries)( HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr ); typedef BOOL (GLAPIENTRY *PFN_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); -typedef BOOL (GLAPIENTRY *PFN_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); +typedef BOOL (GLAPIENTRY *PFN_wglShareLists)( HGLRC hrcSrvShare, HGLRC hrcSrvSource ); typedef BOOL (GLAPIENTRY *PFN_wglSwapBuffers)( HDC hdc ); typedef BOOL (GLAPIENTRY *PFN_wglSwapLayerBuffers)( HDC hdc, UINT fuFlags ); typedef BOOL (GLAPIENTRY *PFN_wglUseFontBitmapsA)( HDC hDC, DWORD first, DWORD count, DWORD listBase ); @@ -9519,7 +9518,7 @@ typedef void (GLAPIENTRY *PFN_glWriteMaskEXT)( GLuint res, GLuint in, GLen typedef void * (GLAPIENTRY *PFN_wglAllocateMemoryNV)( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); typedef BOOL (GLAPIENTRY *PFN_wglBindTexImageARB)( HPBUFFERARB hPbuffer, int iBuffer ); typedef BOOL (GLAPIENTRY *PFN_wglChoosePixelFormatARB)( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); -typedef struct wgl_context * (GLAPIENTRY *PFN_wglCreateContextAttribsARB)( HDC hDC, struct wgl_context * hShareContext, const int *attribList ); +typedef HGLRC (GLAPIENTRY *PFN_wglCreateContextAttribsARB)( HDC hDC, HGLRC hShareContext, const int *attribList, HGLRC client_context ); typedef HPBUFFERARB (GLAPIENTRY *PFN_wglCreatePbufferARB)( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList, HPBUFFERARB client_pbuffer ); typedef BOOL (GLAPIENTRY *PFN_wglDestroyPbufferARB)( HPBUFFERARB hPbuffer ); typedef void (GLAPIENTRY *PFN_wglFreeMemoryNV)( void *pointer ); @@ -9530,7 +9529,7 @@ typedef HDC (GLAPIENTRY *PFN_wglGetPbufferDCARB)( HPBUFFERARB hPbuffer ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribfvARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues ); typedef BOOL (GLAPIENTRY *PFN_wglGetPixelFormatAttribivARB)( HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues ); typedef int (GLAPIENTRY *PFN_wglGetSwapIntervalEXT)(void); -typedef BOOL (GLAPIENTRY *PFN_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, struct wgl_context * hglrc ); +typedef BOOL (GLAPIENTRY *PFN_wglMakeContextCurrentARB)( HDC hDrawDC, HDC hReadDC, HGLRC hglrc ); typedef BOOL (GLAPIENTRY *PFN_wglQueryCurrentRendererIntegerWINE)( GLenum attribute, GLuint *value ); typedef const GLchar * (GLAPIENTRY *PFN_wglQueryCurrentRendererStringWINE)( GLenum attribute ); typedef BOOL (GLAPIENTRY *PFN_wglQueryPbufferARB)( HPBUFFERARB hPbuffer, int iAttribute, int *piValue ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 17 +++++++++++------ dlls/win32u/opengl.c | 9 +++++---- include/wine/opengl_driver.h | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 17994a2c324..c061450b140 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -745,10 +745,12 @@ static BOOL is_any_extension_supported( struct context *ctx, const char *extensi static void set_gl_error( TEB *teb, GLenum error ) { const struct opengl_funcs *funcs = teb->glTable; + struct opengl_client_context *client; struct context *ctx; - if (!(ctx = get_current_context( teb, NULL, NULL )) || ctx->base.error) return; - if (!(ctx->base.error = funcs->p_glGetError())) ctx->base.error = error; + if (!(ctx = get_current_context( teb, NULL, NULL ))) return; + if (!(client = opengl_client_context_from_client( ctx->base.client_context ))) return; + if (!client->last_error && !(client->last_error = funcs->p_glGetError())) client->last_error = error; } static BOOL get_default_fbo_integer( struct context *ctx, struct opengl_drawable *draw, struct opengl_drawable *read, @@ -1961,13 +1963,16 @@ void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint fbo, GLenum pname, GL GLenum wrap_glGetError( TEB *teb ) { const struct opengl_funcs *funcs = teb->glTable; - struct wgl_context *ctx; + struct opengl_client_context *client; GLenum error, wrapped; + struct context *ctx; + + if (!(ctx = get_current_context( teb, NULL, NULL ))) return GL_INVALID_OPERATION; + if (!(client = opengl_client_context_from_client( ctx->base.client_context ))) return GL_INVALID_OPERATION; - if (!(ctx = &get_current_context( teb, NULL, NULL )->base)) return GL_INVALID_OPERATION; error = funcs->p_glGetError(); - wrapped = ctx->error; - ctx->error = GL_NO_ERROR; + wrapped = client->last_error; + client->last_error = GL_NO_ERROR; return wrapped ? wrapped : error; } diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index c41d36f808e..8e5b708a500 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2409,12 +2409,13 @@ static int win32u_wglGetSwapIntervalEXT(void) static void set_gl_error( GLenum error ) { - struct wgl_context *ctx = NtCurrentTeb()->glContext; const struct opengl_funcs *funcs = &display_funcs; + struct opengl_client_context *client; + struct wgl_context *ctx; - if (!ctx || ctx->error) return; - if ((ctx->error = funcs->p_glGetError())) return; - ctx->error = error; + if (!(ctx = NtCurrentTeb()->glContext)) return; + if (!(client = opengl_client_context_from_client( ctx->client_context ))) return; + if (!client->last_error && !(client->last_error = funcs->p_glGetError())) client->last_error = error; } static struct egl_platform *egl_platform_from_index( GLint index ) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 47c5195091f..366f600e002 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -64,6 +64,7 @@ struct opengl_client_context struct HGLRC__ obj; /* client object header */ UINT64 unix_handle; UINT64 unix_funcs; + GLenum last_error; }; static inline struct opengl_client_context *opengl_client_context_from_client( HGLRC client_context ) @@ -100,7 +101,6 @@ struct wgl_context int format; /* pixel format of the context */ struct opengl_drawable *draw; /* currently bound draw surface */ struct opengl_drawable *read; /* currently bound read surface */ - GLenum error; /* wrapped GL error */ }; static inline struct wgl_context *opengl_context_from_handle( HGLRC client_context ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 35 +++++-- dlls/opengl32/private.h | 2 + dlls/opengl32/tests/opengl.c | 14 +++ dlls/opengl32/thunks.c | 51 +++------- dlls/opengl32/unix_private.h | 5 + dlls/opengl32/unix_thunks.c | 54 +++++------ dlls/opengl32/unix_thunks.h | 9 +- dlls/opengl32/unix_wgl.c | 177 ++++++++--------------------------- dlls/opengl32/wgl.c | 153 +++++++++++++++++++++++++++++- include/wine/opengl_driver.h | 6 ++ 10 files changed, 281 insertions(+), 225 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index d71a715e008..be1c67a9bfa 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -165,8 +165,12 @@ my %manual_win_functions = ); my %manual_win_thunks = ( + "glCreateSyncFromCLeventARB" => 1, + "glDeleteSync" => 1, + "glFenceSync" => 1, "glGetString" => 1, "glGetStringi" => 1, + "glImportSyncEXT" => 1, "wglChoosePixelFormatARB" => 1, "wglCreateContext" => 1, "wglCreateContextAttribsARB" => 1, @@ -188,12 +192,14 @@ my %manual_win_thunks = my %manual_unix_thunks = ( "glClear" => 1, + "glCreateSyncFromCLeventARB" => 1, "glDebugMessageCallback" => 1, "glDebugMessageCallbackAMD" => 1, "glDebugMessageCallbackARB" => 1, "glDrawBuffer" => 1, "glDrawBuffers" => 1, "glDrawPixels" => 1, + "glFenceSync" => 1, "glFinish" => 1, "glFlush" => 1, "glFramebufferDrawBufferEXT" => 1, @@ -209,6 +215,7 @@ my %manual_unix_thunks = "glGetString" => 1, "glGetStringi" => 1, "glGetUnsignedBytevEXT" => 1, + "glImportSyncEXT" => 1, "glNamedFramebufferDrawBuffer" => 1, "glNamedFramebufferDrawBuffers" => 1, "glNamedFramebufferReadBuffer" => 1, @@ -289,10 +296,7 @@ my %map_default_fbo_thunks = my %manual_wow64_wrappers = ( "glBufferStorage" => 0, - "glClientWaitSync" => 0, "glDeleteBuffers" => 0, - "glDeleteSync" => 0, - "glFenceSync" => 0, "glFlushMappedBufferRange" => 0, "glFlushMappedNamedBufferRange" => 0, "glFlushMappedNamedBufferRangeEXT" => 0, @@ -300,8 +304,6 @@ my %manual_wow64_wrappers = "glGetBufferPointervARB" => 0, "glGetNamedBufferPointerv" => 0, "glGetNamedBufferPointervEXT" => 0, - "glGetSynciv" => 0, - "glIsSync" => 0, "glMapBuffer" => 0, "glMapBufferARB" => 0, "glMapBufferRange" => 0, @@ -315,7 +317,6 @@ my %manual_wow64_wrappers = "glUnmapBufferARB" => 0, "glUnmapNamedBuffer" => 0, "glUnmapNamedBufferEXT" => 0, - "glWaitSync" => 0, ); my %wow64_invalidate_buffer = ( @@ -516,6 +517,10 @@ sub generate_unix_thunk($$$$) { $call_args .= " (" . $arg_type . ")ULongToPtr(params->$pname),"; } + elsif ($arg_type =~ /GLsync/) + { + $call_args .= " get_unix_sync( ULongToPtr(params->$pname) ),"; + } else { $call_args .= " ULongToPtr(params->$pname),"; @@ -523,7 +528,7 @@ sub generate_unix_thunk($$$$) $need_lock = 1 if $arg_type =~ /GLsync/; } } - $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB|HGLRC/; + $call_args .= " UlongToHandle( params->ret )," if $func_ret =~ /HPBUFFERARB|HGLRC|GLsync/; if (!is_void_func($func)) { my $ret_type = get_arg_type( $func->[0] ); @@ -538,7 +543,7 @@ sub generate_unix_thunk($$$$) elsif ($ptype eq "PTR32") { $ret_expr .= "(UINT_PTR)"; - $need_manual_thunk = 1 if $func_ret !~ /HDC|HPBUFFERARB|HGLRC/; + $need_manual_thunk = 1 if $func_ret !~ /HDC|HPBUFFERARB|HGLRC|GLsync/; } } $ret .= " } *params = args;\n"; @@ -567,9 +572,16 @@ sub generate_unix_thunk($$$$) { my $ptype = get_arg_type( $arg ); my $pname = get_arg_name( $arg ); - $call_args .= " params->$pname,"; + if ($ptype =~ /GLsync/) + { + $call_args .= " get_unix_sync( params->$pname ),"; + } + else + { + $call_args .= " params->$pname,"; + } } - $call_args .= " params->ret," if $func_ret =~ /HPBUFFERARB|HGLRC/; + $call_args .= " params->ret," if $func_ret =~ /HPBUFFERARB|HGLRC|GLsync/; $ret .= " struct $name\_params *params = args;\n"; } $ret .= $vars; @@ -663,6 +675,7 @@ sub generate_wrapper_declaration($$$) } $ret .= " HPBUFFERARB handle," if $ret_type =~ /HPBUFFERARB/; $ret .= " HGLRC handle," if $ret_type =~ /HGLRC/; + $ret .= " GLsync handle," if $ret_type =~ /GLsync/; $ret =~ s/,$/ /; $ret .= ");\n"; return $ret; @@ -673,6 +686,7 @@ sub get_handle_function($) my $ptype = shift; return "get_pbuffer_from_handle" if $ptype =~ /HPBUFFERARB/; return "get_context_from_handle" if $ptype =~ /HGLRC/; + return "get_sync_from_handle" if $ptype =~ /GLsync/; return 0; } @@ -696,6 +710,7 @@ sub generate_win_thunk($$) if (my $get_handle = get_handle_function( $ptype )) { my $retval = is_void_func($func) ? "return;" : "return 0;"; + $retval = "{ set_gl_error( GL_INVALID_VALUE ); $retval }" if $ptype =~ /GLsync/ && $name !~ /glIsSync/; $checks .= " if (!$get_handle( $pname, &args.$pname )) $retval\n"; } else diff --git a/dlls/opengl32/private.h b/dlls/opengl32/private.h index 5ee9a0fce2d..42298ac9ccc 100644 --- a/dlls/opengl32/private.h +++ b/dlls/opengl32/private.h @@ -34,5 +34,7 @@ extern const void *extension_procs[]; extern int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ); extern BOOL get_pbuffer_from_handle( HPBUFFERARB handle, HPBUFFERARB *obj ); extern BOOL get_context_from_handle( HGLRC handle, HGLRC *obj ); +extern BOOL get_sync_from_handle( GLsync handle, GLsync *obj ); +extern void set_gl_error( GLenum error ); #endif /* __WINE_OPENGL32_PRIVATE_H */ diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 656872ec800..5882d75f200 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -112,6 +112,7 @@ static PFN_glFlushMappedBufferRange pglFlushMappedBufferRange; static PFN_glFlushMappedNamedBufferRange pglFlushMappedNamedBufferRange; static PFN_glGenBuffers pglGenBuffers; static PFN_glIsSync pglIsSync; +static PFN_glFenceSync pglFenceSync; static PFN_glMapBuffer pglMapBuffer; static PFN_glMapBufferRange pglMapBufferRange; static PFN_glMapNamedBuffer pglMapNamedBuffer; @@ -198,6 +199,7 @@ static void init_functions(void) GET_PROC(glFlushMappedNamedBufferRange) GET_PROC(glGenBuffers) GET_PROC(glIsSync) + GET_PROC(glFenceSync) GET_PROC(glMapBuffer) GET_PROC(glMapBufferRange) GET_PROC(glMapNamedBuffer) @@ -3500,6 +3502,7 @@ static void test_gl_error( HDC hdc ) HGLRC rc, old_rc; int i; BOOL ret; + GLsync sync; if (!pglDeleteSync) { @@ -3536,6 +3539,17 @@ static void test_gl_error( HDC hdc ) ok( !ret, "glIsSync returned %x\n", ret ); check_gl_error( GL_NO_ERROR ); + sync = pglFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); + ok( !!sync, "got %p\n", sync ); + check_gl_error( GL_NO_ERROR ); + + ret = pglIsSync( sync ); + ok( !!ret, "glIsSync returned %x\n", ret ); + check_gl_error( GL_NO_ERROR ); + + pglDeleteSync( sync ); + check_gl_error( GL_NO_ERROR ); + wglMakeCurrent( hdc, old_rc ); } diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index 437ae70fe9c..a9d08f300d9 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -4207,9 +4207,10 @@ static void WINAPI glClientWaitSemaphoreui64NVX( GLsizei fenceObjectCount, const static GLenum WINAPI glClientWaitSync( GLsync sync, GLbitfield flags, GLuint64 timeout ) { - struct glClientWaitSync_params args = { .teb = NtCurrentTeb(), .sync = sync, .flags = flags, .timeout = timeout }; + struct glClientWaitSync_params args = { .teb = NtCurrentTeb(), .flags = flags, .timeout = timeout }; NTSTATUS status; TRACE( "sync %p, flags %d, timeout %s\n", sync, flags, wine_dbgstr_longlong(timeout) ); + if (!get_sync_from_handle( sync, &args.sync )) { set_gl_error( GL_INVALID_VALUE ); return 0; } if ((status = UNIX_CALL( glClientWaitSync, &args ))) WARN( "glClientWaitSync returned %#lx\n", status ); return args.ret; } @@ -5461,15 +5462,6 @@ static void WINAPI glCreateStatesNV( GLsizei n, GLuint *states ) if ((status = UNIX_CALL( glCreateStatesNV, &args ))) WARN( "glCreateStatesNV returned %#lx\n", status ); } -static GLsync WINAPI glCreateSyncFromCLeventARB( struct _cl_context *context, struct _cl_event *event, GLbitfield flags ) -{ - struct glCreateSyncFromCLeventARB_params args = { .teb = NtCurrentTeb(), .context = context, .event = event, .flags = flags }; - NTSTATUS status; - TRACE( "context %p, event %p, flags %d\n", context, event, flags ); - if ((status = UNIX_CALL( glCreateSyncFromCLeventARB, &args ))) WARN( "glCreateSyncFromCLeventARB returned %#lx\n", status ); - return args.ret; -} - static void WINAPI glCreateTextures( GLenum target, GLsizei n, GLuint *textures ) { struct glCreateTextures_params args = { .teb = NtCurrentTeb(), .target = target, .n = n, .textures = textures }; @@ -5870,14 +5862,6 @@ static void WINAPI glDeleteStatesNV( GLsizei n, const GLuint *states ) if ((status = UNIX_CALL( glDeleteStatesNV, &args ))) WARN( "glDeleteStatesNV returned %#lx\n", status ); } -static void WINAPI glDeleteSync( GLsync sync ) -{ - struct glDeleteSync_params args = { .teb = NtCurrentTeb(), .sync = sync }; - NTSTATUS status; - TRACE( "sync %p\n", sync ); - if ((status = UNIX_CALL( glDeleteSync, &args ))) WARN( "glDeleteSync returned %#lx\n", status ); -} - static void WINAPI glDeleteTexturesEXT( GLsizei n, const GLuint *textures ) { struct glDeleteTexturesEXT_params args = { .teb = NtCurrentTeb(), .n = n, .textures = textures }; @@ -6814,15 +6798,6 @@ static void WINAPI glFeedbackBufferxOES( GLsizei n, GLenum type, const GLfixed * if ((status = UNIX_CALL( glFeedbackBufferxOES, &args ))) WARN( "glFeedbackBufferxOES returned %#lx\n", status ); } -static GLsync WINAPI glFenceSync( GLenum condition, GLbitfield flags ) -{ - struct glFenceSync_params args = { .teb = NtCurrentTeb(), .condition = condition, .flags = flags }; - NTSTATUS status; - TRACE( "condition %d, flags %d\n", condition, flags ); - if ((status = UNIX_CALL( glFenceSync, &args ))) WARN( "glFenceSync returned %#lx\n", status ); - return args.ret; -} - static void WINAPI glFinalCombinerInputNV( GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage ) { struct glFinalCombinerInputNV_params args = { .teb = NtCurrentTeb(), .variable = variable, .input = input, .mapping = mapping, .componentUsage = componentUsage }; @@ -10077,9 +10052,10 @@ static GLint WINAPI glGetSubroutineUniformLocation( GLuint program, GLenum shade static void WINAPI glGetSynciv( GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values ) { - struct glGetSynciv_params args = { .teb = NtCurrentTeb(), .sync = sync, .pname = pname, .count = count, .length = length, .values = values }; + struct glGetSynciv_params args = { .teb = NtCurrentTeb(), .pname = pname, .count = count, .length = length, .values = values }; NTSTATUS status; TRACE( "sync %p, pname %d, count %d, length %p, values %p\n", sync, pname, count, length, values ); + if (!get_sync_from_handle( sync, &args.sync )) { set_gl_error( GL_INVALID_VALUE ); return; } if ((status = UNIX_CALL( glGetSynciv, &args ))) WARN( "glGetSynciv returned %#lx\n", status ); } @@ -11422,15 +11398,6 @@ static void WINAPI glImportSemaphoreWin32NameEXT( GLuint semaphore, GLenum handl if ((status = UNIX_CALL( glImportSemaphoreWin32NameEXT, &args ))) WARN( "glImportSemaphoreWin32NameEXT returned %#lx\n", status ); } -static GLsync WINAPI glImportSyncEXT( GLenum external_sync_type, GLintptr external_sync, GLbitfield flags ) -{ - struct glImportSyncEXT_params args = { .teb = NtCurrentTeb(), .external_sync_type = external_sync_type, .external_sync = external_sync, .flags = flags }; - NTSTATUS status; - TRACE( "external_sync_type %d, external_sync %Id, flags %d\n", external_sync_type, external_sync, flags ); - if ((status = UNIX_CALL( glImportSyncEXT, &args ))) WARN( "glImportSyncEXT returned %#lx\n", status ); - return args.ret; -} - static void WINAPI glIndexFormatNV( GLenum type, GLsizei stride ) { struct glIndexFormatNV_params args = { .teb = NtCurrentTeb(), .type = type, .stride = stride }; @@ -11891,9 +11858,10 @@ static GLboolean WINAPI glIsStateNV( GLuint state ) static GLboolean WINAPI glIsSync( GLsync sync ) { - struct glIsSync_params args = { .teb = NtCurrentTeb(), .sync = sync }; + struct glIsSync_params args = { .teb = NtCurrentTeb() }; NTSTATUS status; TRACE( "sync %p\n", sync ); + if (!get_sync_from_handle( sync, &args.sync )) return 0; if ((status = UNIX_CALL( glIsSync, &args ))) WARN( "glIsSync returned %#lx\n", status ); return args.ret; } @@ -24143,9 +24111,10 @@ static void WINAPI glWaitSemaphoreui64NVX( GLuint waitGpu, GLsizei fenceObjectCo static void WINAPI glWaitSync( GLsync sync, GLbitfield flags, GLuint64 timeout ) { - struct glWaitSync_params args = { .teb = NtCurrentTeb(), .sync = sync, .flags = flags, .timeout = timeout }; + struct glWaitSync_params args = { .teb = NtCurrentTeb(), .flags = flags, .timeout = timeout }; NTSTATUS status; TRACE( "sync %p, flags %d, timeout %s\n", sync, flags, wine_dbgstr_longlong(timeout) ); + if (!get_sync_from_handle( sync, &args.sync )) { set_gl_error( GL_INVALID_VALUE ); return; } if ((status = UNIX_CALL( glWaitSync, &args ))) WARN( "glWaitSync returned %#lx\n", status ); } @@ -24823,7 +24792,11 @@ static BOOL WINAPI wglSwapIntervalEXT( int interval ) return args.ret; } +extern GLsync WINAPI glCreateSyncFromCLeventARB( struct _cl_context *context, struct _cl_event *event, GLbitfield flags ); +extern void WINAPI glDeleteSync( GLsync sync ); +extern GLsync WINAPI glFenceSync( GLenum condition, GLbitfield flags ); extern const GLubyte * WINAPI glGetStringi( GLenum name, GLuint index ); +extern GLsync WINAPI glImportSyncEXT( GLenum external_sync_type, GLintptr external_sync, GLbitfield flags ); extern BOOL WINAPI wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats ); extern HGLRC WINAPI wglCreateContextAttribsARB( HDC hDC, HGLRC hShareContext, const int *attribList ); extern HPBUFFERARB WINAPI wglCreatePbufferARB( HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList ); diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index e1076fe7831..d5ec8cee7c4 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -69,6 +69,11 @@ static inline const struct opengl_funcs *get_context_funcs( HGLRC client_context return client_context ? (struct opengl_funcs *)(UINT_PTR)client->unix_funcs : NULL; } +static inline GLsync get_unix_sync( GLsync sync ) +{ + return (GLsync)(UINT_PTR)sync->unix_handle; +} + #ifdef _WIN64 static inline void *copy_wow64_ptr32s( UINT_PTR address, ULONG count ) diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 41ce0f2d5e1..07314125675 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -5240,7 +5240,7 @@ static NTSTATUS ext_glClientWaitSync( void *args ) struct glClientWaitSync_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glClientWaitSync) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_glClientWaitSync( params->sync, params->flags, params->timeout ); + params->ret = funcs->p_glClientWaitSync( get_unix_sync( params->sync ), params->flags, params->timeout ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -6805,7 +6805,7 @@ static NTSTATUS ext_glCreateSyncFromCLeventARB( void *args ) struct glCreateSyncFromCLeventARB_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glCreateSyncFromCLeventARB) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_glCreateSyncFromCLeventARB( params->context, params->event, params->flags ); + params->ret = wrap_glCreateSyncFromCLeventARB( params->teb, params->context, params->event, params->flags, params->ret ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -7315,7 +7315,7 @@ static NTSTATUS ext_glDeleteSync( void *args ) struct glDeleteSync_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glDeleteSync) return STATUS_NOT_IMPLEMENTED; - funcs->p_glDeleteSync( params->sync ); + funcs->p_glDeleteSync( get_unix_sync( params->sync ) ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -8495,7 +8495,7 @@ static NTSTATUS ext_glFenceSync( void *args ) struct glFenceSync_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glFenceSync) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_glFenceSync( params->condition, params->flags ); + params->ret = wrap_glFenceSync( params->teb, params->condition, params->flags, params->ret ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -12299,7 +12299,7 @@ static NTSTATUS ext_glGetSynciv( void *args ) struct glGetSynciv_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glGetSynciv) return STATUS_NOT_IMPLEMENTED; - funcs->p_glGetSynciv( params->sync, params->pname, params->count, params->length, params->values ); + funcs->p_glGetSynciv( get_unix_sync( params->sync ), params->pname, params->count, params->length, params->values ); return STATUS_SUCCESS; } @@ -13824,7 +13824,7 @@ static NTSTATUS ext_glImportSyncEXT( void *args ) struct glImportSyncEXT_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glImportSyncEXT) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_glImportSyncEXT( params->external_sync_type, params->external_sync, params->flags ); + params->ret = wrap_glImportSyncEXT( params->teb, params->external_sync_type, params->external_sync, params->flags, params->ret ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -14332,7 +14332,7 @@ static NTSTATUS ext_glIsSync( void *args ) struct glIsSync_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glIsSync) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_glIsSync( params->sync ); + params->ret = funcs->p_glIsSync( get_unix_sync( params->sync ) ); return STATUS_SUCCESS; } @@ -29588,7 +29588,7 @@ static NTSTATUS ext_glWaitSync( void *args ) struct glWaitSync_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; if (!funcs->p_glWaitSync) return STATUS_NOT_IMPLEMENTED; - funcs->p_glWaitSync( params->sync, params->flags, params->timeout ); + funcs->p_glWaitSync( get_unix_sync( params->sync ), params->flags, params->timeout ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -42408,9 +42408,7 @@ static NTSTATUS wow64_ext_glClientWaitSync( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glClientWaitSync) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = wow64_glClientWaitSync( teb, ULongToPtr(params->sync), params->flags, params->timeout ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = funcs->p_glClientWaitSync( get_unix_sync( ULongToPtr(params->sync) ), params->flags, params->timeout ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -45411,8 +45409,12 @@ static NTSTATUS wow64_ext_glCreateSyncFromCLeventARB( void *args ) GLbitfield flags; PTR32 ret; } *params = args; - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + TEB *teb = get_teb64( params->teb ); + const struct opengl_funcs *funcs = teb->glTable; + if (!funcs->p_glCreateSyncFromCLeventARB) return STATUS_NOT_IMPLEMENTED; + params->ret = (UINT_PTR)wrap_glCreateSyncFromCLeventARB( teb, ULongToPtr(params->context), ULongToPtr(params->event), params->flags, UlongToHandle( params->ret ) ); + set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); + return STATUS_SUCCESS; } static NTSTATUS wow64_ext_glCreateTextures( void *args ) @@ -46264,9 +46266,7 @@ static NTSTATUS wow64_ext_glDeleteSync( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glDeleteSync) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - wow64_glDeleteSync( teb, ULongToPtr(params->sync) ); - pthread_mutex_unlock( &wgl_lock ); + funcs->p_glDeleteSync( get_unix_sync( ULongToPtr(params->sync) ) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -48232,7 +48232,7 @@ static NTSTATUS wow64_ext_glFenceSync( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glFenceSync) return STATUS_NOT_IMPLEMENTED; - params->ret = (UINT_PTR)wow64_glFenceSync( teb, params->condition, params->flags ); + params->ret = (UINT_PTR)wrap_glFenceSync( teb, params->condition, params->flags, UlongToHandle( params->ret ) ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -55016,9 +55016,7 @@ static NTSTATUS wow64_ext_glGetSynciv( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glGetSynciv) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - wow64_glGetSynciv( teb, ULongToPtr(params->sync), params->pname, params->count, ULongToPtr(params->length), ULongToPtr(params->values) ); - pthread_mutex_unlock( &wgl_lock ); + funcs->p_glGetSynciv( get_unix_sync( ULongToPtr(params->sync) ), params->pname, params->count, ULongToPtr(params->length), ULongToPtr(params->values) ); return STATUS_SUCCESS; } @@ -57774,8 +57772,12 @@ static NTSTATUS wow64_ext_glImportSyncEXT( void *args ) GLbitfield flags; PTR32 ret; } *params = args; - FIXME( "params %p stub!\n", params ); - return STATUS_NOT_IMPLEMENTED; + TEB *teb = get_teb64( params->teb ); + const struct opengl_funcs *funcs = teb->glTable; + if (!funcs->p_glImportSyncEXT) return STATUS_NOT_IMPLEMENTED; + params->ret = (UINT_PTR)wrap_glImportSyncEXT( teb, params->external_sync_type, (GLintptr)ULongToPtr(params->external_sync), params->flags, UlongToHandle( params->ret ) ); + set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); + return STATUS_SUCCESS; } static NTSTATUS wow64_ext_glIndexFormatNV( void *args ) @@ -58633,9 +58635,7 @@ static NTSTATUS wow64_ext_glIsSync( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glIsSync) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - params->ret = wow64_glIsSync( teb, ULongToPtr(params->sync) ); - pthread_mutex_unlock( &wgl_lock ); + params->ret = funcs->p_glIsSync( get_unix_sync( ULongToPtr(params->sync) ) ); return STATUS_SUCCESS; } @@ -85342,9 +85342,7 @@ static NTSTATUS wow64_ext_glWaitSync( void *args ) TEB *teb = get_teb64( params->teb ); const struct opengl_funcs *funcs = teb->glTable; if (!funcs->p_glWaitSync) return STATUS_NOT_IMPLEMENTED; - pthread_mutex_lock( &wgl_lock ); - wow64_glWaitSync( teb, ULongToPtr(params->sync), params->flags, params->timeout ); - pthread_mutex_unlock( &wgl_lock ); + funcs->p_glWaitSync( get_unix_sync( ULongToPtr(params->sync) ), params->flags, params->timeout ); set_context_attribute( teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_thunks.h b/dlls/opengl32/unix_thunks.h index e23c9e9e5bd..2c0824e0268 100644 --- a/dlls/opengl32/unix_thunks.h +++ b/dlls/opengl32/unix_thunks.h @@ -23,10 +23,12 @@ extern const GLubyte *wrap_glGetString( TEB *teb, GLenum name ); extern void wrap_glReadBuffer( TEB *teb, GLenum src ); extern void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ); extern void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height ); +extern GLsync wrap_glCreateSyncFromCLeventARB( TEB *teb, struct _cl_context *context, struct _cl_event *event, GLbitfield flags, GLsync handle ); extern void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const void *userParam ); extern void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, void *userParam ); extern void wrap_glDebugMessageCallbackARB( TEB *teb, GLDEBUGPROCARB callback, const void *userParam ); extern void wrap_glDrawBuffers( TEB *teb, GLsizei n, const GLenum *bufs ); +extern GLsync wrap_glFenceSync( TEB *teb, GLenum condition, GLbitfield flags, GLsync handle ); extern void wrap_glFramebufferDrawBufferEXT( TEB *teb, GLuint framebuffer, GLenum mode ); extern void wrap_glFramebufferDrawBuffersEXT( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glFramebufferReadBufferEXT( TEB *teb, GLuint framebuffer, GLenum mode ); @@ -34,6 +36,7 @@ extern void wrap_glGetFramebufferParameterivEXT( TEB *teb, GLuint framebuffer, G extern void wrap_glGetInteger64v( TEB *teb, GLenum pname, GLint64 *data ); extern const GLubyte *wrap_glGetStringi( TEB *teb, GLenum name, GLuint index ); extern void wrap_glGetUnsignedBytevEXT( TEB *teb, GLenum pname, GLubyte *data ); +extern GLsync wrap_glImportSyncEXT( TEB *teb, GLenum external_sync_type, GLintptr external_sync, GLbitfield flags, GLsync handle ); extern void wrap_glNamedFramebufferDrawBuffer( TEB *teb, GLuint framebuffer, GLenum buf ); extern void wrap_glNamedFramebufferDrawBuffers( TEB *teb, GLuint framebuffer, GLsizei n, const GLenum *bufs ); extern void wrap_glNamedFramebufferReadBuffer( TEB *teb, GLuint framebuffer, GLenum src ); @@ -42,10 +45,7 @@ extern BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC hDrawDC, HDC hReadDC, H #ifdef _WIN64 extern void wow64_glBufferStorage( TEB *teb, GLenum target, GLsizeiptr size, const void *data, GLbitfield flags ); -extern GLenum wow64_glClientWaitSync( TEB *teb, GLsync sync, GLbitfield flags, GLuint64 timeout ); extern void wow64_glDeleteBuffers( TEB *teb, GLsizei n, const GLuint *buffers ); -extern void wow64_glDeleteSync( TEB *teb, GLsync sync ); -extern GLsync wow64_glFenceSync( TEB *teb, GLenum condition, GLbitfield flags ); extern void wow64_glFlushMappedBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeiptr length ); extern void wow64_glFlushMappedNamedBufferRange( TEB *teb, GLuint buffer, GLintptr offset, GLsizeiptr length ); extern void wow64_glFlushMappedNamedBufferRangeEXT( TEB *teb, GLuint buffer, GLintptr offset, GLsizeiptr length ); @@ -53,8 +53,6 @@ extern void wow64_glGetBufferPointerv( TEB *teb, GLenum target, GLenum pname, PT extern void wow64_glGetBufferPointervARB( TEB *teb, GLenum target, GLenum pname, PTR32 *params ); extern void wow64_glGetNamedBufferPointerv( TEB *teb, GLuint buffer, GLenum pname, PTR32 *params ); extern void wow64_glGetNamedBufferPointervEXT( TEB *teb, GLuint buffer, GLenum pname, PTR32 *params ); -extern void wow64_glGetSynciv( TEB *teb, GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values ); -extern GLboolean wow64_glIsSync( TEB *teb, GLsync sync ); extern void *wow64_glMapBuffer( TEB *teb, GLenum target, GLenum access ); extern void *wow64_glMapBufferARB( TEB *teb, GLenum target, GLenum access ); extern void *wow64_glMapBufferRange( TEB *teb, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access ); @@ -68,5 +66,4 @@ extern GLboolean wow64_glUnmapBuffer( TEB *teb, GLenum target ); extern GLboolean wow64_glUnmapBufferARB( TEB *teb, GLenum target ); extern GLboolean wow64_glUnmapNamedBuffer( TEB *teb, GLuint buffer ); extern GLboolean wow64_glUnmapNamedBufferEXT( TEB *teb, GLuint buffer ); -extern void wow64_glWaitSync( TEB *teb, GLsync sync, GLbitfield flags, GLuint64 timeout ); #endif diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index c061450b140..09b1bbf063b 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -56,14 +56,6 @@ static BOOL is_wow64(void) static UINT64 call_gl_debug_message_callback; pthread_mutex_t wgl_lock = PTHREAD_MUTEX_INITIALIZER; -/* handle management */ - -enum wgl_handle_type -{ - HANDLE_GLSYNC = 2 << 12, - HANDLE_TYPE_MASK = 15 << 12, -}; - /* context state management */ struct pixel_mode_state @@ -1976,6 +1968,45 @@ GLenum wrap_glGetError( TEB *teb ) return wrapped ? wrapped : error; } +GLsync wrap_glCreateSyncFromCLeventARB( TEB *teb, struct _cl_context *context, struct _cl_event *event, GLbitfield flags, GLsync client_sync ) +{ + const struct opengl_funcs *funcs = teb->glTable; + GLsync sync; + + FIXME( "stub!\n" ); + + if (!(sync = funcs->p_glCreateSyncFromCLeventARB( context, event, flags ))) return NULL; + client_sync->unix_handle = (UINT_PTR)sync; + + return client_sync; +} + +GLsync wrap_glFenceSync( TEB *teb, GLenum condition, GLbitfield flags, GLsync client_sync ) +{ + const struct opengl_funcs *funcs = teb->glTable; + GLsync sync; + + TRACE( "condition %#x, flags %#x, client_sync %p\n", condition, flags, client_sync ); + + if (!(sync = funcs->p_glFenceSync( condition, flags ))) return NULL; + client_sync->unix_handle = (UINT_PTR)sync; + + return client_sync; +} + +GLsync wrap_glImportSyncEXT( TEB *teb, GLenum external_sync_type, GLintptr external_sync, GLbitfield flags, GLsync client_sync ) +{ + const struct opengl_funcs *funcs = teb->glTable; + GLsync sync; + + FIXME( "stub!\n" ); + + if (!(sync = funcs->p_glImportSyncEXT( external_sync_type, external_sync, flags ))) return NULL; + client_sync->unix_handle = (UINT_PTR)sync; + + return client_sync; +} + NTSTATUS process_attach( void *args ) { struct process_attach_params *params = args; @@ -2074,136 +2105,6 @@ NTSTATUS return_wow64_string( const void *str, PTR32 *wow64_str ) return STATUS_BUFFER_TOO_SMALL; } -struct wgl_handle -{ - UINT handle; - const struct opengl_funcs *funcs; - union - { - GLsync sync; /* for HANDLE_GLSYNC */ - struct wgl_handle *next; /* for free handles */ - void *data; - } u; -}; - -#define MAX_WGL_HANDLES 1024 -static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; -static struct wgl_handle *next_free; -static unsigned int handle_count; - -static 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 HANDLE alloc_handle( enum wgl_handle_type type, const struct opengl_funcs *funcs, void *user_ptr ) -{ - HANDLE handle = 0; - struct wgl_handle *ptr = NULL; - - 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.data = user_ptr; - handle = next_handle( ptr, type ); - } - else RtlSetLastWin32Error( ERROR_NOT_ENOUGH_MEMORY ); - 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; -} - -static struct wgl_handle *get_handle_ptr( HANDLE handle ) -{ - unsigned int index = LOWORD( handle ) & ~HANDLE_TYPE_MASK; - - if (index < handle_count && ULongToHandle(wgl_handles[index].handle) == handle) - return &wgl_handles[index]; - - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return NULL; -} - -static struct wgl_handle *get_sync_ptr( TEB *teb, GLsync sync ) -{ - struct wgl_handle *handle = get_handle_ptr( sync ); - if (!handle) set_gl_error( teb, GL_INVALID_VALUE ); - return handle; -} - -GLenum wow64_glClientWaitSync( TEB *teb, GLsync sync, GLbitfield flags, GLuint64 timeout ) -{ - const struct opengl_funcs *funcs = teb->glTable; - struct wgl_handle *handle; - - if (!(handle = get_sync_ptr( teb, sync ))) return GL_INVALID_VALUE; - return funcs->p_glClientWaitSync( handle->u.sync, flags, timeout ); -} - -void wow64_glDeleteSync( TEB *teb, GLsync sync ) -{ - const struct opengl_funcs *funcs = teb->glTable; - struct wgl_handle *handle; - - if ((handle = get_sync_ptr( teb, sync ))) - { - funcs->p_glDeleteSync( handle->u.sync ); - free_handle_ptr( handle ); - } -} - -GLsync wow64_glFenceSync( TEB *teb, GLenum condition, GLbitfield flags ) -{ - const struct opengl_funcs *funcs = teb->glTable; - GLsync sync, handle; - - if (!(sync = funcs->p_glFenceSync( condition, flags ))) return NULL; - - pthread_mutex_lock( &wgl_lock ); - if (!(handle = alloc_handle( HANDLE_GLSYNC, NULL, sync ))) funcs->p_glDeleteSync( sync ); - pthread_mutex_unlock( &wgl_lock ); - return handle; -} - -void wow64_glGetSynciv( TEB *teb, GLsync sync, GLenum pname, GLsizei count, GLsizei *length, GLint *values ) -{ - const struct opengl_funcs *funcs = teb->glTable; - struct wgl_handle *handle; - - if ((handle = get_sync_ptr( teb, sync ))) funcs->p_glGetSynciv( handle->u.sync, pname, count, length, values ); -} - -GLboolean wow64_glIsSync( TEB *teb, GLsync sync ) -{ - const struct opengl_funcs *funcs = teb->glTable; - struct wgl_handle *handle; - - if (!(handle = get_handle_ptr( sync ))) return FALSE; - return funcs->p_glIsSync( handle->u.sync ); -} - -void wow64_glWaitSync( TEB *teb, GLsync sync, GLbitfield flags, GLuint64 timeout ) -{ - const struct opengl_funcs *funcs = teb->glTable; - struct wgl_handle *handle; - - if ((handle = get_sync_ptr( teb, sync ))) funcs->p_glWaitSync( handle->u.sync, flags, timeout ); -} - static GLint get_buffer_param( TEB *teb, GLenum target, GLenum param ) { const struct opengl_funcs *funcs = teb->glTable; diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index de39feb3405..9999bbdae2f 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -238,6 +238,17 @@ BOOL WINAPI wglDestroyPbufferARB( HPBUFFERARB handle ) return args.ret; } +struct context +{ + struct opengl_client_context base; + struct handle_table syncs; +}; + +static struct context *context_from_opengl_client_context( struct opengl_client_context *base ) +{ + return CONTAINING_RECORD( base, struct context, base ); +} + static struct opengl_client_context *opengl_client_context_from_handle( HGLRC handle ) { struct handle_entry *ptr; @@ -245,16 +256,21 @@ static struct opengl_client_context *opengl_client_context_from_handle( HGLRC ha return ptr->context; } +static struct context *context_from_handle( HGLRC handle ) +{ + return context_from_opengl_client_context( opengl_client_context_from_handle( handle ) ); +} + BOOL get_context_from_handle( HGLRC handle, HGLRC *obj ) { - struct opengl_client_context *context = opengl_client_context_from_handle( handle ); - *obj = context ? &context->obj : NULL; + struct context *context = context_from_handle( handle ); + *obj = context ? &context->base.obj : NULL; return context || !handle; } static struct handle_entry *alloc_client_context(void) { - struct opengl_client_context *context; + struct context *context; struct handle_entry *ptr; if (!(context = calloc( 1, sizeof(*context) ))) return NULL; @@ -269,11 +285,18 @@ static struct handle_entry *alloc_client_context(void) static void free_client_context( struct handle_entry *ptr ) { - struct opengl_client_context *context = ptr->context; + struct context *context = context_from_opengl_client_context( ptr->context ); free_handle( &contexts, ptr ); free( context ); } +void set_gl_error( GLenum error ) +{ + struct opengl_client_context *context; + if (!(context = opengl_client_context_from_handle( NtCurrentTeb()->glCurrentRC ))) return; + if (!context->last_error && !(context->last_error = glGetError())) context->last_error = error; +} + HGLRC WINAPI wglCreateContext( HDC hdc ) { struct wglCreateContext_params args = { .teb = NtCurrentTeb(), .hDc = hdc }; @@ -1846,6 +1869,128 @@ GLint WINAPI glDebugEntry( GLint unknown1, GLint unknown2 ) return 0; } +static GLsync sync_from_handle( GLsync handle ) +{ + struct handle_entry *ptr; + struct context *ctx; + + if (!(ctx = context_from_handle( NtCurrentTeb()->glCurrentRC ))) return NULL; + if (!(ptr = get_handle_ptr( &ctx->syncs, handle ))) return NULL; + return ptr->user_data; +} + +BOOL get_sync_from_handle( GLsync handle, GLsync *obj ) +{ + *obj = sync_from_handle( handle ); + return *obj || !handle; +} + +static struct handle_entry *alloc_client_sync( struct context *ctx ) +{ + struct handle_entry *ptr; + GLsync *sync; + + if (!(sync = calloc( 1, sizeof(*sync) ))) return NULL; + if (!(ptr = alloc_handle( &ctx->syncs, sync ))) + { + free( sync ); + return NULL; + } + + return ptr; +} + +static void free_client_sync( struct context *ctx, struct handle_entry *ptr ) +{ + GLsync sync = ptr->user_data; + free_handle( &ctx->syncs, ptr ); + free( sync ); +} + +GLsync WINAPI glCreateSyncFromCLeventARB( struct _cl_context *context, struct _cl_event *event, GLbitfield flags ) +{ + TEB *teb = NtCurrentTeb(); + struct glCreateSyncFromCLeventARB_params args = { .teb = teb, .context = context, .event = event, .flags = flags }; + struct handle_entry *ptr; + struct context *ctx; + NTSTATUS status; + + TRACE( "context %p, event %p, flags %d\n", context, event, flags ); + + if (!(ctx = context_from_handle( teb->glCurrentRC ))) return NULL; + if (!(ptr = alloc_client_sync( ctx ))) return NULL; + args.ret = ptr->user_data; + + if ((status = UNIX_CALL( glCreateSyncFromCLeventARB, &args ))) WARN( "glCreateSyncFromCLeventARB returned %#lx\n", status ); + assert( args.ret == ptr->user_data || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_context( ptr ); + return NULL; +} + +void WINAPI glDeleteSync( GLsync sync ) +{ + TEB *teb = NtCurrentTeb(); + struct glDeleteSync_params args = { .teb = teb }; + struct handle_entry *ptr; + struct context *ctx; + NTSTATUS status; + + TRACE( "sync %p\n", sync ); + + if (!(ctx = context_from_handle( teb->glCurrentRC ))) return; + if (!(ptr = get_handle_ptr( &ctx->syncs, sync ))) return set_gl_error( GL_INVALID_VALUE ); + args.sync = ptr->user_data; + + if ((status = UNIX_CALL( glDeleteSync, &args ))) WARN( "glDeleteSync returned %#lx\n", status ); + if (!status) free_client_sync( ctx, ptr ); +} + +GLsync WINAPI glFenceSync( GLenum condition, GLbitfield flags ) +{ + TEB *teb = NtCurrentTeb(); + struct glFenceSync_params args = { .teb = teb, .condition = condition, .flags = flags }; + struct handle_entry *ptr; + struct context *ctx; + NTSTATUS status; + + TRACE( "condition %d, flags %d\n", condition, flags ); + + if (!(ctx = context_from_handle( teb->glCurrentRC ))) return NULL; + if (!(ptr = alloc_client_sync( ctx ))) return NULL; + args.ret = ptr->user_data; + + if ((status = UNIX_CALL( glFenceSync, &args ))) WARN( "glFenceSync returned %#lx\n", status ); + assert( args.ret == ptr->user_data || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_context( ptr ); + return NULL; +} + +GLsync WINAPI glImportSyncEXT( GLenum external_sync_type, GLintptr external_sync, GLbitfield flags ) +{ + TEB *teb = NtCurrentTeb(); + struct glImportSyncEXT_params args = { .teb = teb, .external_sync_type = external_sync_type, .external_sync = external_sync, .flags = flags }; + struct handle_entry *ptr; + struct context *ctx; + NTSTATUS status; + + TRACE( "external_sync_type %d, external_sync %Id, flags %d\n", external_sync_type, external_sync, flags ); + + if (!(ctx = context_from_handle( teb->glCurrentRC ))) return NULL; + if (!(ptr = alloc_client_sync( ctx ))) return NULL; + args.ret = ptr->user_data; + + if ((status = UNIX_CALL( glImportSyncEXT, &args ))) WARN( "glImportSyncEXT returned %#lx\n", status ); + assert( args.ret == ptr->user_data || !args.ret ); + + if (!status && args.ret) return UlongToHandle( ptr->handle ); + free_client_context( ptr ); + return NULL; +} + const GLubyte * WINAPI glGetStringi( GLenum name, GLuint index ) { struct glGetStringi_params args = diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 366f600e002..f740303f4de 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -84,6 +84,12 @@ static inline struct opengl_client_pbuffer *opengl_client_pbuffer_from_client( H return CONTAINING_RECORD( client_pbuffer, struct opengl_client_pbuffer, obj ); } +/* client-side opengl sync */ +struct __GLsync +{ + UINT64 unix_handle; +}; + #ifdef WINE_UNIX_LIB #include "wine/gdi_driver.h" -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9953
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)