From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/opengl.c | 156 ++++++++++++++++++++++++++++++++++- dlls/win32u/window.c | 1 + include/wine/opengl_driver.h | 2 + 4 files changed, 156 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 2f3bbdf91c0..fbc3c0d6d64 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -76,6 +76,7 @@ typedef struct tagWND struct window_surface *surface; /* Window surface if any */ struct list vulkan_surfaces; /* list of vulkan surfaces created for this window */ struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */ + int swap_interval; /* OpenGL surface swap interval */ int pixel_format; /* Pixel format set by the graphics driver */ int internal_pixel_format; /* Internal pixel format set via WGL_WINE_pixel_format_passthrough */ int cbWndExtra; /* class cbWndExtra at window creation */ diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 9e177337653..8549c222a69 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -45,6 +45,10 @@ 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 @@ -308,7 +312,7 @@ static void *osmesa_get_proc_address( const char *proc ) return (PROC)pOSMesaGetProcAddress( proc ); }
-static BOOL osmesa_wglSwapBuffers( HDC hdc ) +static BOOL osmesa_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) { return TRUE; } @@ -374,10 +378,10 @@ static BOOL osmesa_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva return ret; }
-static struct opengl_funcs osmesa_opengl_funcs = +static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { - .p_wglSwapBuffers = osmesa_wglSwapBuffers, -}; + return FALSE; +}
static const struct opengl_driver_funcs osmesa_driver_funcs = { @@ -386,10 +390,12 @@ static const struct opengl_driver_funcs osmesa_driver_funcs = .p_describe_pixel_format = osmesa_describe_pixel_format, .p_init_wgl_extensions = osmesa_init_wgl_extensions, .p_set_pixel_format = osmesa_set_pixel_format, + .p_swap_buffers = osmesa_swap_buffers, .p_context_create = osmesa_context_create, .p_context_destroy = osmesa_context_destroy, .p_context_copy = osmesa_context_copy, .p_context_share = osmesa_context_share, + .p_context_flush = osmesa_context_flush, .p_context_make_current = osmesa_context_make_current, };
@@ -517,6 +523,9 @@ static const struct opengl_funcs *default_funcs; /* default GL function table fr 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 int get_dc_pixel_format( HDC hdc, BOOL internal ) { int ret = 0; @@ -655,6 +664,8 @@ 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 )) { @@ -1169,6 +1180,123 @@ static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const in pbuffer->cube_face, max( pbuffer->mipmap_level, 0 ) ); }
+static int get_window_swap_interval( HWND hwnd ) +{ + int interval; + WND *win; + + if (!(win = get_win_ptr( hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return 0; + interval = win->swap_interval; + release_win_ptr( win ); + + return interval; +} + +static void wgl_context_flush( struct wgl_context *context, BOOL finish ) +{ + HDC hdc = NtCurrentTeb()->glReserved1[0]; + int interval; + HWND hwnd; + + if (!(hwnd = NtUserWindowFromDC( 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(); + } +} + +static BOOL win32u_wglSwapBuffers( HDC hdc ) +{ + struct wgl_context *context = NtCurrentTeb()->glContext; + const struct opengl_driver_funcs *driver_funcs; + const struct opengl_funcs *funcs; + int interval; + HWND hwnd; + + if (!(funcs = get_dc_funcs( hdc, NULL ))) + { + RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); + return FALSE; + } + driver_funcs = funcs == display_funcs ? display_driver_funcs : memory_driver_funcs; + + 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; +} + +static BOOL win32u_wglSwapIntervalEXT( int interval ) +{ + HDC hdc = NtCurrentTeb()->glReserved1[0]; + HWND hwnd; + WND *win; + + if (!(hwnd = NtUserWindowFromDC( hdc )) || !(win = get_win_ptr( hwnd ))) + { + RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); + return FALSE; + } + if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) + { + WARN( "setting swap interval on win %p not supported\n", hwnd ); + return TRUE; + } + + TRACE( "setting window %p swap interval %d\n", hwnd, interval ); + win->swap_interval = interval; + release_win_ptr( win ); + return TRUE; +} + +static int win32u_wglGetSwapIntervalEXT(void) +{ + HDC hdc = NtCurrentTeb()->glReserved1[0]; + int interval; + HWND hwnd; + WND *win; + + if (!(hwnd = NtUserWindowFromDC( hdc )) || !(win = get_win_ptr( hwnd ))) + { + RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); + return 0; + } + if (win == WND_DESKTOP || win == WND_OTHER_PROCESS) + { + WARN( "setting swap interval on win %p not supported\n", hwnd ); + return TRUE; + } + interval = win->swap_interval; + release_win_ptr( win ); + + 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) \ @@ -1200,6 +1328,12 @@ static void memory_funcs_init(void) memory_funcs->p_wglCopyContext = win32u_wglCopyContext; memory_funcs->p_wglShareLists = win32u_wglShareLists; 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; }
static void display_funcs_init(void) @@ -1267,6 +1401,20 @@ static void display_funcs_init(void) display_funcs->p_wglBindTexImageARB = win32u_wglBindTexImageARB; display_funcs->p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; display_funcs->p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB; + + if (display_driver_funcs->p_swap_buffers) + { + 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; + + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control" ); + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control_tear" ); + display_funcs->p_wglSwapIntervalEXT = win32u_wglSwapIntervalEXT; + display_funcs->p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT; + } }
static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs ) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 33dc0987b34..9acb9350144 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5560,6 +5560,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, win->hIconSmall = 0; win->hIconSmall2 = 0; win->hSysMenu = 0; + win->swap_interval = 1;
win->min_pos.x = win->min_pos.y = -1; win->max_pos.x = win->max_pos.y = -1; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index f1f7da379e8..decdaec270d 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -118,10 +118,12 @@ struct opengl_driver_funcs BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(void); BOOL (*p_set_pixel_format)(HWND,int,int,BOOL); + 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_copy)(void*,void*,UINT); BOOL (*p_context_share)(void*,void*); + BOOL (*p_context_flush)(void*,HWND,HDC,int,BOOL); 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/wineandroid.drv/opengl.c | 98 +++++++++++------------------------ 1 file changed, 30 insertions(+), 68 deletions(-)
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index c20ac95a936..7d25b28acad 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -91,6 +91,7 @@ struct gl_drawable ANativeWindow *window; EGLSurface surface; EGLSurface pbuffer; + int swap_interval; };
static void *egl_handle; @@ -98,16 +99,12 @@ static void *opengl_handle; static struct egl_pixel_format *pixel_formats; static int nb_pixel_formats, nb_onscreen_formats; static EGLDisplay display; -static int swap_interval; static char wgl_extensions[4096]; static struct opengl_funcs egl_funcs;
static struct list gl_contexts = LIST_INIT( gl_contexts ); static struct list gl_drawables = LIST_INIT( gl_drawables );
-static void (*pglFinish)(void); -static void (*pglFlush)(void); - pthread_mutex_t drawable_mutex;
static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) @@ -355,39 +352,6 @@ done: return ret; }
-/*********************************************************************** - * android_wglSwapIntervalEXT - */ -static BOOL android_wglSwapIntervalEXT( int interval ) -{ - BOOL ret = TRUE; - - TRACE("(%d)\n", interval); - - if (interval < 0) - { - RtlSetLastWin32Error( ERROR_INVALID_DATA ); - return FALSE; - } - - ret = p_eglSwapInterval( display, interval ); - - if (ret) - swap_interval = interval; - else - RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); - - return ret; -} - -/*********************************************************************** - * android_wglGetSwapIntervalEXT - */ -static int android_wglGetSwapIntervalEXT(void) -{ - return swap_interval; -} - /*********************************************************************** * android_wglCopyContext */ @@ -424,40 +388,49 @@ static BOOL android_context_share( void *org, void *dest ) return FALSE; }
-/*********************************************************************** - * android_wglSwapBuffers - */ -static BOOL android_wglSwapBuffers( HDC hdc ) +static void set_swap_interval( struct gl_drawable *gl, int interval ) { - struct android_context *ctx = NtCurrentTeb()->glReserved2; + if (interval < 0) interval = -interval; + if (gl->swap_interval == interval) return; + p_eglSwapInterval( display, interval ); + gl->swap_interval = interval; +} + +static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) +{ + struct android_context *ctx = private; + struct gl_drawable *gl;
if (!ctx) return FALSE;
TRACE( "%p hwnd %p context %p surface %p\n", hdc, ctx->hwnd, ctx->context, ctx->surface );
if (refresh_context( ctx )) return TRUE; + + if ((gl = get_gl_drawable( hwnd, hdc ))) + { + set_swap_interval( gl, interval ); + release_gl_drawable( gl ); + } + if (ctx->surface) p_eglSwapBuffers( display, ctx->surface ); return TRUE; }
-static void wglFinish(void) +static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { - struct android_context *ctx = NtCurrentTeb()->glReserved2; + struct android_context *ctx = private; + struct gl_drawable *gl;
- if (!ctx) return; TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context ); refresh_context( ctx ); - pglFinish(); -}
-static void wglFlush(void) -{ - struct android_context *ctx = NtCurrentTeb()->glReserved2; - - if (!ctx) return; - TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context ); - refresh_context( ctx ); - pglFlush(); + if ((gl = get_gl_drawable( hwnd, hdc ))) + { + set_swap_interval( gl, interval ); + release_gl_drawable( gl ); + } + return FALSE; }
static void register_extension( const char *ext ) @@ -469,10 +442,6 @@ static void register_extension( const char *ext )
static const char *android_init_wgl_extensions(void) { - register_extension("WGL_EXT_swap_control"); - egl_funcs.p_wglSwapIntervalEXT = android_wglSwapIntervalEXT; - egl_funcs.p_wglGetSwapIntervalEXT = android_wglGetSwapIntervalEXT; - register_extension("WGL_EXT_framebuffer_sRGB"); return wgl_extensions; } @@ -762,14 +731,6 @@ static void init_opengl_funcs(void) LOAD_FUNCPTR( glVertexBindingDivisor ); LOAD_FUNCPTR( glWaitSync ); #undef LOAD_FUNCPTR - - /* redirect some standard OpenGL functions */ - -#define REDIRECT(func) \ - do { p##func = egl_funcs.p_##func; egl_funcs.p_##func = w##func; } while(0) - REDIRECT(glFinish); - REDIRECT(glFlush); -#undef REDIRECT }
static UINT android_init_pixel_formats( UINT *onscreen_count ) @@ -828,10 +789,12 @@ static const struct opengl_driver_funcs android_driver_funcs = .p_describe_pixel_format = android_describe_pixel_format, .p_init_wgl_extensions = android_init_wgl_extensions, .p_set_pixel_format = android_set_pixel_format, + .p_swap_buffers = android_swap_buffers, .p_context_create = android_context_create, .p_context_destroy = android_context_destroy, .p_context_copy = android_context_copy, .p_context_share = android_context_share, + .p_context_flush = android_context_flush, .p_context_make_current = android_context_make_current, };
@@ -903,7 +866,6 @@ ALL_GL_FUNCS
static struct opengl_funcs egl_funcs = { - .p_wglSwapBuffers = android_wglSwapBuffers, #define USE_GL_FUNC(name) .p_##name = (void *)glstub_##name, ALL_GL_FUNCS #undef USE_GL_FUNC
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/macdrv.h | 1 - dlls/winemac.drv/opengl.c | 241 ++++++-------------------------------- dlls/winemac.drv/window.c | 1 - 3 files changed, 37 insertions(+), 206 deletions(-)
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 96262a7d030..2e2de456ddf 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -190,7 +190,6 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p unsigned int ulw_layered : 1; /* has UpdateLayeredWindow() been called for window? */ unsigned int per_pixel_alpha : 1; /* is window using per-pixel alpha? */ unsigned int minimized : 1; /* is window minimized? */ - unsigned int swap_interval : 1; /* GL swap interval for window */ };
extern struct macdrv_win_data *get_win_data(HWND hwnd); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 9aa50b69b78..da748777055 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -75,7 +75,7 @@ struct macdrv_context CGLPBufferObj read_pbuffer; BOOL has_been_current; BOOL sharing; - LONG update_swap_interval; + int swap_interval; LONG view_moved; unsigned int last_flush_time; UINT major; @@ -94,7 +94,6 @@ 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 (*pglFinish)(void); static void (*pglFlush)(void); static void (*pglFlushRenderAPPLE)(void); static const GLubyte *(*pglGetString)(GLenum name); @@ -1459,8 +1458,7 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, return FALSE; } context->major = major; - - InterlockedExchange(&context->update_swap_interval, TRUE); + context->swap_interval = INT_MIN;
TRACE("created context %p/%p/%p\n", context, context->context, context->cglcontext);
@@ -1583,6 +1581,11 @@ static BOOL set_swap_interval(struct macdrv_context *context, long interval) { CGLError err;
+ if (!allow_vsync || !context->draw_hwnd) interval = 0; + + if (interval < 0) interval = -interval; + if (context->swap_interval == interval) return TRUE; + /* In theory, for single-buffered contexts, there's no such thing as a swap so the swap interval shouldn't matter. But OS X will synchronize flushes of single-buffered contexts if the interval is set to non-zero. */ @@ -1592,41 +1595,12 @@ static BOOL set_swap_interval(struct macdrv_context *context, long interval) err = CGLSetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&interval); if (err != kCGLNoError) WARN("CGLSetParameter(kCGLCPSwapInterval) failed; error %d %s\n", err, CGLErrorString(err)); + context->swap_interval = interval;
return err == kCGLNoError; }
-/********************************************************************** - * sync_swap_interval - */ -static void sync_swap_interval(struct macdrv_context *context) -{ - if (InterlockedCompareExchange(&context->update_swap_interval, FALSE, TRUE)) - { - int interval; - - if (!allow_vsync) - interval = 0; - else if (context->draw_hwnd) - { - struct macdrv_win_data *data = get_win_data(context->draw_hwnd); - if (data) - { - interval = data->swap_interval; - release_win_data(data); - } - else /* window was destroyed? */ - interval = 1; - } - else /* pbuffer */ - interval = 0; - - set_swap_interval(context, interval); - } -} - - /********************************************************************** * get_iokit_display_property */ @@ -2087,27 +2061,11 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, }
-/********************************************************************** - * macdrv_glFinish - */ -static void macdrv_glFinish(void) -{ - struct macdrv_context *context = NtCurrentTeb()->glReserved2; - - sync_swap_interval(context); - sync_context(context); - pglFinish(); -} - - -/********************************************************************** - * macdrv_glFlush - */ -static void macdrv_glFlush(void) +static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { - struct macdrv_context *context = NtCurrentTeb()->glReserved2; + struct macdrv_context *context = private;
- sync_swap_interval(context); + set_swap_interval(context, interval); sync_context(context);
if (skip_single_buffer_flushes) @@ -2121,7 +2079,7 @@ static void macdrv_glFlush(void) { TRACE("calling glFlushRenderAPPLE()\n"); pglFlushRenderAPPLE(); - return; + return TRUE; } else { @@ -2130,7 +2088,7 @@ static void macdrv_glFlush(void) } }
- pglFlush(); + return FALSE; }
@@ -2209,7 +2167,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) - opengl_funcs.p_glFlush(); + pglFlush();
err = CGLTexImagePBuffer(context->cglcontext, pbuffer, source); if (err != kCGLNoError) @@ -2434,42 +2392,6 @@ static BOOL macdrv_pbuffer_destroy(HDC hdc, void *private) }
-/********************************************************************** - * macdrv_wglGetSwapIntervalEXT - * - * WGL_EXT_swap_control: wglGetSwapIntervalEXT - */ -static int macdrv_wglGetSwapIntervalEXT(void) -{ - struct macdrv_context *context = NtCurrentTeb()->glReserved2; - struct macdrv_win_data *data; - long value; - CGLError err; - - TRACE("\n"); - - if ((data = get_win_data(context->draw_hwnd))) - { - value = data->swap_interval; - release_win_data(data); - - if (InterlockedCompareExchange(&context->update_swap_interval, FALSE, TRUE)) - set_swap_interval(context, allow_vsync ? value : 0); - } - else - { - err = CGLGetParameter(context->cglcontext, kCGLCPSwapInterval, (GLint*)&value); - if (err != kCGLNoError) - { - WARN("CGLGetParameter(kCGLCPSwapInterval) failed; error %d %s\n", - err, CGLErrorString(err)); - value = 1; - } - } - - return value; -} - static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *private) { struct macdrv_context *context = private; @@ -2494,9 +2416,6 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat return FALSE; }
- if (InterlockedCompareExchange(&context->update_swap_interval, FALSE, TRUE) || hwnd != context->draw_hwnd) - set_swap_interval(context, allow_vsync ? data->swap_interval : 0); - context->draw_hwnd = hwnd; context->draw_view = data->client_cocoa_view; context->draw_rect = data->rects.client; @@ -2510,12 +2429,7 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat
pthread_mutex_lock(&dc_pbuffers_mutex); pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, draw_hdc); - if (pbuffer) - { - if (InterlockedCompareExchange(&context->update_swap_interval, FALSE, TRUE) || pbuffer != context->draw_pbuffer) - set_swap_interval(context, 0); - } - else + if (!pbuffer) { WARN("no window or pbuffer for DC\n"); pthread_mutex_unlock(&dc_pbuffers_mutex); @@ -2794,68 +2708,6 @@ static BOOL macdrv_pbuffer_updated(HDC hdc, void *private, GLenum cube_face, GLi return GL_TRUE; }
- -/********************************************************************** - * macdrv_wglSwapIntervalEXT - * - * WGL_EXT_swap_control: wglSwapIntervalEXT - */ -static BOOL macdrv_wglSwapIntervalEXT(int interval) -{ - struct macdrv_context *context = NtCurrentTeb()->glReserved2; - BOOL changed = FALSE; - - TRACE("interval %d\n", interval); - - if (interval < 0) - { - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return FALSE; - } - if (interval > 1) - interval = 1; - - if (context->draw_hwnd) - { - struct macdrv_win_data *data = get_win_data(context->draw_hwnd); - if (data) - { - changed = data->swap_interval != interval; - if (changed) - data->swap_interval = interval; - release_win_data(data); - } - } - else /* pbuffer */ - interval = 0; - - if (!allow_vsync) - interval = 0; - - InterlockedExchange(&context->update_swap_interval, FALSE); - if (!set_swap_interval(context, interval)) - { - RtlSetLastWin32Error(ERROR_GEN_FAILURE); - return FALSE; - } - - if (changed) - { - struct macdrv_context *ctx; - - pthread_mutex_lock(&context_mutex); - LIST_FOR_EACH_ENTRY(ctx, &context_list, struct macdrv_context, entry) - { - if (ctx != context && ctx->draw_hwnd == context->draw_hwnd) - InterlockedExchange(&context->update_swap_interval, TRUE); - } - pthread_mutex_unlock(&context_mutex); - } - - return TRUE; -} - - static void register_extension(const char *ext) { if (gl_info.wglExtensions[0]) @@ -2890,16 +2742,6 @@ static const char *macdrv_init_wgl_extensions(void) register_extension("WGL_NV_render_texture_rectangle"); }
- /* - * EXT Extensions - */ - if (allow_vsync) - { - register_extension("WGL_EXT_swap_control"); - opengl_funcs.p_wglSwapIntervalEXT = macdrv_wglSwapIntervalEXT; - opengl_funcs.p_wglGetSwapIntervalEXT = macdrv_wglGetSwapIntervalEXT; - } - /* Presumably identical to [W]GL_ARB_framebuffer_sRGB, above, but clients may check for either, so register them separately. */ if (gluCheckExtension((GLubyte*)"GL_EXT_framebuffer_sRGB", (GLubyte*)gl_info.glExtensions)) @@ -2968,10 +2810,6 @@ UINT macdrv_OpenGLInit(UINT version, struct opengl_funcs **funcs, const struct o REDIRECT(glGetString); REDIRECT(glReadPixels); REDIRECT(glViewport); - if (skip_single_buffer_flushes || allow_vsync) - REDIRECT(glFlush); - if (allow_vsync) - REDIRECT(glFinish); #undef REDIRECT
/* redirect some OpenGL extension functions */ @@ -2980,8 +2818,16 @@ UINT macdrv_OpenGLInit(UINT version, struct opengl_funcs **funcs, const struct o REDIRECT(glCopyColorTable); #undef REDIRECT
+#define LOAD_FUNCPTR(func) \ + if (!(p##func = dlsym(opengl_handle, #func))) \ + { \ + ERR( "%s not found in OpenGL, disabling.\n", #func ); \ + goto failed; \ + } + LOAD_FUNCPTR(glFlush); if (gluCheckExtension((GLubyte*)"GL_APPLE_flush_render", (GLubyte*)gl_info.glExtensions)) - pglFlushRenderAPPLE = dlsym(opengl_handle, "glFlushRenderAPPLE"); + LOAD_FUNCPTR(glFlushRenderAPPLE); +#undef LOAD_FUNCPTR
*funcs = &opengl_funcs; *driver_funcs = &macdrv_driver_funcs; @@ -3191,25 +3037,21 @@ static void *macdrv_get_proc_address(const char *name) return dlsym(opengl_handle, name); }
-/********************************************************************** - * macdrv_wglSwapBuffers - */ -static BOOL macdrv_wglSwapBuffers(HDC hdc) +static BOOL macdrv_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) { - struct macdrv_context *context = NtCurrentTeb()->glReserved2; + struct macdrv_context *context = private; BOOL match = FALSE; - HWND hwnd;
TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL), (context ? context->cglcontext : NULL));
if (context) { - sync_swap_interval(context); + set_swap_interval(context, interval); sync_context(context); }
- if ((hwnd = NtUserWindowFromDC(hdc))) + if (hwnd) { struct macdrv_win_data *data;
@@ -3242,19 +3084,13 @@ static BOOL macdrv_wglSwapBuffers(HDC hdc) match = TRUE; }
- if (match) - macdrv_flush_opengl_context(context->context); - else + if (!match) { FIXME("current context %p doesn't match hdc %p; can't swap\n", context, hdc); - - /* If there is a current context, then wglSwapBuffers should do an implicit - glFlush(). That would be taken care of by macdrv_flush_opengl_context() - in the other branch, but we have to do it explicitly here. */ - if (context) - pglFlush(); + return FALSE; }
+ macdrv_flush_opengl_context(context->context); return TRUE; }
@@ -3265,18 +3101,15 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_describe_pixel_format = macdrv_describe_pixel_format, .p_init_wgl_extensions = macdrv_init_wgl_extensions, .p_set_pixel_format = macdrv_set_pixel_format, - .p_pbuffer_create = macdrv_pbuffer_create, - .p_pbuffer_destroy = macdrv_pbuffer_destroy, - .p_pbuffer_updated = macdrv_pbuffer_updated, - .p_pbuffer_bind = macdrv_pbuffer_bind, + .p_swap_buffers = macdrv_swap_buffers, .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, .p_context_copy = macdrv_context_copy, .p_context_share = macdrv_context_share, + .p_context_flush = macdrv_context_flush, .p_context_make_current = macdrv_context_make_current, -}; - -static struct opengl_funcs opengl_funcs = -{ - .p_wglSwapBuffers = macdrv_wglSwapBuffers, + .p_pbuffer_create = macdrv_pbuffer_create, + .p_pbuffer_destroy = macdrv_pbuffer_destroy, + .p_pbuffer_updated = macdrv_pbuffer_updated, + .p_pbuffer_bind = macdrv_pbuffer_bind, }; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index c5a8e26a3d2..940fdffa800 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -177,7 +177,6 @@ static struct macdrv_win_data *alloc_win_data(HWND hwnd) if ((data = calloc(1, sizeof(*data)))) { data->hwnd = hwnd; - data->swap_interval = 1; pthread_mutex_lock(&win_data_mutex); if (!win_datas) win_datas = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 87 ++++++++--------------------------- 1 file changed, 19 insertions(+), 68 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 758b483d8bc..f7c68b6a2e3 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -254,11 +254,7 @@ static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *ne
if ((old = find_drawable(hwnd, 0))) list_remove(&old->entry); if (new) list_add_head(&gl_drawables, &new->entry); - if (old && new) - { - update_context_drawables(new, old); - new->swap_interval = old->swap_interval; - } + if (old && new) update_context_drawables(new, old);
pthread_mutex_unlock(&gl_object_mutex);
@@ -422,11 +418,7 @@ static void wayland_context_refresh(struct wayland_context *ctx) ctx->new_read = NULL; refresh = TRUE; } - if (refresh) - { - p_eglMakeCurrent(egl_display, ctx->draw, ctx->read, ctx->context); - if (ctx->draw) p_eglSwapInterval(egl_display, ctx->draw->swap_interval); - } + if (refresh) p_eglMakeCurrent(egl_display, ctx->draw, ctx->read, ctx->context);
pthread_mutex_unlock(&gl_object_mutex);
@@ -528,21 +520,6 @@ static void *wayland_get_proc_address(const char *name) return p_eglGetProcAddress(name); }
-static int wayland_wglGetSwapIntervalEXT(void) -{ - struct wayland_context *ctx = NtCurrentTeb()->glReserved2; - - if (!ctx || !ctx->draw) - { - WARN("No GL drawable found, returning swap interval 0\n"); - return 0; - } - - /* It's safe to read the value without a lock, since only - * the current thread can write to it. */ - return ctx->draw->swap_interval; -} - static BOOL wayland_context_share(void *src_private, void *dst_private) { struct wayland_context *orig = src_private, *dest = dst_private; @@ -587,14 +564,26 @@ static BOOL wayland_context_share(void *src_private, void *dst_private) return TRUE; }
-static BOOL wayland_wglSwapBuffers(HDC hdc) +static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { - struct wayland_context *ctx = NtCurrentTeb()->glReserved2; - HWND hwnd = NtUserWindowFromDC(hdc), toplevel = NtUserGetAncestor(hwnd, GA_ROOT); + return FALSE; +} + +static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) +{ + struct wayland_context *ctx = private; + HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct wayland_gl_drawable *gl;
if (!(gl = wayland_gl_drawable_get(NtUserWindowFromDC(hdc), hdc))) return FALSE;
+ if (interval < 0) interval = -interval; + if (gl->swap_interval != interval) + { + p_eglSwapInterval(egl_display, interval); + gl->swap_interval = interval; + } + if (ctx) wayland_context_refresh(ctx); ensure_window_surface_contents(toplevel); /* Although all the EGL surfaces we create are double-buffered, we want to @@ -607,37 +596,6 @@ static BOOL wayland_wglSwapBuffers(HDC hdc) return TRUE; }
-static BOOL wayland_wglSwapIntervalEXT(int interval) -{ - struct wayland_context *ctx = NtCurrentTeb()->glReserved2; - BOOL ret; - - TRACE("(%d)\n", interval); - - if (interval < 0) - { - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return FALSE; - } - - if (!ctx || !ctx->draw) - { - RtlSetLastWin32Error(ERROR_DC_NOT_FOUND); - return FALSE; - } - - /* Lock to protect against concurrent access to drawable swap_interval - * from wayland_update_gl_drawable */ - pthread_mutex_lock(&gl_object_mutex); - if ((ret = p_eglSwapInterval(egl_display, interval))) - ctx->draw->swap_interval = interval; - else - RtlSetLastWin32Error(ERROR_DC_NOT_FOUND); - pthread_mutex_unlock(&gl_object_mutex); - - return ret; -} - static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, void **private) { @@ -864,10 +822,6 @@ static BOOL init_opengl_funcs(void)
static const char *wayland_init_wgl_extensions(void) { - register_extension("WGL_EXT_swap_control"); - opengl_funcs.p_wglGetSwapIntervalEXT = wayland_wglGetSwapIntervalEXT; - opengl_funcs.p_wglSwapIntervalEXT = wayland_wglSwapIntervalEXT; - if (has_egl_ext_pixel_format_float) { register_extension("WGL_ARB_pixel_format_float"); @@ -939,10 +893,12 @@ static const struct opengl_driver_funcs wayland_driver_funcs = .p_describe_pixel_format = wayland_describe_pixel_format, .p_init_wgl_extensions = wayland_init_wgl_extensions, .p_set_pixel_format = wayland_set_pixel_format, + .p_swap_buffers = wayland_swap_buffers, .p_context_create = wayland_context_create, .p_context_destroy = wayland_context_destroy, .p_context_copy = wayland_context_copy, .p_context_share = wayland_context_share, + .p_context_flush = wayland_context_flush, .p_context_make_current = wayland_context_make_current, .p_pbuffer_create = wayland_pbuffer_create, .p_pbuffer_destroy = wayland_pbuffer_destroy, @@ -1053,11 +1009,6 @@ err: return STATUS_NOT_SUPPORTED; }
-static struct opengl_funcs opengl_funcs = -{ - .p_wglSwapBuffers = wayland_wglSwapBuffers, -}; - /********************************************************************** * wayland_destroy_gl_drawable */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 171 ++++++++------------------------------ 1 file changed, 36 insertions(+), 135 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 6f5b86ce19b..0f6a65b0ec6 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -230,7 +230,6 @@ struct gl_drawable Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ const struct glx_pixel_format *format; /* pixel format for the drawable */ int swap_interval; - BOOL refresh_swap_interval; BOOL mutable_pf; HDC hdc_src; HDC hdc_dst; @@ -357,9 +356,6 @@ static INT64 (*pglXSwapBuffersMscOML)( Display *dpy, GLXDrawable drawable, static void (*pglFinish)(void); static void (*pglFlush)(void); static const GLubyte *(*pglGetString)(GLenum name); - -static void wglFinish(void); -static void wglFlush(void); static const GLubyte *wglGetString(GLenum name);
/* check if the extension is present in the list */ @@ -543,11 +539,19 @@ UINT X11DRV_OpenGLInit( UINT version, struct opengl_funcs **funcs, const struct ALL_GL_FUNCS #undef USE_GL_FUNC
+#define LOAD_FUNCPTR( func ) \ + if (!(p##func = dlsym( opengl_handle, #func ))) \ + { \ + ERR( "%s not found in libGL, disabling OpenGL.\n", #func ); \ + goto failed; \ + } + LOAD_FUNCPTR( glFinish ); + LOAD_FUNCPTR( glFlush ); +#undef LOAD_FUNCPTR + /* redirect some standard OpenGL functions */ #define REDIRECT(func) \ do { p##func = opengl_funcs.p_##func; opengl_funcs.p_##func = w##func; } while(0) - REDIRECT( glFinish ); - REDIRECT( glFlush ); REDIRECT( glGetString ); #undef REDIRECT
@@ -990,15 +994,18 @@ static inline void sync_context(struct x11drv_context *context) pthread_mutex_unlock( &context_mutex ); }
-static BOOL set_swap_interval(GLXDrawable drawable, int interval) +static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) { BOOL ret = TRUE;
+ if (interval < 0 && !has_swap_control_tear) interval = -interval; + if (gl->swap_interval == interval) return TRUE; + switch (swap_control_method) { case GLX_SWAP_CONTROL_EXT: X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL); - pglXSwapIntervalEXT(gdi_display, drawable, interval); + pglXSwapIntervalEXT( gdi_display, gl->drawable, interval ); XSync(gdi_display, False); ret = !X11DRV_check_error(); break; @@ -1080,11 +1087,8 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL;
- /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI - * there is no way to query it, so we have to store it here. - */ - gl->swap_interval = 1; - gl->refresh_swap_interval = TRUE; + /* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI there is no way to query it. */ + gl->swap_interval = INT_MIN; gl->format = format; gl->ref = 1; gl->hwnd = hwnd; @@ -1160,10 +1164,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
pthread_mutex_lock( &context_mutex ); if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) - { - gl->swap_interval = prev->swap_interval; release_gl_drawable( prev ); - } XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)grab_gl_drawable(gl) ); pthread_mutex_unlock( &context_mutex ); return gl; @@ -1722,36 +1723,24 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO if (region) NtGdiDeleteObjectApp( region ); }
-static void wglFinish(void) +static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { struct gl_drawable *gl; - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; - HWND hwnd = NtUserWindowFromDC( ctx->hdc ); + struct x11drv_context *ctx = private;
- if (!(gl = get_gl_drawable( hwnd, 0 ))) pglFinish(); - else - { - sync_context(ctx); - pglFinish(); - present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, FALSE ); - release_gl_drawable( gl ); - } -} + if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; + sync_context( ctx );
-static void wglFlush(void) -{ - struct gl_drawable *gl; - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; - HWND hwnd = NtUserWindowFromDC( ctx->hdc ); + pthread_mutex_lock( &context_mutex ); + set_swap_interval( gl, interval ); + pthread_mutex_unlock( &context_mutex );
- if (!(gl = get_gl_drawable( hwnd, 0 ))) pglFlush(); - else - { - sync_context(ctx); - pglFlush(); - present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, TRUE ); - release_gl_drawable( gl ); - } + if (finish) pglFinish(); + else pglFlush(); + + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, !finish ); + release_gl_drawable( gl ); + return TRUE; }
static const GLubyte *wglGetString(GLenum name) @@ -1930,76 +1919,6 @@ static UINT x11drv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) return -1; /* use default implementation */ }
-/** - * X11DRV_wglGetSwapIntervalEXT - * - * WGL_EXT_swap_control: wglGetSwapIntervalEXT - */ -static int X11DRV_wglGetSwapIntervalEXT(void) -{ - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; - struct gl_drawable *gl; - int swap_interval; - - TRACE("()\n"); - - if (!(gl = get_gl_drawable( NtUserWindowFromDC( ctx->hdc ), ctx->hdc ))) - { - /* This can't happen because a current WGL context is required to get - * here. Likely the application is buggy. - */ - WARN("No GL drawable found, returning swap interval 0\n"); - return 0; - } - - swap_interval = gl->swap_interval; - release_gl_drawable(gl); - - return swap_interval; -} - -/** - * X11DRV_wglSwapIntervalEXT - * - * WGL_EXT_swap_control: wglSwapIntervalEXT - */ -static BOOL X11DRV_wglSwapIntervalEXT(int interval) -{ - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; - struct gl_drawable *gl; - BOOL ret; - - TRACE("(%d)\n", interval); - - /* Without WGL/GLX_EXT_swap_control_tear a negative interval - * is invalid. - */ - if (interval < 0 && !has_swap_control_tear) - { - RtlSetLastWin32Error(ERROR_INVALID_DATA); - return FALSE; - } - - if (!(gl = get_gl_drawable( NtUserWindowFromDC( ctx->hdc ), ctx->hdc ))) - { - RtlSetLastWin32Error(ERROR_DC_NOT_FOUND); - return FALSE; - } - - pthread_mutex_lock( &context_mutex ); - ret = set_swap_interval(gl->drawable, interval); - gl->refresh_swap_interval = FALSE; - if (ret) - gl->swap_interval = interval; - else - RtlSetLastWin32Error(ERROR_DC_NOT_FOUND); - - pthread_mutex_unlock( &context_mutex ); - release_gl_drawable(gl); - - return ret; -} - static BOOL X11DRV_wglQueryCurrentRendererIntegerWINE( GLenum attribute, GLuint *value ) { return pglXQueryCurrentRendererIntegerMESA( attribute, value ); @@ -2068,12 +1987,6 @@ static const char *x11drv_init_wgl_extensions(void)
/* EXT Extensions */
- /* Load this extension even when it isn't backed by a GLX extension because it is has been around for ages. - * Games like Call of Duty and K.O.T.O.R. rely on it. Further our emulation is good enough. */ - register_extension( "WGL_EXT_swap_control" ); - opengl_funcs.p_wglSwapIntervalEXT = X11DRV_wglSwapIntervalEXT; - opengl_funcs.p_wglGetSwapIntervalEXT = X11DRV_wglGetSwapIntervalEXT; - if (has_extension( glxExtensions, "GLX_EXT_framebuffer_sRGB")) register_extension("WGL_EXT_framebuffer_sRGB");
@@ -2083,11 +1996,7 @@ static const char *x11drv_init_wgl_extensions(void) if (has_extension( glxExtensions, "GLX_EXT_swap_control")) { swap_control_method = GLX_SWAP_CONTROL_EXT; - if (has_extension( glxExtensions, "GLX_EXT_swap_control_tear")) - { - register_extension("WGL_EXT_swap_control_tear"); - has_swap_control_tear = TRUE; - } + has_swap_control_tear = has_extension( glxExtensions, "GLX_EXT_swap_control_tear" ); } else if (has_extension( glxExtensions, "GLX_MESA_swap_control")) { @@ -2128,12 +2037,11 @@ static const char *x11drv_init_wgl_extensions(void) * * Swap the buffers of this DC */ -static BOOL glxdrv_wglSwapBuffers( HDC hdc ) +static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) { struct gl_drawable *gl; - struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; + struct x11drv_context *ctx = private; INT64 ust, msc, sbc, target_sbc = 0; - HWND hwnd = NtUserWindowFromDC( hdc ); Drawable drawable = 0;
TRACE("(%p)\n", hdc); @@ -2145,11 +2053,7 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc ) }
pthread_mutex_lock( &context_mutex ); - if (gl->refresh_swap_interval) - { - set_swap_interval(gl->drawable, gl->swap_interval); - gl->refresh_swap_interval = FALSE; - } + set_swap_interval( gl, interval ); pthread_mutex_unlock( &context_mutex );
switch (gl->type) @@ -2206,10 +2110,12 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_describe_pixel_format = x11drv_describe_pixel_format, .p_init_wgl_extensions = x11drv_init_wgl_extensions, .p_set_pixel_format = x11drv_set_pixel_format, + .p_swap_buffers = x11drv_swap_buffers, .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, .p_context_copy = x11drv_context_copy, .p_context_share = x11drv_context_share, + .p_context_flush = x11drv_context_flush, .p_context_make_current = x11drv_context_make_current, .p_pbuffer_create = x11drv_pbuffer_create, .p_pbuffer_destroy = x11drv_pbuffer_destroy, @@ -2217,11 +2123,6 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_pbuffer_bind = x11drv_pbuffer_bind, };
-static struct opengl_funcs opengl_funcs = -{ - .p_wglSwapBuffers = glxdrv_wglSwapBuffers, -}; - #else /* no OpenGL includes */
/**********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 8549c222a69..5bde88ae3c6 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -436,6 +436,11 @@ static BOOL nulldrv_set_pixel_format( HWND hwnd, int old_format, int new_format, return TRUE; }
+static BOOL nulldrv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) +{ + return FALSE; +} + static BOOL nulldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, void **private ) { @@ -477,6 +482,11 @@ static BOOL nulldrv_context_share( void *src_private, void *dst_private ) return FALSE; }
+static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +{ + return FALSE; +} + static BOOL nulldrv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) { return FALSE; @@ -489,6 +499,7 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_describe_pixel_format = nulldrv_describe_pixel_format, .p_init_wgl_extensions = nulldrv_init_wgl_extensions, .p_set_pixel_format = nulldrv_set_pixel_format, + .p_swap_buffers = nulldrv_swap_buffers, .p_pbuffer_create = nulldrv_pbuffer_create, .p_pbuffer_destroy = nulldrv_pbuffer_destroy, .p_pbuffer_updated = nulldrv_pbuffer_updated, @@ -497,6 +508,7 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_context_destroy = nulldrv_context_destroy, .p_context_copy = nulldrv_context_copy, .p_context_share = nulldrv_context_share, + .p_context_flush = nulldrv_context_flush, .p_context_make_current = nulldrv_context_make_current, };
@@ -1364,6 +1376,12 @@ static void display_funcs_init(void) display_funcs->p_wglShareLists = win32u_wglShareLists; 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; + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_extensions_string" ); display_funcs->p_wglGetExtensionsStringARB = win32u_wglGetExtensionsStringARB;
@@ -1402,19 +1420,10 @@ static void display_funcs_init(void) display_funcs->p_wglReleaseTexImageARB = win32u_wglReleaseTexImageARB; display_funcs->p_wglSetPbufferAttribARB = win32u_wglSetPbufferAttribARB;
- if (display_driver_funcs->p_swap_buffers) - { - 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; - - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control" ); - register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control_tear" ); - display_funcs->p_wglSwapIntervalEXT = win32u_wglSwapIntervalEXT; - display_funcs->p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT; - } + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control" ); + register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_EXT_swap_control_tear" ); + display_funcs->p_wglSwapIntervalEXT = win32u_wglSwapIntervalEXT; + display_funcs->p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT; }
static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs )