-- v3: 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
--- 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;
v3: Leave the last change aside for now, just in case.
Dropping a configuration option like that seems like it should have some rationale, especially in the patch itself. Why don't we need this anymore, or why isn't it worth keeping?
It is getting in the way of the refactoring and I prefer to explicitly remove it than silently break it. I asked around, and nobody seem to know about this option, why it was needed or if it's even still useful. It's not even documented.
If it regress something at least we'll know that and what it was useful for, and we can consider implementing a similar mechanism after the dust settles.
It is getting in the way of the refactoring and I prefer to explicitly remove it than silently break it. I asked around, and nobody seem to know about this option, why it was needed or if it's even still useful. It's not even documented.
If it regress something at least we'll know that and what it was useful for, and we can consider implementing a similar mechanism after the dust settles.
That's fine with me as a rationale, what I'm asking is that we say so in the commit message.