-- v4: win32u: Keep track of the most recent window GL drawable. win32u: Use the DC opengl drawable for the memory DC surface. win32u: Pass opengl_drawable pointers to make_current. win32u: Add a flags parameter to opengl_drawable flush. win32u: Use the drawable vtable for flush and swap. winemac: Drop the SkipSingleBufferFlushes option.
From: Rémi Bernon rbernon@codeweavers.com
It's undocumented and doubtfully useful, better remove it than break it silently when changing the way context is being flushed. --- dlls/winemac.drv/macdrv.h | 1 - dlls/winemac.drv/macdrv_main.c | 4 ---- dlls/winemac.drv/opengl.c | 24 ------------------------ 3 files changed, 29 deletions(-)
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 715997eb482..b658c8f7939 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -39,7 +39,6 @@ #include "unixlib.h"
-extern BOOL skip_single_buffer_flushes; extern BOOL allow_vsync; extern BOOL allow_set_gamma; extern BOOL allow_software_rendering; diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c index 9a3a3143e3c..20295d1c6ee 100644 --- a/dlls/winemac.drv/macdrv_main.c +++ b/dlls/winemac.drv/macdrv_main.c @@ -44,7 +44,6 @@ C_ASSERT(NUM_EVENT_TYPES <= sizeof(macdrv_event_mask) * 8);
int topmost_float_inactive = TOPMOST_FLOAT_INACTIVE_NONFULLSCREEN; int capture_displays_for_fullscreen = 0; -BOOL skip_single_buffer_flushes = FALSE; BOOL allow_vsync = TRUE; BOOL allow_set_gamma = TRUE; int left_option_is_alt = 0; @@ -322,9 +321,6 @@ static void setup_options(void) if (!get_config_key(hkey, appkey, "CaptureDisplaysForFullscreen", buffer, sizeof(buffer))) capture_displays_for_fullscreen = IS_OPTION_TRUE(buffer[0]);
- if (!get_config_key(hkey, appkey, "SkipSingleBufferFlushes", buffer, sizeof(buffer))) - skip_single_buffer_flushes = IS_OPTION_TRUE(buffer[0]); - if (!get_config_key(hkey, appkey, "AllowVerticalSync", buffer, sizeof(buffer))) allow_vsync = IS_OPTION_TRUE(buffer[0]);
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 17eacc5eab2..8ef2059211e 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -76,7 +76,6 @@ struct macdrv_context CGLPBufferObj read_pbuffer; int swap_interval; LONG view_moved; - unsigned int last_flush_time; UINT major; };
@@ -106,7 +105,6 @@ static const struct opengl_drawable_funcs macdrv_pbuffer_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 (*pglFlushRenderAPPLE)(void); static const GLubyte *(*pglGetString)(GLenum name); static PFN_glGetIntegerv pglGetIntegerv; static void (*pglReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, @@ -2083,26 +2081,6 @@ static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interva
set_swap_interval(context, interval);
- if (skip_single_buffer_flushes) - { - const pixel_format *pf = &pixel_formats[context->format - 1]; - unsigned int now = NtGetTickCount(); - - TRACE("double buffer %d last flush time %d now %d\n", pf->double_buffer, - context->last_flush_time, now); - if (pglFlushRenderAPPLE && !pf->double_buffer && (now - context->last_flush_time) < 17) - { - TRACE("calling glFlushRenderAPPLE()\n"); - pglFlushRenderAPPLE(); - return TRUE; - } - else - { - TRACE("calling glFlush()\n"); - context->last_flush_time = now; - } - } - return FALSE; }
@@ -2812,8 +2790,6 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co if (!init_gl_info()) goto failed;
- if (gluCheckExtension((GLubyte*)"GL_APPLE_flush_render", (GLubyte*)gl_info.glExtensions)) - LOAD_FUNCPTR(glFlushRenderAPPLE); #undef LOAD_FUNCPTR
*driver_funcs = &macdrv_driver_funcs;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 44 +++++++++-------------- dlls/wineandroid.drv/opengl.c | 46 ++++++++---------------- dlls/winemac.drv/opengl.c | 25 +++++++++---- dlls/winewayland.drv/opengl.c | 23 ++++++------ dlls/winex11.drv/opengl.c | 68 ++++++++++++++--------------------- include/wine/opengl_driver.h | 6 ++-- 6 files changed, 89 insertions(+), 123 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index a8a898ba7be..92ddd6a22ed 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -406,12 +406,6 @@ static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl return TRUE; }
-static BOOL egldrv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) -{ - FIXME( "stub!\n" ); - return TRUE; -} - static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ) { @@ -443,12 +437,6 @@ static BOOL egldrv_context_destroy( void *private ) return FALSE; }
-static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) -{ - FIXME( "stub!\n" ); - return FALSE; -} - static BOOL egldrv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) { FIXME( "stub!\n" ); @@ -462,13 +450,11 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_describe_pixel_format = egldrv_describe_pixel_format, .p_init_wgl_extensions = egldrv_init_wgl_extensions, .p_surface_create = egldrv_surface_create, - .p_swap_buffers = egldrv_swap_buffers, .p_pbuffer_create = egldrv_pbuffer_create, .p_pbuffer_updated = egldrv_pbuffer_updated, .p_pbuffer_bind = egldrv_pbuffer_bind, .p_context_create = egldrv_context_create, .p_context_destroy = egldrv_context_destroy, - .p_context_flush = egldrv_context_flush, .p_context_make_current = egldrv_context_make_current, };
@@ -614,11 +600,6 @@ static BOOL nulldrv_surface_create( HWND hwnd, HDC hdc, int format, struct openg 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, struct opengl_drawable **drawable ) { @@ -645,11 +626,6 @@ static BOOL nulldrv_context_destroy( void *private ) return FALSE; }
-static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) -{ - return FALSE; -} - static BOOL nulldrv_context_make_current( HDC draw, HDC read, void *context ) { return FALSE; @@ -662,13 +638,11 @@ 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_surface_create = nulldrv_surface_create, - .p_swap_buffers = nulldrv_swap_buffers, .p_pbuffer_create = nulldrv_pbuffer_create, .p_pbuffer_updated = nulldrv_pbuffer_updated, .p_pbuffer_bind = nulldrv_pbuffer_bind, .p_context_create = nulldrv_context_create, .p_context_destroy = nulldrv_context_destroy, - .p_context_flush = nulldrv_context_flush, .p_context_make_current = nulldrv_context_make_current, };
@@ -1496,8 +1470,10 @@ static int get_window_swap_interval( HWND hwnd ) static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void) ) { HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; + struct opengl_drawable *draw; int interval; HWND hwnd; + BOOL ret;
if (!(hwnd = NtUserWindowFromDC( draw_hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd ); @@ -1506,7 +1482,12 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)
context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); if (context->memory_pbuffer) return flush_memory_pbuffer( context, draw_hdc, FALSE, flush ); - return driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); + + if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; + ret = draw->funcs->flush( draw, interval, flush ); + opengl_drawable_release( draw ); + + return ret; }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1514,15 +1495,22 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; struct wgl_context *context = NtCurrentTeb()->glContext; const struct opengl_funcs *funcs = &display_funcs; + struct opengl_drawable *draw; int interval; HWND hwnd; + BOOL ret;
if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); if (context->memory_pbuffer) return flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFlush ); - return driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); + + if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; + ret = draw->funcs->swap( draw, interval ); + opengl_drawable_release( draw ); + + return ret; }
static BOOL win32u_wglSwapIntervalEXT( int interval ) diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 99d712d7471..db236029516 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -60,7 +60,6 @@ struct android_context { EGLConfig config; EGLContext context; - EGLSurface surface; };
struct gl_drawable @@ -242,7 +241,6 @@ static BOOL android_context_create( int format, void *share, const int *attribs, ctx = malloc( sizeof(*ctx) );
ctx->config = egl_config_for_format(format); - ctx->surface = 0; ctx->context = funcs->p_eglCreateContext( egl->display, ctx->config, shared_ctx ? shared_ctx->context : EGL_NO_CONTEXT, attribs ); TRACE( "fmt %d ctx %p\n", format, ctx->context );
@@ -272,11 +270,7 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv TRACE( "%p/%p context %p surface %p/%p\n", draw_hdc, read_hdc, ctx->context, draw_gl->surface, read_gl->surface ); ret = funcs->p_eglMakeCurrent( egl->display, draw_gl->surface, read_gl->surface, ctx->context ); - if (ret) - { - ctx->surface = draw_gl->surface; - goto done; - } + if (ret) goto done; } RtlSetLastWin32Error( ERROR_INVALID_HANDLE );
@@ -319,38 +313,26 @@ static void set_swap_interval( struct gl_drawable *gl, int interval ) gl->swap_interval = interval; }
-static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) +static BOOL android_drawable_swap( struct opengl_drawable *base, int interval ) { - struct android_context *ctx = private; - struct gl_drawable *gl; - - if (!ctx) return FALSE; + struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "%p hwnd %p context %p surface %p\n", hdc, hwnd, ctx->context, ctx->surface ); + TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->surface );
- if ((gl = get_gl_drawable( hwnd, hdc ))) - { - set_swap_interval( gl, interval ); - release_gl_drawable( gl ); - } - - if (ctx->surface) funcs->p_eglSwapBuffers( egl->display, ctx->surface ); + set_swap_interval( gl, interval ); + funcs->p_eglSwapBuffers( egl->display, gl->surface ); return TRUE; }
-static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) +static BOOL android_drawable_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) { - struct android_context *ctx = private; - struct gl_drawable *gl; + struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "hwnd %p context %p\n", hwnd, ctx->context ); + TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->surface );
- if ((gl = get_gl_drawable( hwnd, hdc ))) - { - set_swap_interval( gl, interval ); - release_gl_drawable( gl ); - } - return FALSE; + set_swap_interval( gl, interval ); + if (flush) flush(); + return TRUE; }
static const char *android_init_wgl_extensions( struct opengl_funcs *funcs ) @@ -364,16 +346,16 @@ static struct opengl_driver_funcs android_driver_funcs = .p_get_proc_address = android_get_proc_address, .p_init_wgl_extensions = android_init_wgl_extensions, .p_surface_create = android_surface_create, - .p_swap_buffers = android_swap_buffers, .p_context_create = android_context_create, .p_context_destroy = android_context_destroy, - .p_context_flush = android_context_flush, .p_context_make_current = android_context_make_current, };
static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, + .flush = android_drawable_flush, + .swap = android_drawable_swap, };
/********************************************************************** diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 8ef2059211e..822cb32d7c5 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2075,9 +2075,9 @@ 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, void (*flush)(void) ) +static BOOL macdrv_surface_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) { - struct macdrv_context *context = private; + struct macdrv_context *context = NtCurrentTeb()->glReserved2;
set_swap_interval(context, interval);
@@ -2374,6 +2374,15 @@ static void macdrv_pbuffer_destroy(struct opengl_drawable *base) CGLReleasePBuffer(gl->pbuffer); }
+static BOOL macdrv_pbuffer_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) +{ + return FALSE; +} + +static BOOL macdrv_pbuffer_swap(struct opengl_drawable *base, int interval) +{ + return FALSE; +}
static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *private) { @@ -2942,9 +2951,11 @@ static void *macdrv_get_proc_address(const char *name) return dlsym(opengl_handle, name); }
-static BOOL macdrv_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) +static BOOL macdrv_surface_swap(struct opengl_drawable *base, int interval) { - struct macdrv_context *context = private; + struct macdrv_context *context = NtCurrentTeb()->glReserved2; + HWND hwnd = base->hwnd; + HDC hdc = base->hdc; BOOL match = FALSE;
TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL), @@ -3002,10 +3013,8 @@ 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_surface_create = macdrv_surface_create, - .p_swap_buffers = macdrv_swap_buffers, .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, - .p_context_flush = macdrv_context_flush, .p_context_make_current = macdrv_context_make_current, .p_pbuffer_create = macdrv_pbuffer_create, .p_pbuffer_updated = macdrv_pbuffer_updated, @@ -3015,9 +3024,13 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = static const struct opengl_drawable_funcs macdrv_surface_funcs = { .destroy = macdrv_surface_destroy, + .flush = macdrv_surface_flush, + .swap = macdrv_surface_swap, };
static const struct opengl_drawable_funcs macdrv_pbuffer_funcs = { .destroy = macdrv_pbuffer_destroy, + .flush = macdrv_pbuffer_flush, + .swap = macdrv_pbuffer_swap, }; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 304b0c530e8..f06caf66b5b 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -419,25 +419,24 @@ static EGLenum wayland_init_egl_platform(const struct egl_platform *platform, EG return EGL_PLATFORM_WAYLAND_KHR; }
-static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) +static BOOL wayland_drawable_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) { - struct wayland_context *ctx = private; + struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base); + + TRACE("drawable %s\n", debugstr_opengl_drawable(base));
/* Since context_flush is called from operations that may latch the native size, * perform any pending resizes before calling them. */ - if (ctx->draw) wayland_gl_drawable_sync_size(ctx->draw); + wayland_gl_drawable_sync_size(gl);
if (flush) flush(); - return TRUE; }
-static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) +static BOOL wayland_drawable_swap(struct opengl_drawable *base, int interval) { - HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); - struct wayland_gl_drawable *gl; - - if (!(gl = wayland_gl_drawable_get(NtUserWindowFromDC(hdc), hdc))) return FALSE; + HWND hwnd = base->hwnd, toplevel = NtUserGetAncestor(hwnd, GA_ROOT); + struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
if (interval < 0) interval = -interval; if (gl->swap_interval != interval) @@ -454,8 +453,6 @@ static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval if (gl->double_buffered) funcs->p_eglSwapBuffers(egl->display, gl->surface); wayland_gl_drawable_sync_size(gl);
- opengl_drawable_release(&gl->base); - return TRUE; }
@@ -492,10 +489,8 @@ static struct opengl_driver_funcs wayland_driver_funcs = { .p_init_egl_platform = wayland_init_egl_platform, .p_surface_create = wayland_opengl_surface_create, - .p_swap_buffers = wayland_swap_buffers, .p_context_create = wayland_context_create, .p_context_destroy = wayland_context_destroy, - .p_context_flush = wayland_context_flush, .p_context_make_current = wayland_context_make_current, .p_pbuffer_create = wayland_pbuffer_create, .p_pbuffer_updated = wayland_pbuffer_updated, @@ -505,6 +500,8 @@ static struct opengl_driver_funcs wayland_driver_funcs = static const struct opengl_drawable_funcs wayland_drawable_funcs = { .destroy = wayland_drawable_destroy, + .flush = wayland_drawable_flush, + .swap = wayland_drawable_swap, };
/********************************************************************** diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 96b9d62321e..dc0261a54e8 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1327,10 +1327,11 @@ done: return ret; }
-static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) +static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) { - HWND toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); + HWND hwnd = gl->base.hwnd, toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); struct x11drv_win_data *data; + HDC hdc = gl->base.hdc; Drawable window; RECT rect_dst, rect; HRGN region; @@ -1363,16 +1364,9 @@ 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, void (*flush)(void) ) +static BOOL x11drv_surface_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) { - struct gl_drawable *gl; - - if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; - if (gl->base.funcs != &x11drv_surface_funcs) - { - opengl_drawable_release( &gl->base ); - return FALSE; - } + struct gl_drawable *gl = impl_from_opengl_drawable( base );
pthread_mutex_lock( &context_mutex ); set_swap_interval( gl, interval ); @@ -1380,13 +1374,10 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva
if (flush) flush();
- pthread_mutex_lock( &context_mutex ); update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); - pthread_mutex_unlock( &context_mutex );
- present_gl_drawable( hwnd, hdc, gl, TRUE, flush != funcs->p_glFinish ); - opengl_drawable_release( &gl->base ); + present_gl_drawable( gl, TRUE, flush != funcs->p_glFinish ); return TRUE; }
@@ -1530,6 +1521,16 @@ static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) pglXDestroyPbuffer( gdi_display, gl->drawable ); }
+static BOOL x11drv_pbuffer_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) +{ + return FALSE; +} + +static BOOL x11drv_pbuffer_swap( struct opengl_drawable *base, int interval ) +{ + return FALSE; +} + static BOOL x11drv_pbuffer_updated( HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level ) { return GL_TRUE; @@ -1653,35 +1654,19 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) return wglExtensions; }
-/** - * glxdrv_SwapBuffers - * - * Swap the buffers of this DC - */ -static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) +static BOOL x11drv_surface_swap( struct opengl_drawable *base, int interval ) { - struct gl_drawable *gl; - struct x11drv_context *ctx = private; + struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; + struct gl_drawable *gl = impl_from_opengl_drawable( base ); INT64 ust, msc, sbc, target_sbc = 0;
- TRACE("(%p)\n", hdc); - - if (!(gl = get_gl_drawable( hwnd, hdc ))) - { - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return FALSE; - } - if (gl->base.funcs == &x11drv_pbuffer_funcs) - { - opengl_drawable_release( &gl->base ); - return TRUE; - } + TRACE( "drawable %s, interval %d\n", debugstr_opengl_drawable( base ), interval );
pthread_mutex_lock( &context_mutex ); set_swap_interval( gl, interval ); pthread_mutex_unlock( &context_mutex );
- if (!ctx || !gl->offscreen || !pglXSwapBuffersMscOML) pglXSwapBuffers( gdi_display, gl->drawable ); + if (!ctx || gl->offscreen || !pglXSwapBuffersMscOML) pglXSwapBuffers( gdi_display, gl->drawable ); else { funcs->p_glFlush(); @@ -1689,13 +1674,10 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval if (pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); }
- pthread_mutex_lock( &context_mutex ); update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); - pthread_mutex_unlock( &context_mutex );
- present_gl_drawable( hwnd, hdc, gl, !pglXWaitForSbcOML, FALSE ); - opengl_drawable_release( &gl->base ); + present_gl_drawable( gl, !pglXWaitForSbcOML, FALSE ); return TRUE; }
@@ -1706,10 +1688,8 @@ 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_surface_create = x11drv_surface_create, - .p_swap_buffers = x11drv_swap_buffers, .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, - .p_context_flush = x11drv_context_flush, .p_context_make_current = x11drv_context_make_current, .p_pbuffer_create = x11drv_pbuffer_create, .p_pbuffer_updated = x11drv_pbuffer_updated, @@ -1719,11 +1699,15 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = static const struct opengl_drawable_funcs x11drv_surface_funcs = { .destroy = x11drv_surface_destroy, + .flush = x11drv_surface_flush, + .swap = x11drv_surface_swap, };
static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = { .destroy = x11drv_pbuffer_destroy, + .flush = x11drv_pbuffer_flush, + .swap = x11drv_pbuffer_swap, };
#else /* no OpenGL includes */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 6b580fabf4c..cabb5c04e15 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -131,6 +131,10 @@ struct opengl_drawable; struct opengl_drawable_funcs { void (*destroy)( struct opengl_drawable *iface ); + /* flush the drawable and the opengl context, called from render thread */ + BOOL (*flush)( struct opengl_drawable *iface, int interval, void (*flush)(void) ); + /* swap and present the drawable buffers, called from render thread */ + BOOL (*swap)( struct opengl_drawable *iface, int interval ); };
struct opengl_drawable @@ -165,10 +169,8 @@ struct opengl_driver_funcs BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(struct opengl_funcs *funcs); BOOL (*p_surface_create)( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ); - BOOL (*p_swap_buffers)(void*,HWND,HDC,int); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); - BOOL (*p_context_flush)(void*,HWND,HDC,int,void(*)(void)); BOOL (*p_context_make_current)(HDC,HDC,void*); BOOL (*p_pbuffer_create)( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 31 +++++++++++++++++++++++++++---- dlls/wineandroid.drv/opengl.c | 20 ++++---------------- dlls/winemac.drv/opengl.c | 15 ++++++--------- dlls/winewayland.drv/opengl.c | 20 +++++--------------- dlls/winex11.drv/opengl.c | 32 +++++++++++++------------------- include/wine/opengl_driver.h | 17 +++++++++++------ 6 files changed, 66 insertions(+), 69 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 92ddd6a22ed..395a68d8cde 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -174,6 +174,7 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun drawable->ref = 1;
drawable->format = format; + drawable->interval = INT_MIN; drawable->hwnd = hwnd; drawable->hdc = hdc;
@@ -1470,10 +1471,11 @@ static int get_window_swap_interval( HWND hwnd ) static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void) ) { HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; + const struct opengl_funcs *funcs = &display_funcs; struct opengl_drawable *draw; + UINT flags = 0; int interval; HWND hwnd; - BOOL ret;
if (!(hwnd = NtUserWindowFromDC( draw_hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd ); @@ -1484,10 +1486,19 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) if (context->memory_pbuffer) return flush_memory_pbuffer( context, draw_hdc, FALSE, flush );
if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; - ret = draw->funcs->flush( draw, interval, flush ); + if (interval != draw->interval) + { + draw->interval = interval; + flags = GL_FLUSH_INTERVAL; + } + + if (flush) flush(); + if (flush == funcs->p_glFinish) flags |= GL_FLUSH_FINISHED; + + if (flags) draw->funcs->flush( draw, flags ); opengl_drawable_release( draw );
- return ret; + return TRUE; }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1496,6 +1507,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) struct wgl_context *context = NtCurrentTeb()->glContext; const struct opengl_funcs *funcs = &display_funcs; struct opengl_drawable *draw; + UINT flags = 0; int interval; HWND hwnd; BOOL ret; @@ -1507,7 +1519,18 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) if (context->memory_pbuffer) return flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFlush );
if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; - ret = draw->funcs->swap( draw, interval ); + if (interval != draw->interval) + { + draw->interval = interval; + flags = GL_FLUSH_INTERVAL; + } + + if (!draw->hwnd || !draw->funcs->swap) ret = TRUE; /* pbuffer, nothing to do */ + else + { + if (flags) draw->funcs->flush( draw, flags ); + ret = draw->funcs->swap( draw ); + } opengl_drawable_release( draw );
return ret; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index db236029516..9d5d03292e1 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -68,7 +68,6 @@ struct gl_drawable struct list entry; ANativeWindow *window; EGLSurface surface; - int swap_interval; };
static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) @@ -305,34 +304,23 @@ static void *android_get_proc_address( const char *name ) return funcs->p_eglGetProcAddress( name ); }
-static void set_swap_interval( struct gl_drawable *gl, int interval ) -{ - if (interval < 0) interval = -interval; - if (gl->swap_interval == interval) return; - funcs->p_eglSwapInterval( egl->display, interval ); - gl->swap_interval = interval; -} - -static BOOL android_drawable_swap( struct opengl_drawable *base, int interval ) +static BOOL android_drawable_swap( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->surface );
- set_swap_interval( gl, interval ); funcs->p_eglSwapBuffers( egl->display, gl->surface ); return TRUE; }
-static BOOL android_drawable_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) +static void android_drawable_flush( struct opengl_drawable *base, UINT flags ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "drawable %s surface %p\n", debugstr_opengl_drawable( base ), gl->surface ); + TRACE( "drawable %s, surface %p, flags %#x\n", debugstr_opengl_drawable( base ), gl->surface, flags );
- set_swap_interval( gl, interval ); - if (flush) flush(); - return TRUE; + if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); }
static const char *android_init_wgl_extensions( struct opengl_funcs *funcs ) diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 822cb32d7c5..f93890f6af1 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2075,13 +2075,13 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, }
-static BOOL macdrv_surface_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) +static void macdrv_surface_flush(struct opengl_drawable *base, UINT flags) { struct macdrv_context *context = NtCurrentTeb()->glReserved2;
- set_swap_interval(context, interval); + TRACE("%s flags %#x\n", debugstr_opengl_drawable(base), flags);
- return FALSE; + if (flags & GL_FLUSH_INTERVAL) set_swap_interval(context, base->interval); }
@@ -2374,12 +2374,11 @@ static void macdrv_pbuffer_destroy(struct opengl_drawable *base) CGLReleasePBuffer(gl->pbuffer); }
-static BOOL macdrv_pbuffer_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) +static void macdrv_pbuffer_flush(struct opengl_drawable *base, UINT flags) { - return FALSE; }
-static BOOL macdrv_pbuffer_swap(struct opengl_drawable *base, int interval) +static BOOL macdrv_pbuffer_swap(struct opengl_drawable *base) { return FALSE; } @@ -2951,7 +2950,7 @@ static void *macdrv_get_proc_address(const char *name) return dlsym(opengl_handle, name); }
-static BOOL macdrv_surface_swap(struct opengl_drawable *base, int interval) +static BOOL macdrv_surface_swap(struct opengl_drawable *base) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; HWND hwnd = base->hwnd; @@ -2961,8 +2960,6 @@ static BOOL macdrv_surface_swap(struct opengl_drawable *base, int interval) TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL), (context ? context->cglcontext : NULL));
- if (context) set_swap_interval(context, interval); - if (hwnd) { struct macdrv_win_data *data; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index f06caf66b5b..ead93917733 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -58,7 +58,6 @@ struct wayland_gl_drawable struct wl_egl_window *wl_egl_window; EGLSurface surface; LONG resized; - int swap_interval; BOOL double_buffered; };
@@ -174,7 +173,6 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc *attrib++ = EGL_NONE;
if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, hwnd, hdc))) return NULL; - gl->swap_interval = 1;
/* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the @@ -419,32 +417,24 @@ static EGLenum wayland_init_egl_platform(const struct egl_platform *platform, EG return EGL_PLATFORM_WAYLAND_KHR; }
-static BOOL wayland_drawable_flush(struct opengl_drawable *base, int interval, void (*flush)(void)) +static void wayland_drawable_flush(struct opengl_drawable *base, UINT flags) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- TRACE("drawable %s\n", debugstr_opengl_drawable(base)); + TRACE("drawable %s, flags %#x\n", debugstr_opengl_drawable(base), flags); + + if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval(egl->display, abs(base->interval));
/* Since context_flush is called from operations that may latch the native size, * perform any pending resizes before calling them. */ wayland_gl_drawable_sync_size(gl); - - if (flush) flush(); - return TRUE; }
-static BOOL wayland_drawable_swap(struct opengl_drawable *base, int interval) +static BOOL wayland_drawable_swap(struct opengl_drawable *base) { HWND hwnd = base->hwnd, toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- if (interval < 0) interval = -interval; - if (gl->swap_interval != interval) - { - funcs->p_eglSwapInterval(egl->display, interval); - gl->swap_interval = interval; - } - ensure_window_surface_contents(toplevel); set_client_surface(hwnd, gl->client);
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index dc0261a54e8..37bb99d3bcc 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -210,7 +210,6 @@ struct gl_drawable Window window; /* window if drawable is a GLXWindow */ Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ - int swap_interval; BOOL offscreen; HDC hdc_src; HDC hdc_dst; @@ -846,7 +845,6 @@ 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) { @@ -920,7 +918,6 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl
if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd, hdc ))) return FALSE; /* 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->rect = rect;
gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, @@ -1364,21 +1361,23 @@ static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_fin if (region) NtGdiDeleteObjectApp( region ); }
-static BOOL x11drv_surface_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) +static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
- pthread_mutex_lock( &context_mutex ); - set_swap_interval( gl, interval ); - pthread_mutex_unlock( &context_mutex ); + TRACE( "%s flags %#x\n", debugstr_opengl_drawable( base ), flags );
- if (flush) flush(); + if (flags & GL_FLUSH_INTERVAL) + { + pthread_mutex_lock( &context_mutex ); + set_swap_interval( gl, base->interval ); + pthread_mutex_unlock( &context_mutex ); + }
update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl );
- present_gl_drawable( gl, TRUE, flush != funcs->p_glFinish ); - return TRUE; + present_gl_drawable( gl, TRUE, !(flags & GL_FLUSH_FINISHED) ); }
/*********************************************************************** @@ -1521,12 +1520,11 @@ static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) pglXDestroyPbuffer( gdi_display, gl->drawable ); }
-static BOOL x11drv_pbuffer_flush( struct opengl_drawable *base, int interval, void (*flush)(void) ) +static void x11drv_pbuffer_flush( struct opengl_drawable *base, UINT flags ) { - return FALSE; }
-static BOOL x11drv_pbuffer_swap( struct opengl_drawable *base, int interval ) +static BOOL x11drv_pbuffer_swap( struct opengl_drawable *base ) { return FALSE; } @@ -1654,17 +1652,13 @@ static const char *x11drv_init_wgl_extensions( struct opengl_funcs *funcs ) return wglExtensions; }
-static BOOL x11drv_surface_swap( struct opengl_drawable *base, int interval ) +static BOOL x11drv_surface_swap( struct opengl_drawable *base ) { struct x11drv_context *ctx = NtCurrentTeb()->glReserved2; struct gl_drawable *gl = impl_from_opengl_drawable( base ); INT64 ust, msc, sbc, target_sbc = 0;
- TRACE( "drawable %s, interval %d\n", debugstr_opengl_drawable( base ), interval ); - - pthread_mutex_lock( &context_mutex ); - set_swap_interval( gl, interval ); - pthread_mutex_unlock( &context_mutex ); + TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
if (!ctx || gl->offscreen || !pglXSwapBuffersMscOML) pglXSwapBuffers( gdi_display, gl->drawable ); else diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index cabb5c04e15..3fd609e0f27 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -131,20 +131,25 @@ struct opengl_drawable; struct opengl_drawable_funcs { void (*destroy)( struct opengl_drawable *iface ); - /* flush the drawable and the opengl context, called from render thread */ - BOOL (*flush)( struct opengl_drawable *iface, int interval, void (*flush)(void) ); + /* flush and update the drawable front buffer, called from render thread */ + void (*flush)( struct opengl_drawable *iface, UINT flags ); /* swap and present the drawable buffers, called from render thread */ - BOOL (*swap)( struct opengl_drawable *iface, int interval ); + BOOL (*swap)( struct opengl_drawable *iface ); };
+/* flags for opengl_drawable flush */ +#define GL_FLUSH_FINISHED 0x01 +#define GL_FLUSH_INTERVAL 0x02 + struct opengl_drawable { const struct opengl_drawable_funcs *funcs; LONG ref;
- int format; /* pixel format of the drawable */ - HWND hwnd; /* window the drawable was created for */ - HDC hdc; /* DC the drawable was created for */ + int format; /* pixel format of the drawable */ + int interval; /* last set surface swap interval */ + HWND hwnd; /* window the drawable was created for */ + HDC hdc; /* DC the drawable was created for */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 10 ++--- dlls/wineandroid.drv/android.h | 1 - dlls/wineandroid.drv/opengl.c | 80 ++++------------------------------ dlls/winemac.drv/opengl.c | 18 ++++---- dlls/winewayland.drv/opengl.c | 25 +++-------- dlls/winex11.drv/opengl.c | 78 ++++++++------------------------- include/wine/opengl_driver.h | 2 +- 7 files changed, 48 insertions(+), 166 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 395a68d8cde..098e5fe04a8 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -438,7 +438,7 @@ static BOOL egldrv_context_destroy( void *private ) return FALSE; }
-static BOOL egldrv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) +static BOOL egldrv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) { FIXME( "stub!\n" ); return FALSE; @@ -456,7 +456,7 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_pbuffer_bind = egldrv_pbuffer_bind, .p_context_create = egldrv_context_create, .p_context_destroy = egldrv_context_destroy, - .p_context_make_current = egldrv_context_make_current, + .p_make_current = egldrv_make_current, };
static BOOL egl_init( const struct opengl_driver_funcs **driver_funcs ) @@ -627,7 +627,7 @@ static BOOL nulldrv_context_destroy( void *private ) return FALSE; }
-static BOOL nulldrv_context_make_current( HDC draw, HDC read, void *context ) +static BOOL nulldrv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) { return FALSE; } @@ -644,7 +644,7 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_pbuffer_bind = nulldrv_pbuffer_bind, .p_context_create = nulldrv_context_create, .p_context_destroy = nulldrv_context_destroy, - .p_context_make_current = nulldrv_context_make_current, + .p_make_current = nulldrv_make_current, };
static const struct opengl_driver_funcs *driver_funcs = &nulldrv_funcs; @@ -965,7 +965,7 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H WARN( "Unexpected drawables with NULL context\n" ); else if (!force && new_draw == context->draw && new_read == context->read) TRACE( "Drawables didn't change, nothing to do\n" ); - else if (driver_funcs->p_context_make_current( draw_hdc, read_hdc, private )) + else if (driver_funcs->p_make_current( new_draw, new_read, private )) { if ((context->draw = new_draw)) opengl_drawable_add_ref( new_draw ); if ((context->read = new_read)) opengl_drawable_add_ref( new_read ); diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 291d2f0d299..3316ee015ac 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -55,7 +55,6 @@ DECL_FUNCPTR( ANativeWindow_release );
extern pthread_mutex_t drawable_mutex; extern void update_gl_drawable( HWND hwnd ); -extern void destroy_gl_drawable( HWND hwnd ); extern UINT ANDROID_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs );
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 9d5d03292e1..4637a04eec9 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -76,9 +76,6 @@ static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *ba }
static void *opengl_handle; -static struct list gl_drawables = LIST_INIT( gl_drawables ); - -pthread_mutex_t drawable_mutex;
static inline EGLConfig egl_config_for_format(int format) { @@ -87,12 +84,6 @@ static inline EGLConfig egl_config_for_format(int format) return egl->configs[format - egl->config_count - 1]; }
-static struct gl_drawable *gl_drawable_grab( struct gl_drawable *gl ) -{ - opengl_drawable_add_ref( &gl->base ); - return gl; -} - static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, ANativeWindow *window ) { static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; @@ -106,28 +97,10 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, A if (!window) gl->surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); else gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL );
- pthread_mutex_lock( &drawable_mutex ); - list_add_head( &gl_drawables, &gl->entry ); - opengl_drawable_add_ref( &gl->base ); - TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; }
-static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) -{ - struct gl_drawable *gl; - - pthread_mutex_lock( &drawable_mutex ); - LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) - { - if (hwnd && gl->base.hwnd == hwnd) return gl_drawable_grab( gl ); - if (hdc && gl->base.hdc == hdc) return gl_drawable_grab( gl ); - } - pthread_mutex_unlock( &drawable_mutex ); - return NULL; -} - static void android_drawable_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); @@ -135,26 +108,6 @@ static void android_drawable_destroy( struct opengl_drawable *base ) release_ioctl_window( gl->window ); }
-static void release_gl_drawable( struct gl_drawable *gl ) -{ - opengl_drawable_release( &gl->base ); - pthread_mutex_unlock( &drawable_mutex ); -} - -void destroy_gl_drawable( HWND hwnd ) -{ - struct gl_drawable *gl; - - pthread_mutex_lock( &drawable_mutex ); - LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) - { - if (gl->base.hwnd != hwnd) continue; - list_remove( &gl->entry ); - return release_gl_drawable( gl ); - } - pthread_mutex_unlock( &drawable_mutex ); -} - void update_gl_drawable( HWND hwnd ) { struct gl_drawable *old, *new; @@ -163,7 +116,7 @@ void update_gl_drawable( HWND hwnd ) if ((new = create_gl_drawable( hwnd, 0, old->base.format, old->window ))) { set_window_opengl_drawable( hwnd, &new->base ); - release_gl_drawable( new ); + opengl_drawable_release( &new->base ); } opengl_drawable_release( &old->base );
@@ -194,9 +147,7 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg }
if (!(gl = create_gl_drawable( hwnd, hdc, format, NULL ))) return FALSE; - opengl_drawable_add_ref( (*drawable = &gl->base) ); - release_gl_drawable( gl ); - + *drawable = &gl->base; return TRUE; }
@@ -247,14 +198,12 @@ static BOOL android_context_create( int format, void *share, const int *attribs, return TRUE; }
-static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) +static BOOL android_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) { + struct gl_drawable *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); struct android_context *ctx = private; - BOOL ret = FALSE; - struct gl_drawable *draw_gl, *read_gl = NULL; - HWND draw_hwnd;
- TRACE( "%p %p %p\n", draw_hdc, read_hdc, ctx ); + TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), private );
if (!private) { @@ -262,21 +211,8 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv return TRUE; }
- draw_hwnd = NtUserWindowFromDC( draw_hdc ); - if ((draw_gl = get_gl_drawable( draw_hwnd, draw_hdc ))) - { - read_gl = get_gl_drawable( NtUserWindowFromDC( read_hdc ), read_hdc ); - TRACE( "%p/%p context %p surface %p/%p\n", - draw_hdc, read_hdc, ctx->context, draw_gl->surface, read_gl->surface ); - ret = funcs->p_eglMakeCurrent( egl->display, draw_gl->surface, read_gl->surface, ctx->context ); - if (ret) goto done; - } - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - -done: - if (read_gl) release_gl_drawable( read_gl ); - if (draw_gl) release_gl_drawable( draw_gl ); - return ret; + if (!funcs->p_eglMakeCurrent( egl->display, draw->surface, read->surface, ctx->context )) return FALSE; + return TRUE; }
/*********************************************************************** @@ -336,7 +272,7 @@ static struct opengl_driver_funcs android_driver_funcs = .p_surface_create = android_surface_create, .p_context_create = android_context_create, .p_context_destroy = android_context_destroy, - .p_context_make_current = android_context_make_current, + .p_make_current = android_make_current, };
static const struct opengl_drawable_funcs android_drawable_funcs = diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index f93890f6af1..9a28ec10b51 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2383,14 +2383,14 @@ static BOOL macdrv_pbuffer_swap(struct opengl_drawable *base) return FALSE; }
-static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *private) +static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private) { + struct gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); struct macdrv_context *context = private; struct macdrv_win_data *data; HWND hwnd;
- TRACE("draw_hdc %p read_hdc %p context %p/%p/%p\n", draw_hdc, read_hdc, context, - (context ? context->context : NULL), (context ? context->cglcontext : NULL)); + TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), private);
if (!private) { @@ -2399,7 +2399,7 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat return TRUE; }
- if ((hwnd = NtUserWindowFromDC(draw_hdc))) + if ((hwnd = draw->base.hwnd)) { if (!(data = get_win_data(hwnd))) { @@ -2420,7 +2420,7 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat CGLPBufferObj pbuffer;
pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, draw_hdc); + pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, draw->base.hdc); if (!pbuffer) { WARN("no window or pbuffer for DC\n"); @@ -2437,9 +2437,9 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat
context->read_view = NULL; context->read_pbuffer = NULL; - if (read_hdc && read_hdc != draw_hdc) + if (read != draw) { - if ((hwnd = NtUserWindowFromDC(read_hdc))) + if ((hwnd = read->base.hwnd)) { if ((data = get_win_data(hwnd))) { @@ -2455,7 +2455,7 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat else { pthread_mutex_lock(&dc_pbuffers_mutex); - context->read_pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, read_hdc); + context->read_pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, read->base.hdc); pthread_mutex_unlock(&dc_pbuffers_mutex); } } @@ -3012,7 +3012,7 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_surface_create = macdrv_surface_create, .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, - .p_context_make_current = macdrv_context_make_current, + .p_make_current = macdrv_make_current, .p_pbuffer_create = macdrv_pbuffer_create, .p_pbuffer_updated = macdrv_pbuffer_updated, .p_pbuffer_bind = macdrv_pbuffer_bind, diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index ead93917733..ede1b5982fa 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -236,14 +236,14 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) } }
-static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *private) +static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private) { + struct wayland_gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); BOOL ret; struct wayland_context *ctx = private; - struct wayland_gl_drawable *draw, *read; struct wayland_gl_drawable *old_draw = NULL, *old_read = NULL;
- TRACE("draw_hdc=%p read_hdc=%p ctx=%p\n", draw_hdc, read_hdc, ctx); + TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), private);
if (!private) { @@ -251,14 +251,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva return TRUE; }
- draw = wayland_gl_drawable_get(NtUserWindowFromDC(draw_hdc), draw_hdc); - read = wayland_gl_drawable_get(NtUserWindowFromDC(read_hdc), read_hdc); - - TRACE("%p/%p context %p surface %p/%p\n", - draw_hdc, read_hdc, ctx->context, - draw ? draw->surface : EGL_NO_SURFACE, - read ? read->surface : EGL_NO_SURFACE); - /* Since making an EGL surface current may latch the native size, * perform any pending resizes before calling it. */ if (draw) wayland_gl_drawable_sync_size(draw); @@ -273,13 +265,8 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva { old_draw = ctx->draw; old_read = ctx->read; - ctx->draw = draw; - ctx->read = read; - } - else - { - old_draw = draw; - old_read = read; + if ((ctx->draw = draw)) opengl_drawable_add_ref(&draw->base); + if ((ctx->read = read)) opengl_drawable_add_ref(&read->base); }
pthread_mutex_unlock(&gl_object_mutex); @@ -481,7 +468,7 @@ static struct opengl_driver_funcs wayland_driver_funcs = .p_surface_create = wayland_opengl_surface_create, .p_context_create = wayland_context_create, .p_context_destroy = wayland_context_destroy, - .p_context_make_current = wayland_context_make_current, + .p_make_current = wayland_make_current, .p_pbuffer_create = wayland_pbuffer_create, .p_pbuffer_updated = wayland_pbuffer_updated, .p_pbuffer_bind = wayland_pbuffer_bind, diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 37bb99d3bcc..7f0b3215ffd 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -821,12 +821,6 @@ static struct glx_pixel_format *glx_pixel_format_from_format( int format ) return &pixel_formats[format - 1]; }
-static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl ) -{ - opengl_drawable_add_ref( &gl->base ); - return gl; -} - static void x11drv_surface_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); @@ -879,21 +873,6 @@ static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) return ret; }
-static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) -{ - struct gl_drawable *gl; - - pthread_mutex_lock( &context_mutex ); - if (hwnd && !XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) - gl = grab_gl_drawable( gl ); - else if (hdc && !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) - gl = grab_gl_drawable( gl ); - else - gl = NULL; - pthread_mutex_unlock( &context_mutex ); - return gl; -} - static GLXContext create_glxcontext( struct x11drv_context *context, int format, GLXContext share, const int *attribs ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); @@ -1272,26 +1251,13 @@ static void *x11drv_get_proc_address( const char *name ) return pglXGetProcAddressARB( (const GLubyte *)name ); }
-static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawable **draw, - struct gl_drawable **read ) -{ - struct gl_drawable *old_draw, *old_read; - - old_draw = ctx->draw; - old_read = ctx->read; - ctx->draw = *draw; - ctx->read = *read; - *draw = old_draw; - *read = old_read; -} - -static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) +static BOOL x11drv_make_current( struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private ) { + struct gl_drawable *old_draw, *old_read, *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); struct x11drv_context *ctx = private; BOOL ret = FALSE; - struct gl_drawable *draw_gl, *read_gl = NULL;
- TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, ctx); + TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), private );
if (!private) { @@ -1300,28 +1266,22 @@ static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva return TRUE; }
- if ((draw_gl = get_gl_drawable( NtUserWindowFromDC( draw_hdc ), draw_hdc ))) - { - read_gl = get_gl_drawable( NtUserWindowFromDC( read_hdc ), read_hdc ); + if (!pglXMakeContextCurrent) ret = pglXMakeCurrent( gdi_display, draw->drawable, ctx->ctx ); + else ret = pglXMakeContextCurrent( gdi_display, draw->drawable, read->drawable, ctx->ctx ); + if (!ret) return FALSE;
- pthread_mutex_lock( &context_mutex ); - if (!pglXMakeContextCurrent) ret = pglXMakeCurrent( gdi_display, draw_gl->drawable, ctx->ctx ); - else ret = pglXMakeContextCurrent( gdi_display, draw_gl->drawable, read_gl ? read_gl->drawable : 0, ctx->ctx ); - if (ret) - { - set_context_drawables( ctx, &draw_gl, &read_gl ); - NtCurrentTeb()->glReserved2 = ctx; - pthread_mutex_unlock( &context_mutex ); - goto done; - } - pthread_mutex_unlock( &context_mutex ); - } - RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); -done: - if (read_gl) opengl_drawable_release( &read_gl->base ); - if (draw_gl) opengl_drawable_release( &draw_gl->base ); - TRACE( "%p,%p,%p returning %d\n", draw_hdc, read_hdc, ctx, ret ); - return ret; + pthread_mutex_lock( &context_mutex ); + old_draw = ctx->draw; + old_read = ctx->read; + if ((ctx->draw = draw)) opengl_drawable_add_ref( &draw->base ); + if ((ctx->read = read)) opengl_drawable_add_ref( &read->base ); + pthread_mutex_unlock( &context_mutex ); + + if (old_draw) opengl_drawable_release( &old_draw->base ); + if (old_read) opengl_drawable_release( &old_read->base ); + + NtCurrentTeb()->glReserved2 = ctx; + return TRUE; }
static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) @@ -1684,7 +1644,7 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_surface_create = x11drv_surface_create, .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, - .p_context_make_current = x11drv_context_make_current, + .p_make_current = x11drv_make_current, .p_pbuffer_create = x11drv_pbuffer_create, .p_pbuffer_updated = x11drv_pbuffer_updated, .p_pbuffer_bind = x11drv_pbuffer_bind, diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 3fd609e0f27..c319d93ce27 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -176,7 +176,7 @@ struct opengl_driver_funcs BOOL (*p_surface_create)( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); - BOOL (*p_context_make_current)(HDC,HDC,void*); + BOOL (*p_make_current)( struct opengl_drawable *draw, struct opengl_drawable *read, void *private ); BOOL (*p_pbuffer_create)( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ); BOOL (*p_pbuffer_updated)( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/bitmap.c | 5 +++ dlls/win32u/opengl.c | 78 ++++++++++++++++++-------------------------- 2 files changed, 37 insertions(+), 46 deletions(-)
diff --git a/dlls/win32u/bitmap.c b/dlls/win32u/bitmap.c index a02708dc8de..2fec0a1ed32 100644 --- a/dlls/win32u/bitmap.c +++ b/dlls/win32u/bitmap.c @@ -31,6 +31,7 @@ #include "winbase.h" #include "wingdi.h" #include "ntgdi_private.h" +#include "wine/opengl_driver.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(bitmap); @@ -370,6 +371,7 @@ LONG WINAPI NtGdiSetBitmapBits( */ HGDIOBJ WINAPI NtGdiSelectBitmap( HDC hdc, HGDIOBJ handle ) { + struct opengl_drawable *drawable = NULL; HGDIOBJ ret; BITMAPOBJ *bitmap; DC *dc; @@ -419,6 +421,8 @@ HGDIOBJ WINAPI NtGdiSelectBitmap( HDC hdc, HGDIOBJ handle ) } else { + drawable = dc->opengl_drawable; + dc->opengl_drawable = NULL; dc->hBitmap = handle; GDI_inc_ref_count( handle ); dc->dirty = 0; @@ -434,6 +438,7 @@ HGDIOBJ WINAPI NtGdiSelectBitmap( HDC hdc, HGDIOBJ handle )
done: release_dc_ptr( dc ); + if (ret && drawable) opengl_drawable_release( drawable ); return ret; }
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 098e5fe04a8..83472326ac9 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -44,8 +44,6 @@ struct wgl_context void *driver_private; int pixel_format;
- HBITMAP memory_bitmap; - struct wgl_pbuffer *memory_pbuffer; struct opengl_drawable *draw; struct opengl_drawable *read; }; @@ -767,21 +765,20 @@ static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc ) return drawable; }
-static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) +static BOOL create_memory_pbuffer( HDC hdc, int format ) { const struct opengl_funcs *funcs = &display_funcs; - struct wgl_pbuffer *pbuffer = NULL; + dib_info dib = {.rect = {0, 0, 1, 1}}; + BOOL ret = TRUE; BITMAPOBJ *bmp; - dib_info dib; - BOOL ret; DC *dc;
- if (!(dc = get_dc_ptr( hdc ))) return NULL; - if (get_gdi_object_type( hdc ) != NTGDI_OBJ_MEMDC) ret = FALSE; - else if (!(bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) ret = FALSE; - else + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + else if (dc->opengl_drawable) ret = FALSE; + else if (get_gdi_object_type( hdc ) != NTGDI_OBJ_MEMDC) ret = FALSE; + else if ((bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) { - ret = init_dib_info_from_bitmapobj( &dib, bmp ); + init_dib_info_from_bitmapobj( &dib, bmp ); GDI_ReleaseObj( dc->hBitmap ); } release_dc_ptr( dc ); @@ -789,33 +786,38 @@ static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) if (ret) { int width = dib.rect.right - dib.rect.left, height = dib.rect.bottom - dib.rect.top; - pbuffer = funcs->p_wglCreatePbufferARB( hdc, format, width, height, NULL ); - if (pbuffer) set_dc_opengl_drawable( hdc, pbuffer->drawable ); + struct wgl_pbuffer *pbuffer; + + if (!(pbuffer = funcs->p_wglCreatePbufferARB( 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 ); + } }
- if (pbuffer) TRACE( "Created pbuffer %p for memory DC %p\n", pbuffer, hdc ); - else WARN( "Failed to create pbuffer for memory DC %p\n", hdc ); - return pbuffer; + return ret; }
-static BOOL flush_memory_pbuffer( struct wgl_context *context, HDC hdc, BOOL write, void (*flush)(void) ) +static BOOL flush_memory_dc( struct wgl_context *context, HDC hdc, BOOL write, void (*flush)(void) ) { const struct opengl_funcs *funcs = &display_funcs; + BOOL ret = TRUE; BITMAPOBJ *bmp; DC *dc;
- if (flush) flush(); - - if (!(dc = get_dc_ptr( hdc ))) return TRUE; - if ((bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + if (get_gdi_object_type( hdc ) != NTGDI_OBJ_MEMDC) ret = FALSE; + else if (context && (bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct bitblt_coords src = {0}; struct gdi_image_bits bits;
- if (dc->hBitmap != context->memory_bitmap) write = TRUE; - context->memory_bitmap = dc->hBitmap; + if (flush) flush();
if (!get_image_from_bitmap( bmp, info, &bits, &src )) { @@ -827,16 +829,7 @@ static BOOL flush_memory_pbuffer( struct wgl_context *context, HDC hdc, BOOL wri } release_dc_ptr( dc );
- return TRUE; -} - -static void destroy_memory_pbuffer( struct wgl_context *context, HDC hdc ) -{ - const struct opengl_funcs *funcs = &display_funcs; - flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFinish ); - set_dc_opengl_drawable( hdc, NULL ); - funcs->p_wglDestroyPbufferARB( context->memory_pbuffer ); - context->memory_pbuffer = NULL; + return ret; }
static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) @@ -952,8 +945,9 @@ static struct wgl_context *win32u_wglCreateContext( HDC hdc ) static BOOL context_set_drawables( struct wgl_context *context, void *private, HDC draw_hdc, HDC read_hdc, BOOL force ) { struct opengl_drawable *new_draw, *new_read, *old_draw = context->draw, *old_read = context->read; - BOOL ret = FALSE; + BOOL ret = FALSE, flush;
+ flush = create_memory_pbuffer( draw_hdc, context->pixel_format ); new_draw = get_dc_opengl_drawable( draw_hdc ); new_read = get_dc_opengl_drawable( read_hdc );
@@ -976,6 +970,8 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H
if (new_draw) opengl_drawable_release( new_draw ); if (new_read) opengl_drawable_release( new_read ); + + if (ret && flush) flush_memory_dc( context, draw_hdc, TRUE, NULL ); return ret; }
@@ -993,14 +989,11 @@ static BOOL win32u_wglDeleteContext( struct wgl_context *context )
static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context ) { - HDC hdc = draw_hdc, prev_draw = NtCurrentTeb()->glReserved1[0]; struct wgl_context *prev_context = NtCurrentTeb()->glContext; int format;
TRACE( "draw_hdc %p, read_hdc %p, context %p\n", draw_hdc, read_hdc, context );
- if (prev_context && prev_context->memory_pbuffer) destroy_memory_pbuffer( prev_context, prev_draw ); - if (!context) { if (!(context = prev_context)) return TRUE; @@ -1022,15 +1015,8 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return FALSE; }
- if ((context->memory_pbuffer = create_memory_pbuffer( draw_hdc, context->pixel_format ))) - { - if (read_hdc != draw_hdc) ERR( "read != draw not supported\n" ); - draw_hdc = read_hdc = context->memory_pbuffer->hdc; - } - if (!context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, TRUE )) return FALSE; NtCurrentTeb()->glContext = context; - if (context->memory_pbuffer) flush_memory_pbuffer( context, hdc, TRUE, NULL ); return TRUE; }
@@ -1483,7 +1469,7 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush );
context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); - if (context->memory_pbuffer) return flush_memory_pbuffer( context, draw_hdc, FALSE, flush ); + if (flush_memory_dc( context, draw_hdc, FALSE, flush )) return TRUE;
if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; if (interval != draw->interval) @@ -1516,7 +1502,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) else interval = get_window_swap_interval( hwnd );
context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); - if (context->memory_pbuffer) return flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFlush ); + if (flush_memory_dc( context, hdc, FALSE, funcs->p_glFlush )) return TRUE;
if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; if (interval != draw->interval)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 83472326ac9..7f73742fe42 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -733,10 +733,14 @@ struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ) static void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ) { void *old_drawable = NULL; + HWND hwnd; DC *dc;
TRACE( "hdc %p, new_drawable %s\n", hdc, debugstr_opengl_drawable( new_drawable ) );
+ /* update the current window drawable to the last used draw surface */ + if ((hwnd = NtUserWindowFromDC( hdc ))) set_window_opengl_drawable( hwnd, new_drawable ); + if ((dc = get_dc_ptr( hdc ))) { old_drawable = dc->opengl_drawable; @@ -747,13 +751,14 @@ static void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawabl if (old_drawable) opengl_drawable_release( old_drawable ); }
-static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc ) +static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc, BOOL read ) { void *drawable = NULL; HWND hwnd; DC *dc;
- if ((hwnd = NtUserWindowFromDC( hdc ))) return get_window_opengl_drawable( hwnd ); + /* get the last used window drawable when reading */ + if ((hwnd = NtUserWindowFromDC( hdc )) && read) return get_window_opengl_drawable( hwnd );
if ((dc = get_dc_ptr( hdc ))) { @@ -857,9 +862,9 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal )
if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format;
- drawable = get_window_opengl_drawable( hwnd ); + drawable = get_dc_opengl_drawable( hdc, FALSE ); if ((ret = driver_funcs->p_surface_create( hwnd, hdc, new_format, &drawable ))) - set_window_opengl_drawable( hwnd, drawable ); + set_dc_opengl_drawable( hdc, drawable ); if (drawable) opengl_drawable_release( drawable );
if (!ret) return FALSE; @@ -946,10 +951,11 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H { struct opengl_drawable *new_draw, *new_read, *old_draw = context->draw, *old_read = context->read; BOOL ret = FALSE, flush; + HWND hwnd;
flush = create_memory_pbuffer( draw_hdc, context->pixel_format ); - new_draw = get_dc_opengl_drawable( draw_hdc ); - new_read = get_dc_opengl_drawable( read_hdc ); + new_draw = get_dc_opengl_drawable( draw_hdc, FALSE ); + new_read = get_dc_opengl_drawable( read_hdc, read_hdc != draw_hdc );
TRACE( "context %p, new_draw %s, new_read %s\n", context, debugstr_opengl_drawable( new_draw ), debugstr_opengl_drawable( new_read ) );
@@ -965,6 +971,9 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H if ((context->read = new_read)) opengl_drawable_add_ref( new_read ); if (old_draw) opengl_drawable_release( old_draw ); if (old_read) opengl_drawable_release( old_read ); + + /* update the current window drawable to the last used draw surface */ + if ((hwnd = NtUserWindowFromDC( draw_hdc ))) set_window_opengl_drawable( hwnd, new_draw ); ret = TRUE; }
@@ -1471,7 +1480,7 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); if (flush_memory_dc( context, draw_hdc, FALSE, flush )) return TRUE;
- if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; + if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; if (interval != draw->interval) { draw->interval = interval; @@ -1504,7 +1513,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, FALSE ); if (flush_memory_dc( context, hdc, FALSE, funcs->p_glFlush )) return TRUE;
- if (!(draw = get_dc_opengl_drawable( draw_hdc ))) return FALSE; + if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; if (interval != draw->interval) { draw->interval = interval;
v4: Detail the option removal commit message.