-- v2: winewayland: Remove now unnecessary context sync. winemac: Remove now unnecessary context sync. wineandroid: Remove now unnecessary context sync. win32u: Track and update opengl drawables in the contexts. win32u: Keep a reference to the pbuffer drawables in the DCs. win32u: Keep a reference to the GL drawables in the windows.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/opengl.c | 52 +++++++++++++++++++++++++++++++---- dlls/win32u/window.c | 3 ++ dlls/wineandroid.drv/opengl.c | 32 +++++++++++++-------- dlls/winemac.drv/opengl.c | 23 +++++++++++++--- dlls/winewayland.drv/opengl.c | 16 +++++------ dlls/winex11.drv/opengl.c | 32 ++++++--------------- include/wine/opengl_driver.h | 2 +- 8 files changed, 107 insertions(+), 54 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 33b5cdc3b27..a3714cd8994 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -67,6 +67,7 @@ typedef struct tagWND HIMC imc; /* window's input context */ struct window_surface *surface; /* Window surface if any */ struct list vulkan_surfaces; /* list of vulkan surfaces created for this window */ + struct opengl_drawable *opengl_drawable; /* last GL client surface for this window */ struct tagDIALOGINFO *dlgInfo; /* Dialog additional info (dialogs only) */ int swap_interval; /* OpenGL surface swap interval */ int pixel_format; /* Pixel format set by the graphics driver */ diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index c165f9588c7..7450fb91ada 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -398,7 +398,7 @@ static const char *egldrv_init_wgl_extensions( struct opengl_funcs *funcs ) return ""; }
-static BOOL egldrv_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) +static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { FIXME( "stub!\n" ); return TRUE; @@ -459,7 +459,7 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_init_pixel_formats = egldrv_init_pixel_formats, .p_describe_pixel_format = egldrv_describe_pixel_format, .p_init_wgl_extensions = egldrv_init_wgl_extensions, - .p_set_pixel_format = egldrv_set_pixel_format, + .p_surface_create = egldrv_surface_create, .p_swap_buffers = egldrv_swap_buffers, .p_pbuffer_create = egldrv_pbuffer_create, .p_pbuffer_updated = egldrv_pbuffer_updated, @@ -607,7 +607,7 @@ static const char *nulldrv_init_wgl_extensions( struct opengl_funcs *funcs ) return ""; }
-static BOOL nulldrv_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) +static BOOL nulldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { return TRUE; } @@ -648,7 +648,7 @@ static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interv return FALSE; }
-static BOOL nulldrv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) +static BOOL nulldrv_context_make_current( HDC draw, HDC read, void *context ) { return FALSE; } @@ -659,7 +659,7 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_init_pixel_formats = nulldrv_init_pixel_formats, .p_describe_pixel_format = nulldrv_describe_pixel_format, .p_init_wgl_extensions = nulldrv_init_wgl_extensions, - .p_set_pixel_format = nulldrv_set_pixel_format, + .p_surface_create = nulldrv_surface_create, .p_swap_buffers = nulldrv_swap_buffers, .p_pbuffer_create = nulldrv_pbuffer_create, .p_pbuffer_updated = nulldrv_pbuffer_updated, @@ -723,6 +723,38 @@ static int win32u_wglGetPixelFormat( HDC hdc ) return format > 0 ? format : 0; }
+static void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable ) +{ + void *old_drawable = NULL; + WND *win; + + TRACE( "hwnd %p, new_drawable %s\n", hwnd, debugstr_opengl_drawable( new_drawable ) ); + + if ((win = get_win_ptr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) + { + old_drawable = win->opengl_drawable; + if ((win->opengl_drawable = new_drawable)) opengl_drawable_add_ref( new_drawable ); + release_win_ptr( win ); + } + + if (old_drawable) opengl_drawable_release( old_drawable ); +} + +static struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ) +{ + void *drawable = NULL; + WND *win; + + if ((win = get_win_ptr( hwnd )) && win != WND_DESKTOP && win != WND_OTHER_PROCESS) + { + if ((drawable = win->opengl_drawable)) opengl_drawable_add_ref( drawable ); + release_win_ptr( win ); + } + + TRACE( "hwnd %p, drawable %s\n", hwnd, debugstr_opengl_drawable( drawable ) ); + return drawable; +} + static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) { const struct opengl_funcs *funcs = &display_funcs; @@ -804,7 +836,9 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal )
if ((hwnd = NtUserWindowFromDC( hdc ))) { + struct opengl_drawable *drawable; int old_format; + BOOL ret;
if (new_format > onscreen) { @@ -815,7 +849,13 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal );
if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format; - if (!driver_funcs->p_set_pixel_format( hwnd, old_format, new_format, internal )) return FALSE; + + drawable = get_window_opengl_drawable( hwnd ); + if ((ret = driver_funcs->p_surface_create( hwnd, hdc, new_format, &drawable ))) + set_window_opengl_drawable( hwnd, drawable ); + if (drawable) opengl_drawable_release( drawable ); + + if (!ret) return FALSE; return set_window_pixel_format( hwnd, new_format, internal ); }
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 08db9cab0bd..352dc938b66 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -29,6 +29,7 @@ #define WIN32_NO_STATUS #include "ntgdi_private.h" #include "ntuser_private.h" +#include "wine/opengl_driver.h" #include "wine/server.h" #include "wine/debug.h"
@@ -5054,6 +5055,7 @@ LRESULT destroy_window( HWND hwnd ) }
vulkan_detach_surfaces( &vulkan_surfaces ); + if (win->opengl_drawable) opengl_drawable_release( win->opengl_drawable ); user_driver->pDestroyWindow( hwnd );
free_window_handle( hwnd ); @@ -5208,6 +5210,7 @@ void destroy_thread_windows(void) TRACE( "destroying %p\n", entry );
user_driver->pDestroyWindow( entry->handle ); + if (win->opengl_drawable) opengl_drawable_release( win->opengl_drawable );
NtUserDestroyMenu( entry->menu ); NtUserDestroyMenu( entry->sys_menu ); diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 593b5e448aa..c570d82e2e4 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -199,23 +199,31 @@ void update_gl_drawable( HWND hwnd ) } }
-static BOOL android_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) +static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { struct gl_drawable *gl;
- TRACE( "hwnd %p, old_format %d, new_format %d, internal %u\n", hwnd, old_format, new_format, internal ); + TRACE( "hwnd %p, hdc %p, format %d, drawable %p\n", hwnd, hdc, format, drawable );
- if ((gl = get_gl_drawable( hwnd, 0 ))) + if (*drawable) { - if (internal) - { - EGLint pf; - funcs->p_eglGetConfigAttrib( egl->display, egl_config_for_format(new_format), EGL_NATIVE_VISUAL_ID, &pf ); - gl->window->perform( gl->window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, pf ); - gl->base.format = new_format; - } + EGLint pf; + + FIXME( "Updating drawable %s, multiple surfaces not implemented\n", debugstr_opengl_drawable( *drawable ) ); + + gl = impl_from_opengl_drawable( *drawable ); + funcs->p_eglGetConfigAttrib( egl->display, egl_config_for_format(format), EGL_NATIVE_VISUAL_ID, &pf ); + gl->window->perform( gl->window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, pf ); + gl->base.hwnd = hwnd; + gl->base.hdc = hdc; + gl->base.format = format; + + TRACE( "Updated drawable %s\n", debugstr_opengl_drawable( *drawable ) ); + return TRUE; } - else if (!(gl = create_gl_drawable( hwnd, 0, new_format ))) return FALSE; + + if (!(gl = create_gl_drawable( hwnd, hdc, format ))) return FALSE; + opengl_drawable_add_ref( (*drawable = &gl->base) ); release_gl_drawable( gl );
return TRUE; @@ -397,7 +405,7 @@ static struct opengl_driver_funcs android_driver_funcs = .p_init_egl_platform = android_init_egl_platform, .p_get_proc_address = android_get_proc_address, .p_init_wgl_extensions = android_init_wgl_extensions, - .p_set_pixel_format = android_set_pixel_format, + .p_surface_create = android_surface_create, .p_swap_buffers = android_swap_buffers, .p_context_create = android_context_create, .p_context_destroy = android_context_destroy, diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index bddd6f531f4..11f90ff8ac1 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -100,6 +100,7 @@ static pthread_mutex_t dc_pbuffers_mutex = PTHREAD_MUTEX_INITIALIZER; static void *opengl_handle; static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs macdrv_driver_funcs; +static const struct opengl_drawable_funcs macdrv_surface_funcs; static const struct opengl_drawable_funcs macdrv_pbuffer_funcs;
static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, @@ -1473,11 +1474,12 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, return TRUE; }
-static BOOL macdrv_set_pixel_format(HWND hwnd, int old_format, int new_format, BOOL internal) +static BOOL macdrv_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { struct macdrv_win_data *data; + struct gl_drawable *gl;
- TRACE("hwnd %p, old_format %d, new_format %d, internal %u\n", hwnd, old_format, new_format, internal); + TRACE("hwnd %p, hdc %p, format %d, drawable %p\n", hwnd, hdc, format, drawable);
if (!(data = get_win_data(hwnd))) { @@ -1485,11 +1487,19 @@ static BOOL macdrv_set_pixel_format(HWND hwnd, int old_format, int new_format, B return FALSE; }
- data->pixel_format = new_format; + data->pixel_format = format; release_win_data(data); + + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, hwnd, hdc))) return FALSE; + *drawable = &gl->base; + return TRUE; }
+static void macdrv_surface_destroy(struct opengl_drawable *base) +{ + TRACE("drawable %s\n", debugstr_opengl_drawable(base)); +}
/********************************************************************** * mark_contexts_for_moved_view @@ -3050,7 +3060,7 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_init_pixel_formats = macdrv_init_pixel_formats, .p_describe_pixel_format = macdrv_describe_pixel_format, .p_init_wgl_extensions = macdrv_init_wgl_extensions, - .p_set_pixel_format = macdrv_set_pixel_format, + .p_surface_create = macdrv_surface_create, .p_swap_buffers = macdrv_swap_buffers, .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, @@ -3061,6 +3071,11 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_pbuffer_bind = macdrv_pbuffer_bind, };
+static const struct opengl_drawable_funcs macdrv_surface_funcs = +{ + .destroy = macdrv_surface_destroy, +}; + static const struct opengl_drawable_funcs macdrv_pbuffer_funcs = { .destroy = macdrv_pbuffer_destroy, diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 0b7595c3dcf..2bfd41a6358 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -337,23 +337,23 @@ static void wayland_context_refresh(struct wayland_context *ctx) if (old_read) opengl_drawable_release(&old_read->base); }
-static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, BOOL internal) +static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { + struct opengl_drawable *previous; struct wayland_gl_drawable *gl; RECT rect;
- /* Even for internal pixel format fail setting it if the app has already set a - * different pixel format. Let wined3d create a backup GL context instead. - * Switching pixel format involves drawable recreation and is much more expensive - * than blitting from backup context. */ - if (old_format) return old_format == new_format; + if ((previous = *drawable) && previous->format == format) return TRUE;
NtUserGetClientRect(hwnd, &rect, NtUserGetDpiForWindow(hwnd)); if (rect.right == rect.left) rect.right = rect.left + 1; if (rect.bottom == rect.top) rect.bottom = rect.top + 1;
- if (!(gl = wayland_gl_drawable_create(hwnd, 0, new_format, rect.right - rect.left, rect.bottom - rect.top))) return FALSE; + if (!(gl = wayland_gl_drawable_create(hwnd, 0, format, rect.right - rect.left, rect.bottom - rect.top))) return FALSE; wayland_update_gl_drawable(hwnd, gl); + + if (previous) opengl_drawable_release( previous ); + opengl_drawable_add_ref( (*drawable = &gl->base) ); return TRUE; }
@@ -538,7 +538,7 @@ static UINT wayland_pbuffer_bind(HDC hdc, struct opengl_drawable *base, GLenum b static struct opengl_driver_funcs wayland_driver_funcs = { .p_init_egl_platform = wayland_init_egl_platform, - .p_set_pixel_format = wayland_set_pixel_format, + .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, diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index ad82c8d8f7a..96b9d62321e 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -908,18 +908,17 @@ static GLXContext create_glxcontext( struct x11drv_context *context, int format, return ctx; }
-/*********************************************************************** - * create_gl_drawable - */ -static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) +static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); + struct opengl_drawable *previous; struct gl_drawable *gl, *prev; RECT rect;
+ if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd, 0 ))) return NULL; + 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; @@ -933,7 +932,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) if (!gl->drawable) { free( gl ); - return NULL; + return FALSE; }
TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); @@ -941,26 +940,13 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) pthread_mutex_lock( &context_mutex ); if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) opengl_drawable_release( &prev->base ); - XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)grab_gl_drawable(gl) ); + XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl ); pthread_mutex_unlock( &context_mutex ); - return gl; -}
-static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) -{ - struct gl_drawable *gl; - - /* Even for internal pixel format fail setting it if the app has already set a - * different pixel format. Let wined3d create a backup GL context instead. - * Switching pixel format involves drawable recreation and is much more expensive - * than blitting from backup context. */ - if (old_format) return old_format == new_format; - - if (!(gl = create_gl_drawable( hwnd, new_format ))) return FALSE; - TRACE( "created GL drawable %lx for win %p\n", gl->drawable, hwnd); XFlush( gdi_display ); - opengl_drawable_release( &gl->base );
+ if (previous) opengl_drawable_release( previous ); + opengl_drawable_add_ref( (*drawable = &gl->base) ); return TRUE; }
@@ -1719,7 +1705,7 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_init_pixel_formats = x11drv_init_pixel_formats, .p_describe_pixel_format = x11drv_describe_pixel_format, .p_init_wgl_extensions = x11drv_init_wgl_extensions, - .p_set_pixel_format = x11drv_set_pixel_format, + .p_surface_create = x11drv_surface_create, .p_swap_buffers = x11drv_swap_buffers, .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 15f9b26e5cf..3cf775a4317 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -161,7 +161,7 @@ struct opengl_driver_funcs UINT (*p_init_pixel_formats)(UINT*); BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); const char *(*p_init_wgl_extensions)(struct opengl_funcs *funcs); - BOOL (*p_set_pixel_format)(HWND,int,int,BOOL); + 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*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dc.c | 7 +++++++ dlls/win32u/ntgdi_private.h | 1 + dlls/win32u/opengl.c | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+)
diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 922fa8b5317..16092141163 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -37,6 +37,7 @@ #include "winerror.h" #include "ntgdi_private.h"
+#include "wine/opengl_driver.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dc); @@ -457,6 +458,7 @@ void DC_UpdateXforms( DC *dc ) */ static BOOL reset_dc_state( HDC hdc ) { + struct opengl_drawable *drawable; DC *dc, *dcs, *next;
if (!(dc = get_dc_ptr( hdc ))) return FALSE; @@ -485,7 +487,12 @@ static BOOL reset_dc_state( HDC hdc ) } dc->saved_dc = NULL; dc->attr->save_level = 0; + + drawable = dc->opengl_drawable; + dc->opengl_drawable = NULL; release_dc_ptr( dc ); + + if (drawable) opengl_drawable_release( drawable ); return TRUE; }
diff --git a/dlls/win32u/ntgdi_private.h b/dlls/win32u/ntgdi_private.h index 136921a211c..78b3ad89796 100644 --- a/dlls/win32u/ntgdi_private.h +++ b/dlls/win32u/ntgdi_private.h @@ -61,6 +61,7 @@ typedef struct tagDC UINT bounds_enabled:1; /* bounds tracking is enabled */ UINT path_open:1; /* path is currently open (only for saved DCs) */ UINT is_display:1; /* DC is for display device */ + struct opengl_drawable *opengl_drawable; /* GL driver drawable for the DC */
RECT device_rect; /* rectangle for the whole device */ int pixel_format; /* pixel format (for memory DCs) */ diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 7450fb91ada..817e723d94a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -755,6 +755,23 @@ static struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ) return drawable; }
+static void set_dc_opengl_drawable( HDC hdc, struct opengl_drawable *new_drawable ) +{ + void *old_drawable = NULL; + DC *dc; + + TRACE( "hdc %p, new_drawable %s\n", hdc, debugstr_opengl_drawable( new_drawable ) ); + + if ((dc = get_dc_ptr( hdc ))) + { + old_drawable = dc->opengl_drawable; + if ((dc->opengl_drawable = new_drawable)) opengl_drawable_add_ref( new_drawable ); + release_dc_ptr( dc ); + } + + if (old_drawable) opengl_drawable_release( old_drawable ); +} + static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) { const struct opengl_funcs *funcs = &display_funcs; @@ -778,6 +795,7 @@ static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) { 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 ); }
if (pbuffer) TRACE( "Created pbuffer %p for memory DC %p\n", pbuffer, hdc ); @@ -821,6 +839,7 @@ 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; } @@ -1114,7 +1133,10 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int if (driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, pbuffer->texture_target, max_level, &pbuffer->width, &pbuffer->height, &pbuffer->drawable )) + { + set_dc_opengl_drawable( pbuffer->hdc, pbuffer->drawable ); return pbuffer; + }
failed: RtlSetLastWin32Error( ERROR_INVALID_DATA );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 59 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 817e723d94a..ccb0cec01d6 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -46,6 +46,8 @@ struct wgl_context
HBITMAP memory_bitmap; struct wgl_pbuffer *memory_pbuffer; + struct opengl_drawable *draw; + struct opengl_drawable *read; };
struct wgl_pbuffer @@ -772,6 +774,24 @@ 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 ) +{ + void *drawable = NULL; + HWND hwnd; + DC *dc; + + if ((hwnd = NtUserWindowFromDC( hdc ))) return get_window_opengl_drawable( hwnd ); + + if ((dc = get_dc_ptr( hdc ))) + { + if ((drawable = dc->opengl_drawable)) opengl_drawable_add_ref( drawable ); + release_dc_ptr( dc ); + } + + TRACE( "hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable( drawable ) ); + return drawable; +} + static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) { const struct opengl_funcs *funcs = &display_funcs; @@ -954,6 +974,36 @@ static struct wgl_context *win32u_wglCreateContext( HDC hdc ) return context_create( hdc, NULL, NULL ); }
+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; + + new_draw = get_dc_opengl_drawable( draw_hdc ); + new_read = get_dc_opengl_drawable( read_hdc ); + + TRACE( "context %p, new_draw %s, new_read %s\n", context, debugstr_opengl_drawable( new_draw ), debugstr_opengl_drawable( new_read ) ); + + if (private && (!new_draw || !new_read)) + WARN( "One of the drawable has been lost, ignoring\n" ); + else if (!private && (new_draw || new_read)) + 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 )) + { + if ((context->draw = new_draw)) opengl_drawable_add_ref( new_draw ); + 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 ); + ret = TRUE; + } + + if (new_draw) opengl_drawable_release( new_draw ); + if (new_read) opengl_drawable_release( new_read ); + return ret; +} + static BOOL win32u_wglDeleteContext( struct wgl_context *context ) { BOOL ret; @@ -979,7 +1029,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!context) { if (!(context = prev_context)) return TRUE; - if (!driver_funcs->p_context_make_current( NULL, NULL, NULL )) return FALSE; + if (!context_set_drawables( context, NULL, NULL, NULL, TRUE )) return FALSE; NtCurrentTeb()->glContext = NULL; return TRUE; } @@ -1003,7 +1053,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct draw_hdc = read_hdc = context->memory_pbuffer->hdc; }
- if (!driver_funcs->p_context_make_current( draw_hdc, read_hdc, context->driver_private )) return FALSE; + 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; @@ -1445,7 +1495,7 @@ 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]; + HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; int interval; HWND hwnd;
@@ -1454,12 +1504,14 @@ 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 ); return driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); }
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; int interval; @@ -1468,6 +1520,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) 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 ); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 4 +- dlls/wineandroid.drv/opengl.c | 84 +++++++++-------------------------- include/wine/opengl_driver.h | 3 ++ 3 files changed, 26 insertions(+), 65 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index ccb0cec01d6..a8a898ba7be 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -725,7 +725,7 @@ static int win32u_wglGetPixelFormat( HDC hdc ) return format > 0 ? format : 0; }
-static void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable ) +void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_drawable ) { void *old_drawable = NULL; WND *win; @@ -742,7 +742,7 @@ static void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *new_d if (old_drawable) opengl_drawable_release( old_drawable ); }
-static struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ) +struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ) { void *drawable = NULL; WND *win; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index c570d82e2e4..c54f5f409a6 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -58,12 +58,9 @@ struct egl_pixel_format
struct android_context { - struct list entry; EGLConfig config; EGLContext context; EGLSurface surface; - HWND hwnd; - BOOL refresh; };
struct gl_drawable @@ -72,7 +69,6 @@ struct gl_drawable struct list entry; ANativeWindow *window; EGLSurface surface; - EGLSurface pbuffer; int swap_interval; };
@@ -82,7 +78,6 @@ static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *ba }
static void *opengl_handle; -static struct list gl_contexts = LIST_INIT( gl_contexts ); static struct list gl_drawables = LIST_INIT( gl_drawables );
pthread_mutex_t drawable_mutex; @@ -100,15 +95,19 @@ static struct gl_drawable *gl_drawable_grab( struct gl_drawable *gl ) return gl; }
-static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) +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 }; struct gl_drawable *gl;
if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, hwnd, hdc ))) return NULL; - gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); - gl->surface = 0; - gl->pbuffer = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); + + if (!window) gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); + else gl->window = grab_ioctl_window( window ); + + 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 ); @@ -135,7 +134,6 @@ static void android_drawable_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); if (gl->surface) funcs->p_eglDestroySurface( egl->display, gl->surface ); - if (gl->pbuffer) funcs->p_eglDestroySurface( egl->display, gl->pbuffer ); release_ioctl_window( gl->window ); }
@@ -159,44 +157,19 @@ void destroy_gl_drawable( HWND hwnd ) pthread_mutex_unlock( &drawable_mutex ); }
-static BOOL refresh_context( struct android_context *ctx ) -{ - BOOL ret = InterlockedExchange( &ctx->refresh, FALSE ); - - if (ret) - { - TRACE( "refreshing hwnd %p context %p surface %p\n", ctx->hwnd, ctx->context, ctx->surface ); - funcs->p_eglMakeCurrent( egl->display, ctx->surface, ctx->surface, ctx->context ); - NtUserRedrawWindow( ctx->hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); - } - return ret; -} - void update_gl_drawable( HWND hwnd ) { - struct gl_drawable *gl; - struct android_context *ctx; + struct gl_drawable *old, *new;
- if ((gl = get_gl_drawable( hwnd, 0 ))) + if (!(old = impl_from_opengl_drawable( get_window_opengl_drawable( hwnd ) ))) return; + if ((new = create_gl_drawable( hwnd, 0, old->base.format, old->window ))) { - if (!gl->surface && - (gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), - gl->window, NULL ))) - { - LIST_FOR_EACH_ENTRY( ctx, &gl_contexts, struct android_context, entry ) - { - if (ctx->hwnd != hwnd) continue; - TRACE( "hwnd %p refreshing %p %scurrent\n", hwnd, ctx, NtCurrentTeb()->glReserved2 == ctx ? "" : "not " ); - ctx->surface = gl->surface; - if (NtCurrentTeb()->glReserved2 == ctx) - funcs->p_eglMakeCurrent( egl->display, ctx->surface, ctx->surface, ctx->context ); - else - InterlockedExchange( &ctx->refresh, TRUE ); - } - } - release_gl_drawable( gl ); - NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); + set_window_opengl_drawable( hwnd, &new->base ); + release_gl_drawable( new ); } + release_gl_drawable( old ); + + NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); }
static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) @@ -222,7 +195,7 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg return TRUE; }
- if (!(gl = create_gl_drawable( hwnd, hdc, format ))) return FALSE; + if (!(gl = create_gl_drawable( hwnd, hdc, format, NULL ))) return FALSE; opengl_drawable_add_ref( (*drawable = &gl->base) ); release_gl_drawable( gl );
@@ -270,10 +243,8 @@ static BOOL android_context_create( int format, void *share, const int *attribs,
ctx->config = egl_config_for_format(format); ctx->surface = 0; - ctx->refresh = FALSE; 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 ); - list_add_head( &gl_contexts, &ctx->entry );
*private = ctx; return TRUE; @@ -284,7 +255,6 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv struct android_context *ctx = private; BOOL ret = FALSE; struct gl_drawable *draw_gl, *read_gl = NULL; - EGLSurface draw_surface, read_surface; HWND draw_hwnd;
TRACE( "%p %p %p\n", draw_hdc, read_hdc, ctx ); @@ -292,7 +262,6 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv if (!private) { funcs->p_eglMakeCurrent( egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); - NtCurrentTeb()->glReserved2 = NULL; return TRUE; }
@@ -300,17 +269,12 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv if ((draw_gl = get_gl_drawable( draw_hwnd, draw_hdc ))) { read_gl = get_gl_drawable( NtUserWindowFromDC( read_hdc ), read_hdc ); - draw_surface = draw_gl->surface ? draw_gl->surface : draw_gl->pbuffer; - read_surface = read_gl->surface ? read_gl->surface : read_gl->pbuffer; TRACE( "%p/%p context %p surface %p/%p\n", - draw_hdc, read_hdc, ctx->context, draw_surface, read_surface ); - ret = funcs->p_eglMakeCurrent( egl->display, draw_surface, read_surface, ctx->context ); + 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; - ctx->hwnd = draw_hwnd; - ctx->refresh = FALSE; - NtCurrentTeb()->glReserved2 = ctx; goto done; } } @@ -328,9 +292,6 @@ done: static BOOL android_context_destroy( void *private ) { struct android_context *ctx = private; - pthread_mutex_lock( &drawable_mutex ); - list_remove( &ctx->entry ); - pthread_mutex_unlock( &drawable_mutex ); funcs->p_eglDestroyContext( egl->display, ctx->context ); free( ctx ); return TRUE; @@ -365,9 +326,7 @@ static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interva
if (!ctx) return FALSE;
- TRACE( "%p hwnd %p context %p surface %p\n", hdc, ctx->hwnd, ctx->context, ctx->surface ); - - if (refresh_context( ctx )) return TRUE; + TRACE( "%p hwnd %p context %p surface %p\n", hdc, hwnd, ctx->context, ctx->surface );
if ((gl = get_gl_drawable( hwnd, hdc ))) { @@ -384,8 +343,7 @@ static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interv struct android_context *ctx = private; struct gl_drawable *gl;
- TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context ); - refresh_context( ctx ); + TRACE( "hwnd %p context %p\n", hwnd, ctx->context );
if ((gl = get_gl_drawable( hwnd, hdc ))) { diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 3cf775a4317..6b580fabf4c 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -153,6 +153,9 @@ W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_fu W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable );
+W32KAPI struct opengl_drawable *get_window_opengl_drawable( HWND hwnd ); +W32KAPI void set_window_opengl_drawable( HWND hwnd, struct opengl_drawable *drawable ); + /* interface between win32u and the user drivers */ struct opengl_driver_funcs {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/opengl.c | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-)
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 11f90ff8ac1..17eacc5eab2 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -111,7 +111,6 @@ static const GLubyte *(*pglGetString)(GLenum name); static PFN_glGetIntegerv pglGetIntegerv; static void (*pglReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); -static void (*pglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
struct color_mode { @@ -1591,16 +1590,6 @@ static void make_context_current(struct macdrv_context *context, BOOL read) }
-/********************************************************************** - * sync_context - */ -static void sync_context(struct macdrv_context *context) -{ - if (sync_context_rect(context)) - make_context_current(context, FALSE); -} - - /********************************************************************** * set_swap_interval */ @@ -2093,7 +2082,6 @@ static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interva struct macdrv_context *context = private;
set_swap_interval(context, interval); - sync_context(context);
if (skip_single_buffer_flushes) { @@ -2163,23 +2151,6 @@ static void macdrv_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, }
-/********************************************************************** - * macdrv_glViewport - * - * Hook into glViewport as an opportunity to update the OpenGL context - * if necessary. This is modeled after what Mesa GLX's Apple - * implementation does. - */ -static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) -{ - struct macdrv_context *context = NtCurrentTeb()->glReserved2; - - sync_context(context); - macdrv_update_opengl_context(context->context); - pglViewport(x, y, width, height); -} - - /*********************************************************************** * macdrv_wglBindTexImageARB * @@ -2836,7 +2807,6 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co LOAD_FUNCPTR(glGetIntegerv); LOAD_FUNCPTR(glGetString); LOAD_FUNCPTR(glReadPixels); - LOAD_FUNCPTR(glViewport); LOAD_FUNCPTR(glCopyColorTable);
if (!init_gl_info()) @@ -2990,7 +2960,6 @@ static void *macdrv_get_proc_address(const char *name) if (!strcmp(name, "glCopyPixels")) return macdrv_glCopyPixels; if (!strcmp(name, "glGetString")) return macdrv_glGetString; if (!strcmp(name, "glReadPixels")) return macdrv_glReadPixels; - if (!strcmp(name, "glViewport")) return macdrv_glViewport;
/* redirect some OpenGL extension functions */ if (!strcmp(name, "glCopyColorTable")) return macdrv_glCopyColorTable; @@ -3005,11 +2974,7 @@ static BOOL macdrv_swap_buffers(void *private, HWND hwnd, HDC hdc, 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); - sync_context(context); - } + if (context) set_swap_interval(context, interval);
if (hwnd) {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 49 +---------------------------------- 1 file changed, 1 insertion(+), 48 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 2bfd41a6358..304b0c530e8 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -72,7 +72,7 @@ struct wayland_context struct list entry; EGLConfig config; EGLContext context; - struct wayland_gl_drawable *draw, *read, *new_draw, *new_read; + struct wayland_gl_drawable *draw, *read; };
struct wgl_pbuffer @@ -208,18 +208,6 @@ err: return NULL; }
-static void update_context_drawables(struct wayland_gl_drawable *new, - struct wayland_gl_drawable *old) -{ - struct wayland_context *ctx; - - LIST_FOR_EACH_ENTRY(ctx, &gl_contexts, struct wayland_context, entry) - { - if (ctx->draw == old || ctx->new_draw == old) ctx->new_draw = new; - if (ctx->read == old || ctx->new_read == old) ctx->new_read = new; - } -} - static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *new) { struct wayland_gl_drawable *old; @@ -228,7 +216,6 @@ static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *ne
if ((old = find_drawable(hwnd, 0))) list_remove(&old->entry); if (new) list_add_head(&gl_drawables, &new->entry); - if (old && new) update_context_drawables(new, old);
pthread_mutex_unlock(&gl_object_mutex);
@@ -263,7 +250,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva if (!private) { funcs->p_eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - NtCurrentTeb()->glReserved2 = NULL; return TRUE; }
@@ -291,8 +277,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva old_read = ctx->read; ctx->draw = draw; ctx->read = read; - ctx->new_draw = ctx->new_read = NULL; - NtCurrentTeb()->glReserved2 = ctx; } else { @@ -308,35 +292,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva return ret; }
-static void wayland_context_refresh(struct wayland_context *ctx) -{ - BOOL refresh = FALSE; - struct wayland_gl_drawable *old_draw = NULL, *old_read = NULL; - - pthread_mutex_lock(&gl_object_mutex); - - if (ctx->new_draw) - { - old_draw = ctx->draw; - ctx->draw = wayland_gl_drawable_acquire(ctx->new_draw); - ctx->new_draw = NULL; - refresh = TRUE; - } - if (ctx->new_read) - { - old_read = ctx->read; - ctx->read = wayland_gl_drawable_acquire(ctx->new_read); - ctx->new_read = NULL; - refresh = TRUE; - } - if (refresh) funcs->p_eglMakeCurrent(egl->display, ctx->draw, ctx->read, ctx->context); - - pthread_mutex_unlock(&gl_object_mutex); - - if (old_draw) opengl_drawable_release(&old_draw->base); - if (old_read) opengl_drawable_release(&old_read->base); -} - static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { struct opengl_drawable *previous; @@ -479,7 +434,6 @@ static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interv
static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) { - struct wayland_context *ctx = private; HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct wayland_gl_drawable *gl;
@@ -492,7 +446,6 @@ static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval gl->swap_interval = interval; }
- if (ctx) wayland_context_refresh(ctx); ensure_window_surface_contents(toplevel); set_client_surface(hwnd, gl->client);
v2: Remove winex11/winewayland pixel format check which don't play well with the new logic [^1]. Update the wineandroid code to use the new win32u surface tracking to update the window surface when the native window is ready (though untested).
[^1]: New GL surface will be created each time a new pixel format is selected, and last surface presented will be set on screen if possible (or all surfaces are offscreen and blitted as needed if child window is involved). Unused surfaces will be destroyed once they aren't referenced anymore.