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 | 10 ++++--- dlls/winex11.drv/opengl.c | 35 ++++++++--------------- include/wine/opengl_driver.h | 2 +- 8 files changed, 108 insertions(+), 50 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..55b33051079 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 void *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..edb2df9d94d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -337,7 +337,7 @@ 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 wayland_gl_drawable *gl; RECT rect; @@ -346,14 +346,16 @@ static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, * 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 (*drawable) return (*drawable)->format == format;
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); + + opengl_drawable_add_ref( (*drawable = &gl->base) ); return TRUE; }
@@ -538,7 +540,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..1b0a2c3d1e1 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -908,18 +908,21 @@ 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 gl_drawable *gl, *prev; 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 (*drawable) return (*drawable)->format == format; + 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 +936,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 +944,12 @@ 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 );
+ opengl_drawable_add_ref( (*drawable = &gl->base) ); return TRUE; }
@@ -1719,7 +1708,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 55b33051079..c5583bc54ba 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -755,6 +755,23 @@ static void *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 c5583bc54ba..bd46a6af104 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 void *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/wineandroid.drv/opengl.c | 16 ---------------- 1 file changed, 16 deletions(-)
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index c570d82e2e4..b564f031f50 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -159,19 +159,6 @@ 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; @@ -367,8 +354,6 @@ static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interva
TRACE( "%p hwnd %p context %p surface %p\n", hdc, ctx->hwnd, ctx->context, ctx->surface );
- if (refresh_context( ctx )) return TRUE; - if ((gl = get_gl_drawable( hwnd, hdc ))) { set_swap_interval( gl, interval ); @@ -385,7 +370,6 @@ static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interv struct gl_drawable *gl;
TRACE( "hwnd %p context %p\n", ctx->hwnd, ctx->context ); - refresh_context( ctx );
if ((gl = get_gl_drawable( hwnd, hdc ))) {
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 | 47 +---------------------------------- 1 file changed, 1 insertion(+), 46 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index edb2df9d94d..d2a39e4b2f7 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);
@@ -291,7 +278,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 +294,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 wayland_gl_drawable *gl; @@ -481,7 +438,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;
@@ -494,7 +450,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);