From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 3 ++ dlls/opengl32/unix_private.h | 3 ++ dlls/opengl32/unix_thunks.c | 8 ++--- dlls/opengl32/unix_wgl.c | 38 +++++++++++++++++++++ dlls/win32u/opengl.c | 62 +++++++---------------------------- dlls/wineandroid.drv/opengl.c | 2 +- dlls/winemac.drv/opengl.c | 2 +- dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 7 ++-- include/wine/opengl_driver.h | 3 +- 10 files changed, 66 insertions(+), 64 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 0001ffe28f3..bc8eb05aaa5 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -200,10 +200,13 @@ my %manual_unix_thunks = "glDebugMessageCallback" => 1, "glDebugMessageCallbackAMD" => 1, "glDebugMessageCallbackARB" => 1, + "glFinish" => 1, + "glFlush" => 1, "glGetIntegerv" => 1, "glGetString" => 1, "glGetStringi" => 1, "wglGetProcAddress" => 1, + "wglSwapBuffers" => 1, ); my %manual_wow64_thunks = ( diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index 62e96dfbe81..30b90545105 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -80,6 +80,9 @@ extern HGLRC wrap_wglCreateContext( TEB *teb, HDC hDc ); 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 ); +extern void wrap_glFinish( TEB *teb ); +extern void wrap_glFlush( TEB *teb ); +extern BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ); extern BOOL wrap_wglShareLists( TEB *teb, HGLRC hrcSrvShare, HGLRC hrcSrvSource ); extern void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ); extern const GLubyte * wrap_glGetString( TEB *teb, GLenum name ); diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 4342e809481..ae97dfbec47 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -100,7 +100,7 @@ static NTSTATUS wgl_wglSwapBuffers( void *args ) struct wglSwapBuffers_params *params = args; const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); if (!funcs || !funcs->p_wglSwapBuffers) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_wglSwapBuffers( params->hdc ); + params->ret = wrap_wglSwapBuffers( params->teb, params->hdc ); return STATUS_SUCCESS; }
@@ -907,8 +907,7 @@ static NTSTATUS gl_glFeedbackBuffer( void *args ) static NTSTATUS gl_glFinish( void *args ) { struct glFinish_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFinish(); + wrap_glFinish( params->teb ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -916,8 +915,7 @@ static NTSTATUS gl_glFinish( void *args ) static NTSTATUS gl_glFlush( void *args ) { struct glFlush_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFlush(); + wrap_glFlush( params->teb ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 94220daf4fd..f009c74e209 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -986,6 +986,44 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) return TRUE; }
+static void flush_context( TEB *teb, void (*flush)(void) ) +{ + struct opengl_context *ctx = get_current_context( teb ); + const struct opengl_funcs *funcs = teb->glTable; + + if (!ctx || !funcs->p_wgl_context_flush( ctx->drv_ctx, flush )) + { + /* default implementation: call the functions directly */ + if (flush) flush(); + } +} + +void wrap_glFinish( TEB *teb ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, funcs->p_glFinish ); +} + +void wrap_glFlush( TEB *teb ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, funcs->p_glFlush ); +} + +BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) +{ + const struct opengl_funcs *funcs = get_dc_funcs( hdc ); + BOOL ret; + + if (!(ret = funcs->p_wglSwapBuffers( hdc ))) + { + /* default implementation: implicitly flush the context */ + flush_context( teb, funcs->p_glFlush ); + } + + return ret; +} + BOOL wrap_wglShareLists( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 223bae502c2..13c9d230925 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -45,10 +45,6 @@ struct wgl_context const struct opengl_funcs *funcs; void *driver_private; int pixel_format; - - /* hooked host function pointers */ - PFN_glFinish p_glFinish; - PFN_glFlush p_glFlush; };
struct wgl_pbuffer @@ -74,9 +70,6 @@ static struct egl_platform display_egl; static struct opengl_funcs display_funcs; static struct opengl_funcs memory_funcs;
-static PFN_glFinish p_memory_glFinish, p_display_glFinish; -static PFN_glFlush p_memory_glFlush, p_display_glFlush; - static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs );
static const struct @@ -424,7 +417,7 @@ static BOOL egldrv_context_destroy( void *private ) return FALSE; }
-static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { FIXME( "stub!\n" ); return FALSE; @@ -767,7 +760,7 @@ static BOOL osmesa_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva return ret; }
-static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } @@ -859,7 +852,7 @@ static BOOL nulldrv_context_destroy( void *private ) return FALSE; }
-static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } @@ -1044,8 +1037,6 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, context->driver_funcs = driver_funcs; context->funcs = funcs; context->pixel_format = format; - context->p_glFinish = funcs == &display_funcs ? p_display_glFinish : p_memory_glFinish; - context->p_glFlush = funcs == &display_funcs ? p_display_glFlush : p_memory_glFlush;
if (!driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) { @@ -1552,23 +1543,17 @@ static int get_window_swap_interval( HWND hwnd ) return interval; }
-static void wgl_context_flush( struct wgl_context *context, BOOL finish ) +static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void) ) { - HDC hdc = NtCurrentTeb()->glReserved1[0]; + HDC draw_hdc = NtCurrentTeb()->glReserved1[0]; int interval; HWND hwnd;
- if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; + if (!(hwnd = NtUserWindowFromDC( draw_hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- TRACE( "context %p, hwnd %p, hdc %p, interval %d, finish %u\n", context, hwnd, hdc, interval, finish ); - - if (!context->driver_funcs->p_context_flush( context->driver_private, hwnd, hdc, interval, finish )) - { - /* default implementation: call the hooked functions */ - if (finish) context->p_glFinish(); - else context->p_glFlush(); - } + TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush ); + return context->driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1589,14 +1574,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- if (!driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval )) - { - /* default implementation: implicitly flush the context */ - if (context) wgl_context_flush( context, FALSE ); - return FALSE; - } - - return TRUE; + return driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); }
static BOOL win32u_wglSwapIntervalEXT( int interval ) @@ -1645,18 +1623,6 @@ static int win32u_wglGetSwapIntervalEXT(void) return interval; }
-static void win32u_glFlush(void) -{ - struct wgl_context *context = NtCurrentTeb()->glContext; - if (context) wgl_context_flush( context, FALSE ); -} - -static void win32u_glFinish(void) -{ - struct wgl_context *context = NtCurrentTeb()->glContext; - if (context) wgl_context_flush( context, TRUE ); -} - static void init_opengl_funcs( struct opengl_funcs *funcs, const struct opengl_driver_funcs *driver_funcs ) { #define USE_GL_FUNC(func) \ @@ -1689,10 +1655,7 @@ static void memory_funcs_init(void) memory_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
memory_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - p_memory_glFinish = memory_funcs.p_glFinish; - memory_funcs.p_glFinish = win32u_glFinish; - p_memory_glFlush = memory_funcs.p_glFlush; - memory_funcs.p_glFlush = win32u_glFlush; + memory_funcs.p_wgl_context_flush = win32u_wgl_context_flush; }
static void display_funcs_init(void) @@ -1722,10 +1685,7 @@ static void display_funcs_init(void) display_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
display_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - p_display_glFinish = display_funcs.p_glFinish; - display_funcs.p_glFinish = win32u_glFinish; - p_display_glFlush = display_funcs.p_glFlush; - display_funcs.p_glFlush = win32u_glFlush; + display_funcs.p_wgl_context_flush = win32u_wgl_context_flush;
if (display_egl.has_EGL_EXT_pixel_format_float) { diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 0e8da03ab0c..60cdd419f62 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -355,7 +355,7 @@ static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interva return TRUE; }
-static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct android_context *ctx = private; struct gl_drawable *gl; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 474d8f9d4e8..f1d3ef3a265 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2068,7 +2068,7 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, }
-static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct macdrv_context *context = private;
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index d9b93f44c73..5b995f6b6ab 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -479,7 +479,7 @@ static void *wayland_get_proc_address(const char *name) return funcs->p_eglGetProcAddress(name); }
-static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3d583a170e7..3c40d864338 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1612,7 +1612,7 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO if (region) NtGdiDeleteObjectApp( region ); }
-static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct gl_drawable *gl; struct x11drv_context *ctx = private; @@ -1624,10 +1624,9 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva set_swap_interval( gl, interval ); pthread_mutex_unlock( &context_mutex );
- if (finish) pglFinish(); - else pglFlush(); + if (flush) flush();
- present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, !finish ); + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != pglFinish ); release_gl_drawable( gl ); return TRUE; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 71e799660b8..ed441fdb932 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -69,6 +69,7 @@ struct wgl_pbuffer; /* interface between opengl32 and win32u */ struct opengl_funcs { + BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void) ); 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 ); @@ -134,7 +135,7 @@ struct opengl_driver_funcs BOOL (*p_swap_buffers)(void*,HWND,HDC,int); BOOL (*p_context_create)(HDC,int,void*,const int*,void**); BOOL (*p_context_destroy)(void*); - BOOL (*p_context_flush)(void*,HWND,HDC,int,BOOL); + BOOL (*p_context_flush)(void*,HWND,HDC,int,void(*)(void)); BOOL (*p_context_make_current)(HDC,HDC,void*); BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLenum,GLenum,GLint,GLsizei*,GLsizei*,void **); BOOL (*p_pbuffer_destroy)(HDC,void*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3c40d864338..07e90ef2caa 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -346,10 +346,12 @@ static INT64 (*pglXSwapBuffersMscOML)( Display *dpy, GLXDrawable drawable, INT64 target_msc, INT64 divisor, INT64 remainder );
/* Standard OpenGL */ -static void (*pglFinish)(void); -static void (*pglFlush)(void); static const GLubyte *(*pglGetString)(GLenum name);
+static void *opengl_handle; +static const struct opengl_funcs *funcs; +static const struct opengl_driver_funcs x11drv_driver_funcs; + /* check if the extension is present in the list */ static BOOL has_extension( const char *list, const char *ext ) { @@ -490,9 +492,6 @@ done: return ret; }
-static void *opengl_handle; -static const struct opengl_driver_funcs x11drv_driver_funcs; - /********************************************************************** * X11DRV_OpenglInit */ @@ -505,6 +504,7 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version, WINE_OPENGL_DRIVER_VERSION ); return STATUS_INVALID_PARAMETER; } + funcs = opengl_funcs;
/* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and include all dependencies */ @@ -523,8 +523,6 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c ERR( "%s not found in libGL, disabling OpenGL.\n", #func ); \ goto failed; \ } - LOAD_FUNCPTR( glFinish ); - LOAD_FUNCPTR( glFlush ); LOAD_FUNCPTR( glGetString ); #undef LOAD_FUNCPTR
@@ -1589,7 +1587,7 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO window = get_dc_drawable( hdc, &rect ); region = get_dc_monitor_region( hwnd, hdc );
- if (gl_finish) pglFinish(); + if (gl_finish) funcs->p_glFinish(); if (flush) XFlush( gdi_display );
NtUserGetClientRect( hwnd, &rect_dst, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); @@ -1626,7 +1624,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva
if (flush) flush();
- present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != pglFinish ); + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != funcs->p_glFinish ); release_gl_drawable( gl ); return TRUE; } @@ -1942,14 +1940,14 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval /* (glX)SwapBuffers has an implicit glFlush effect, however * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before * copying */ - pglFlush(); + funcs->p_glFlush(); pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0, gl->rect.right, gl->rect.bottom ); break; } if (ctx && pglXSwapBuffersMscOML) { - pglFlush(); + funcs->p_glFlush(); target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); break; } @@ -1963,7 +1961,7 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval default: if (ctx && drawable && pglXSwapBuffersMscOML) { - pglFlush(); + funcs->p_glFlush(); target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/opengl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index f1d3ef3a265..c55ecc0976a 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -86,12 +86,13 @@ static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER; static CFMutableDictionaryRef dc_pbuffers; static pthread_mutex_t dc_pbuffers_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void *opengl_handle; +static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs macdrv_driver_funcs;
static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); static void (*pglCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -static void (*pglFlush)(void); static void (*pglFlushRenderAPPLE)(void); static const GLubyte *(*pglGetString)(GLenum name); static PFN_glGetIntegerv pglGetIntegerv; @@ -232,9 +233,6 @@ static pixel_format *pixel_formats; static int nb_formats, nb_displayable_formats;
-static void *opengl_handle; - - static const char* debugstr_attrib(int attrib, int value) { static const struct { @@ -2174,7 +2172,7 @@ static UINT macdrv_pbuffer_bind(HDC hdc, void *private, GLenum source) TRACE("hdc %p pbuffer %p source 0x%x\n", hdc, pbuffer, source);
if (!context->draw_view && context->draw_pbuffer == pbuffer && source != GL_NONE) - pglFlush(); + funcs->p_glFlush();
err = CGLTexImagePBuffer(context->cglcontext, pbuffer, source); if (err != kCGLNoError) @@ -2782,6 +2780,7 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co ERR("version mismatch, opengl32 wants %u but macdrv has %u\n", version, WINE_OPENGL_DRIVER_VERSION); return STATUS_INVALID_PARAMETER; } + funcs = opengl_funcs;
dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); if (!dc_pbuffers) @@ -2810,7 +2809,6 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co LOAD_FUNCPTR(glReadPixels); LOAD_FUNCPTR(glViewport); LOAD_FUNCPTR(glCopyColorTable); - LOAD_FUNCPTR(glFlush);
if (!init_gl_info()) goto failed;