From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7f0b3215ffd..37b93e1b5b0 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -827,9 +827,9 @@ static void x11drv_surface_destroy( struct opengl_drawable *base )
TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
- pglXDestroyWindow( gdi_display, gl->drawable ); - destroy_client_window( gl->base.hwnd, gl->window ); - XFreeColormap( gdi_display, gl->colormap ); + if (gl->drawable) pglXDestroyWindow( gdi_display, gl->drawable ); + if (gl->window) destroy_client_window( gl->base.hwnd, gl->window ); + if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); } @@ -907,7 +907,7 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl
if (!gl->drawable) { - free( gl ); + opengl_drawable_release( &gl->base ); return FALSE; }
@@ -1450,7 +1450,7 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); if (!gl->drawable) { - free( gl ); + opengl_drawable_release( &gl->base ); return FALSE; } pglXQueryDrawable( gdi_display, gl->drawable, GLX_WIDTH, (unsigned int *)width ); @@ -1477,7 +1477,7 @@ static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); pthread_mutex_unlock( &context_mutex );
- pglXDestroyPbuffer( gdi_display, gl->drawable ); + if (gl->drawable) pglXDestroyPbuffer( gdi_display, gl->drawable ); }
static void x11drv_pbuffer_flush( struct opengl_drawable *base, UINT flags )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 3 +++ dlls/win32u/opengl.c | 37 ++++++++++++++++++++++++++++++++++++ dlls/win32u/window.c | 2 ++ include/wine/opengl_driver.h | 1 + 4 files changed, 43 insertions(+)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index a3714cd8994..fc2d2947210 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -223,6 +223,9 @@ extern PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr; extern BOOL vulkan_init(void); extern void vulkan_detach_surfaces( struct list *surfaces );
+/* opengl.c */ +extern void detach_opengl_drawables( HWND hwnd ); + /* window.c */ HANDLE alloc_user_handle( void *ptr, unsigned short type ); void *free_user_handle( HANDLE handle, unsigned short type ); diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 7e0b2116111..b024937a2e0 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -163,6 +163,31 @@ static void register_extension( char *list, size_t size, const char *name ) } }
+static pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER; +static struct list drawables = LIST_INIT( drawables ); + +/* drawables_lock must be held */ +static void opengl_drawable_detach( struct opengl_drawable *drawable ) +{ + list_remove( &drawable->entry ); + list_init( &drawable->entry ); +} + +void detach_opengl_drawables( HWND hwnd ) +{ + struct opengl_drawable *drawable, *next; + + pthread_mutex_lock( &drawables_lock ); + + LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &drawables, struct opengl_drawable, entry ) + { + if (drawable->hwnd != hwnd) continue; + opengl_drawable_detach( drawable ); + } + + pthread_mutex_unlock( &drawables_lock ); +} + void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ) { struct opengl_drawable *drawable; @@ -176,6 +201,14 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun drawable->hwnd = hwnd; drawable->hdc = hdc;
+ if (!hwnd) list_init( &drawable->entry ); /* pbuffer, keep it unlinked */ + else + { + pthread_mutex_lock( &drawables_lock ); + list_add_tail( &drawables, &drawable->entry ); + pthread_mutex_unlock( &drawables_lock ); + } + TRACE( "created %s\n", debugstr_opengl_drawable( drawable ) ); return drawable; } @@ -193,6 +226,10 @@ void opengl_drawable_release( struct opengl_drawable *drawable )
if (!ref) { + pthread_mutex_lock( &drawables_lock ); + opengl_drawable_detach( drawable ); + pthread_mutex_unlock( &drawables_lock ); + drawable->funcs->destroy( drawable ); free( drawable ); } diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index a82462e44e4..f33b3c51e7f 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -5054,6 +5054,7 @@ LRESULT destroy_window( HWND hwnd ) window_surface_release( surface ); }
+ detach_opengl_drawables( hwnd ); vulkan_detach_surfaces( &vulkan_surfaces ); if (win->opengl_drawable) opengl_drawable_release( win->opengl_drawable ); user_driver->pDestroyWindow( hwnd ); @@ -5211,6 +5212,7 @@ void destroy_thread_windows(void) free_list = entry->next; TRACE( "destroying %p\n", entry );
+ detach_opengl_drawables( entry->handle ); user_driver->pDestroyWindow( entry->handle ); if (entry->opengl_drawable) opengl_drawable_release( entry->opengl_drawable );
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index c319d93ce27..fbd7b82e4e5 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -150,6 +150,7 @@ struct opengl_drawable int interval; /* last set surface swap interval */ HWND hwnd; /* window the drawable was created for */ HDC hdc; /* DC the drawable was created for */ + struct list entry; /* entry in win32u managed list */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 1 + dlls/wineandroid.drv/opengl.c | 6 ++++++ dlls/wineandroid.drv/window.c | 2 -- dlls/winemac.drv/opengl.c | 10 ++++++++++ dlls/winewayland.drv/opengl.c | 27 +++++++++++++++------------ dlls/winewayland.drv/waylanddrv.h | 1 - dlls/winewayland.drv/window.c | 1 - dlls/winex11.drv/opengl.c | 29 +++++++++++++++++------------ dlls/winex11.drv/window.c | 1 - dlls/winex11.drv/x11drv.h | 1 - include/wine/opengl_driver.h | 2 ++ 11 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index b024937a2e0..8198fd25487 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -169,6 +169,7 @@ static struct list drawables = LIST_INIT( drawables ); /* drawables_lock must be held */ static void opengl_drawable_detach( struct opengl_drawable *drawable ) { + drawable->funcs->detach( drawable ); list_remove( &drawable->entry ); list_init( &drawable->entry ); } diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 4637a04eec9..ff8f2a13027 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -108,6 +108,11 @@ static void android_drawable_destroy( struct opengl_drawable *base ) release_ioctl_window( gl->window ); }
+static void android_drawable_detach( struct opengl_drawable *base ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); +} + void update_gl_drawable( HWND hwnd ) { struct gl_drawable *old, *new; @@ -278,6 +283,7 @@ static struct opengl_driver_funcs android_driver_funcs = static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, + .detach = android_drawable_detach, .flush = android_drawable_flush, .swap = android_drawable_swap, }; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index c71778f32d4..d1017fd8764 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -984,8 +984,6 @@ void ANDROID_DestroyWindow( HWND hwnd ) struct android_win_data *data;
if (!(data = get_win_data( hwnd ))) return; - - destroy_gl_drawable( hwnd ); free_win_data( data ); }
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 9a28ec10b51..36cb0854acc 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2074,6 +2074,10 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, make_context_current(context, FALSE); }
+static void macdrv_surface_detach(struct opengl_drawable *base) +{ + TRACE("%s\n", debugstr_opengl_drawable(base)); +}
static void macdrv_surface_flush(struct opengl_drawable *base, UINT flags) { @@ -2374,6 +2378,10 @@ static void macdrv_pbuffer_destroy(struct opengl_drawable *base) CGLReleasePBuffer(gl->pbuffer); }
+static void macdrv_pbuffer_detach(struct opengl_drawable *base) +{ +} + static void macdrv_pbuffer_flush(struct opengl_drawable *base, UINT flags) { } @@ -3021,6 +3029,7 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = static const struct opengl_drawable_funcs macdrv_surface_funcs = { .destroy = macdrv_surface_destroy, + .detach = macdrv_surface_detach, .flush = macdrv_surface_flush, .swap = macdrv_surface_swap, }; @@ -3028,6 +3037,7 @@ static const struct opengl_drawable_funcs macdrv_surface_funcs = static const struct opengl_drawable_funcs macdrv_pbuffer_funcs = { .destroy = macdrv_pbuffer_destroy, + .detach = macdrv_pbuffer_detach, .flush = macdrv_pbuffer_flush, .swap = macdrv_pbuffer_swap, }; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index ede1b5982fa..9c239faa340 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -144,6 +144,20 @@ static void wayland_drawable_destroy(struct opengl_drawable *base) } }
+static void wayland_drawable_detach(struct opengl_drawable *base) +{ + struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base), *old; + HWND hwnd = base->hwnd; + + TRACE("%s\n", debugstr_opengl_drawable(base)); + + pthread_mutex_lock(&gl_object_mutex); + if ((old = find_drawable(hwnd, 0)) && old == gl) list_remove(&gl->entry); + pthread_mutex_unlock(&gl_object_mutex); + + if (gl) opengl_drawable_release(&gl->base); +} + static inline BOOL is_onscreen_format(int format) { return format > 0 && format <= egl->config_count; @@ -477,6 +491,7 @@ static struct opengl_driver_funcs wayland_driver_funcs = static const struct opengl_drawable_funcs wayland_drawable_funcs = { .destroy = wayland_drawable_destroy, + .detach = wayland_drawable_detach, .flush = wayland_drawable_flush, .swap = wayland_drawable_swap, }; @@ -505,14 +520,6 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c return STATUS_SUCCESS; }
-/********************************************************************** - * wayland_destroy_gl_drawable - */ -void wayland_destroy_gl_drawable(HWND hwnd) -{ - wayland_update_gl_drawable(hwnd, NULL); -} - /********************************************************************** * wayland_resize_gl_drawable */ @@ -534,10 +541,6 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c return STATUS_NOT_IMPLEMENTED; }
-void wayland_destroy_gl_drawable(HWND hwnd) -{ -} - void wayland_resize_gl_drawable(HWND hwnd) { } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index e0be6970b05..e31be8d294a 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -416,7 +416,6 @@ void wayland_data_device_init(void); * OpenGL */
-void wayland_destroy_gl_drawable(HWND hwnd); void wayland_resize_gl_drawable(HWND hwnd);
/********************************************************************** diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index dbcbd90be00..8077767a26f 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -403,7 +403,6 @@ void WAYLAND_DestroyWindow(HWND hwnd)
if (!(data = wayland_win_data_get(hwnd))) return; wayland_win_data_destroy(data); - wayland_destroy_gl_drawable(hwnd); }
/*********************************************************************** diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 37b93e1b5b0..d99a86a8f33 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -914,10 +914,10 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window );
pthread_mutex_lock( &context_mutex ); - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) - opengl_drawable_release( &prev->base ); + if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) prev = NULL; XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl ); pthread_mutex_unlock( &context_mutex ); + if (prev) opengl_drawable_release( &prev->base );
XFlush( gdi_display );
@@ -1020,20 +1020,19 @@ void sync_gl_drawable( HWND hwnd ) }
-/*********************************************************************** - * destroy_gl_drawable - */ -void destroy_gl_drawable( HWND hwnd ) +static void x11drv_surface_detach( struct opengl_drawable *base ) { - struct gl_drawable *gl; + struct gl_drawable *gl = impl_from_opengl_drawable( base ), *current; + HWND hwnd = base->hwnd; + + TRACE( "%s\n", debugstr_opengl_drawable( base ) );
pthread_mutex_lock( &context_mutex ); - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) - { - XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); - opengl_drawable_release( &gl->base ); - } + if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)¤t )) current = NULL; + else if (current == gl) XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); pthread_mutex_unlock( &context_mutex ); + + if (current == gl) opengl_drawable_release( ¤t->base ); }
@@ -1480,6 +1479,10 @@ static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) if (gl->drawable) pglXDestroyPbuffer( gdi_display, gl->drawable ); }
+static void x11drv_pbuffer_detach( struct opengl_drawable *base ) +{ +} + static void x11drv_pbuffer_flush( struct opengl_drawable *base, UINT flags ) { } @@ -1653,6 +1656,7 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = static const struct opengl_drawable_funcs x11drv_surface_funcs = { .destroy = x11drv_surface_destroy, + .detach = x11drv_surface_detach, .flush = x11drv_surface_flush, .swap = x11drv_surface_swap, }; @@ -1660,6 +1664,7 @@ static const struct opengl_drawable_funcs x11drv_surface_funcs = static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = { .destroy = x11drv_pbuffer_destroy, + .detach = x11drv_pbuffer_detach, .flush = x11drv_pbuffer_flush, .swap = x11drv_pbuffer_swap, }; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 726478ff040..e68d8d9d552 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2551,7 +2551,6 @@ void X11DRV_DestroyWindow( HWND hwnd ) XDeleteContext( gdi_display, (XID)hwnd, win_data_context ); release_win_data( data ); free( data ); - destroy_gl_drawable( hwnd ); }
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 421d394de20..47a413974f5 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -682,7 +682,6 @@ extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window get_dummy_parent(void);
extern void sync_gl_drawable( HWND hwnd ); -extern void destroy_gl_drawable( HWND hwnd );
extern BOOL window_is_reparenting( HWND hwnd ); extern BOOL window_should_take_focus( HWND hwnd, Time time ); diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index fbd7b82e4e5..6509daf3d0f 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -131,6 +131,8 @@ struct opengl_drawable; struct opengl_drawable_funcs { void (*destroy)( struct opengl_drawable *iface ); + /* detach the drawable from its window, called from window owner thread */ + void (*detach)( struct opengl_drawable *drawable ); /* 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 */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 1 + dlls/win32u/opengl.c | 76 ++++++++++++++++---------- dlls/win32u/window.c | 1 + dlls/wineandroid.drv/opengl.c | 6 ++ dlls/winemac.drv/macdrv.h | 1 - dlls/winemac.drv/opengl.c | 39 +++++-------- dlls/winemac.drv/window.c | 2 - dlls/winewayland.drv/opengl.c | 63 ++++----------------- dlls/winewayland.drv/wayland_surface.c | 2 - dlls/winewayland.drv/waylanddrv.h | 6 -- dlls/winex11.drv/opengl.c | 26 ++------- dlls/winex11.drv/window.c | 4 -- dlls/winex11.drv/x11drv.h | 2 - include/wine/opengl_driver.h | 4 ++ 14 files changed, 90 insertions(+), 143 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index fc2d2947210..f010ca4ac88 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -224,6 +224,7 @@ extern BOOL vulkan_init(void); extern void vulkan_detach_surfaces( struct list *surfaces );
/* opengl.c */ +extern void update_opengl_drawables( HWND hwnd ); extern void detach_opengl_drawables( HWND hwnd );
/* window.c */ diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 8198fd25487..107078f6108 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -189,6 +189,22 @@ void detach_opengl_drawables( HWND hwnd ) pthread_mutex_unlock( &drawables_lock ); }
+void update_opengl_drawables( HWND hwnd ) +{ + struct opengl_drawable *drawable, *next; + + pthread_mutex_lock( &drawables_lock ); + + LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &drawables, struct opengl_drawable, entry ) + { + if (drawable->hwnd != hwnd) continue; + drawable->funcs->update( drawable ); + InterlockedExchange( &drawable->updated, 1 ); + } + + pthread_mutex_unlock( &drawables_lock ); +} + void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ) { struct opengl_drawable *drawable; @@ -236,6 +252,18 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) } }
+static void opengl_drawable_flush( struct opengl_drawable *drawable, int interval, UINT flags ) +{ + if (InterlockedCompareExchange( &drawable->updated, 0, 1 )) flags |= GL_FLUSH_UPDATED; + if (interval != drawable->interval) + { + drawable->interval = interval; + flags = GL_FLUSH_INTERVAL; + } + + if (flags) drawable->funcs->flush( drawable, flags ); +} + #ifdef SONAME_LIBEGL
static void *egldrv_get_proc_address( const char *name ) @@ -1003,16 +1031,21 @@ 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_make_current( new_draw, new_read, private )) + else { - 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 ); - - /* 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; + if (new_draw) opengl_drawable_flush( new_draw, new_draw->interval, 0 ); + if (new_read) opengl_drawable_flush( new_read, new_read->interval, 0 ); + + if ((ret = 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 ); + 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 ); + } }
if (new_draw) opengl_drawable_release( new_draw ); @@ -1518,17 +1551,11 @@ 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, FALSE ))) return FALSE; - 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 ); + if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; + opengl_drawable_flush( draw, interval, flags ); opengl_drawable_release( draw );
return TRUE; @@ -1540,7 +1567,6 @@ 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; @@ -1552,18 +1578,8 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) if (flush_memory_dc( context, hdc, FALSE, funcs->p_glFlush )) return TRUE;
if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; - 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_flush( draw, interval, 0 ); + ret = draw->funcs->swap( draw ); opengl_drawable_release( draw );
return ret; diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index f33b3c51e7f..673d375321e 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2136,6 +2136,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru
user_driver->pWindowPosChanged( hwnd, insert_after, owner_hint, swp_flags, is_fullscreen, &monitor_rects, get_driver_window_surface( new_surface, raw_dpi ) ); + update_opengl_drawables( hwnd );
update_children_window_state( hwnd ); } diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index ff8f2a13027..d41ff76e320 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -113,6 +113,11 @@ static void android_drawable_detach( struct opengl_drawable *base ) TRACE( "%s\n", debugstr_opengl_drawable( base ) ); }
+static void android_drawable_update( struct opengl_drawable *base ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); +} + void update_gl_drawable( HWND hwnd ) { struct gl_drawable *old, *new; @@ -284,6 +289,7 @@ static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, .detach = android_drawable_detach, + .update = android_drawable_update, .flush = android_drawable_flush, .swap = android_drawable_swap, }; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index b658c8f7939..9c76fe78c38 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -241,7 +241,6 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p
extern UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs); extern UINT macdrv_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); -extern void sync_gl_view(struct macdrv_win_data* data, const struct window_rects *old_rects);
extern CGImageRef create_cgimage_from_icon_bitmaps(HDC hdc, HANDLE icon, HBITMAP hbmColor, unsigned char *color_bits, int color_size, HBITMAP hbmMask, diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 36cb0854acc..dd3b3e4da59 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1514,6 +1514,20 @@ static void mark_contexts_for_moved_view(macdrv_view view) pthread_mutex_unlock(&context_mutex); }
+static void macdrv_surface_update(struct opengl_drawable *base) +{ + struct macdrv_win_data *data = get_win_data(base->hwnd); + + TRACE("%s\n", debugstr_opengl_drawable(base)); + + if (data->client_cocoa_view && data->pixel_format) + { + TRACE("GL view %p changed position; marking contexts\n", data->client_cocoa_view); + mark_contexts_for_moved_view(data->client_cocoa_view); + } + + release_win_data(data); +}
/********************************************************************** * sync_context_rect @@ -2817,30 +2831,6 @@ failed: return STATUS_NOT_SUPPORTED; }
- -/*********************************************************************** - * sync_gl_view - * - * Synchronize the Mac GL view position with the Windows child window - * position. - */ -void sync_gl_view(struct macdrv_win_data* data, const struct window_rects *old_rects) -{ - if (data->client_cocoa_view && data->pixel_format) - { - RECT old = old_rects->client, new = data->rects.client; - - OffsetRect(&old, -old_rects->visible.left, -old_rects->visible.top); - OffsetRect(&new, -data->rects.visible.left, -data->rects.visible.top); - if (!EqualRect(&old, &new)) - { - TRACE("GL view %p changed position; marking contexts\n", data->client_cocoa_view); - mark_contexts_for_moved_view(data->client_cocoa_view); - } - } -} - - static BOOL macdrv_describe_pixel_format(int format, struct wgl_pixel_format *descr) { const pixel_format *pf = pixel_formats + format - 1; @@ -3030,6 +3020,7 @@ static const struct opengl_drawable_funcs macdrv_surface_funcs = { .destroy = macdrv_surface_destroy, .detach = macdrv_surface_detach, + .update = macdrv_surface_update, .flush = macdrv_surface_flush, .swap = macdrv_surface_swap, }; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 940fdffa800..c9a4fcd5060 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1736,8 +1736,6 @@ void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT TRACE("win %p/%p new_rects %s style %08x flags %08x surface %p\n", hwnd, data->cocoa_window, debugstr_window_rects(new_rects), new_style, swp_flags, surface);
- sync_gl_view(data, &old_rects); - if (!data->cocoa_window && !data->cocoa_view) goto done;
if (data->on_screen) diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9c239faa340..d7eb99dde13 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -57,7 +57,6 @@ struct wayland_gl_drawable struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; - LONG resized; BOOL double_buffered; };
@@ -102,24 +101,6 @@ static struct wayland_gl_drawable *find_drawable(HWND hwnd, HDC hdc) return NULL; }
-static struct wayland_gl_drawable *wayland_gl_drawable_acquire(struct wayland_gl_drawable *gl) -{ - opengl_drawable_add_ref(&gl->base); - return gl; -} - -static struct wayland_gl_drawable *wayland_gl_drawable_get(HWND hwnd, HDC hdc) -{ - struct wayland_gl_drawable *ret; - - pthread_mutex_lock(&gl_object_mutex); - if ((ret = find_drawable(hwnd, hdc))) - ret = wayland_gl_drawable_acquire(ret); - pthread_mutex_unlock(&gl_object_mutex); - - return ret; -} - static void wayland_drawable_destroy(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base); @@ -158,6 +139,11 @@ static void wayland_drawable_detach(struct opengl_drawable *base) if (gl) opengl_drawable_release(&gl->base); }
+static void wayland_drawable_update(struct opengl_drawable *base) +{ + TRACE("%s\n", debugstr_opengl_drawable(base)); +} + static inline BOOL is_onscreen_format(int format) { return format > 0 && format <= egl->config_count; @@ -239,15 +225,12 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) int client_width, client_height; RECT client_rect = {0};
- if (InterlockedCompareExchange(&gl->resized, FALSE, TRUE)) - { - NtUserGetClientRect(gl->base.hwnd, &client_rect, NtUserGetDpiForWindow(gl->base.hwnd)); - client_width = client_rect.right - client_rect.left; - client_height = client_rect.bottom - client_rect.top; - if (client_width == 0 || client_height == 0) client_width = client_height = 1; + NtUserGetClientRect(gl->base.hwnd, &client_rect, NtUserGetDpiForWindow(gl->base.hwnd)); + client_width = client_rect.right - client_rect.left; + client_height = client_rect.bottom - client_rect.top; + if (client_width == 0 || client_height == 0) client_width = client_height = 1;
- wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); - } + wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); }
static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private) @@ -265,10 +248,6 @@ static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct openg return TRUE; }
- /* 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); - pthread_mutex_lock(&gl_object_mutex);
ret = funcs->p_eglMakeCurrent(egl->display, @@ -428,7 +407,7 @@ static void wayland_drawable_flush(struct opengl_drawable *base, UINT flags)
/* 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 (flags & GL_FLUSH_UPDATED) wayland_gl_drawable_sync_size(gl); }
static BOOL wayland_drawable_swap(struct opengl_drawable *base) @@ -442,7 +421,6 @@ static BOOL wayland_drawable_swap(struct opengl_drawable *base) /* Although all the EGL surfaces we create are double-buffered, we want to * use some as single-buffered, so avoid swapping those. */ if (gl->double_buffered) funcs->p_eglSwapBuffers(egl->display, gl->surface); - wayland_gl_drawable_sync_size(gl);
return TRUE; } @@ -492,6 +470,7 @@ static const struct opengl_drawable_funcs wayland_drawable_funcs = { .destroy = wayland_drawable_destroy, .detach = wayland_drawable_detach, + .update = wayland_drawable_update, .flush = wayland_drawable_flush, .swap = wayland_drawable_swap, }; @@ -520,20 +499,6 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c return STATUS_SUCCESS; }
-/********************************************************************** - * wayland_resize_gl_drawable - */ -void wayland_resize_gl_drawable(HWND hwnd) -{ - struct wayland_gl_drawable *gl; - - if (!(gl = wayland_gl_drawable_get(hwnd, 0))) return; - /* wl_egl_window_resize is not thread safe, so we just mark the - * drawable as resized and perform the resize in the proper thread. */ - InterlockedExchange(&gl->resized, TRUE); - opengl_drawable_release(&gl->base); -} - #else /* No GL */
UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs) @@ -541,8 +506,4 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c return STATUS_NOT_IMPLEMENTED; }
-void wayland_resize_gl_drawable(HWND hwnd) -{ -} - #endif diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index d0385f03a4e..15a5786ec69 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -608,8 +608,6 @@ static void wayland_surface_reconfigure_client(struct wayland_surface *surface, wp_viewport_set_destination(client->wp_viewport, width, height); else /* We can't have a 0x0 destination, use 1x1 instead. */ wp_viewport_set_destination(client->wp_viewport, 1, 1); - - wayland_resize_gl_drawable(client->hwnd); }
/********************************************************************** diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index e31be8d294a..73b76483070 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -412,12 +412,6 @@ void wayland_text_input_deinit(void);
void wayland_data_device_init(void);
-/********************************************************************** - * OpenGL - */ - -void wayland_resize_gl_drawable(HWND hwnd); - /********************************************************************** * Helpers */ diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index d99a86a8f33..72a9660bdf2 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -994,29 +994,12 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) } }
-/*********************************************************************** - * sync_gl_drawable - */ -void sync_gl_drawable( HWND hwnd ) +static void x11drv_surface_update( struct opengl_drawable *base ) { - struct x11drv_context *context; - struct gl_drawable *gl; + struct gl_drawable *gl = impl_from_opengl_drawable( base );
- pthread_mutex_lock( &context_mutex ); - LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) - { - if ((gl = context->draw) && gl->base.funcs == &x11drv_surface_funcs && gl->base.hwnd == hwnd) - { - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); - } - if ((gl = context->read) && gl->base.funcs == &x11drv_surface_funcs && gl->base.hwnd == hwnd) - { - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); - } - } - pthread_mutex_unlock( &context_mutex ); + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); }
@@ -1657,6 +1640,7 @@ static const struct opengl_drawable_funcs x11drv_surface_funcs = { .destroy = x11drv_surface_destroy, .detach = x11drv_surface_detach, + .update = x11drv_surface_update, .flush = x11drv_surface_flush, .swap = x11drv_surface_swap, }; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index e68d8d9d552..f0db2c32e74 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2759,7 +2759,6 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const struct w if (parent != NtUserGetDesktopWindow() && !NtUserGetAncestor( parent, GA_PARENT )) return NULL;
if (NtUserGetWindowThread( hwnd, NULL ) != GetCurrentThreadId()) return NULL; - sync_gl_drawable( parent );
display = thread_init_display(); init_clip_window(); /* make sure the clip window is initialized in this thread */ @@ -3075,7 +3074,6 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) } done: release_win_data( data ); - sync_gl_drawable( parent );
fetch_icon_data( hwnd, 0, 0 ); } @@ -3163,8 +3161,6 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN struct window_rects old_rects; BOOL was_fullscreen, activate = !(swp_flags & SWP_NOACTIVATE);
- sync_gl_drawable( hwnd ); - if (!(data = get_win_data( hwnd ))) return; if (is_window_managed( hwnd, swp_flags, fullscreen )) window_set_managed( data, TRUE );
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 47a413974f5..e61ced9a25e 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -681,8 +681,6 @@ extern void set_window_parent( struct x11drv_win_data *data, Window parent ); extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window get_dummy_parent(void);
-extern void sync_gl_drawable( HWND hwnd ); - extern BOOL window_is_reparenting( HWND hwnd ); extern BOOL window_should_take_focus( HWND hwnd, Time time ); extern BOOL window_has_pending_wm_state( HWND hwnd, UINT state ); diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 6509daf3d0f..55d862c9dfe 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -133,6 +133,8 @@ struct opengl_drawable_funcs void (*destroy)( struct opengl_drawable *iface ); /* detach the drawable from its window, called from window owner thread */ void (*detach)( struct opengl_drawable *drawable ); + /* update the drawable to match its window state, called from window owner thread */ + void (*update)( struct opengl_drawable *drawable ); /* 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 */ @@ -142,6 +144,7 @@ struct opengl_drawable_funcs /* flags for opengl_drawable flush */ #define GL_FLUSH_FINISHED 0x01 #define GL_FLUSH_INTERVAL 0x02 +#define GL_FLUSH_UPDATED 0x04
struct opengl_drawable { @@ -153,6 +156,7 @@ struct opengl_drawable HWND hwnd; /* window the drawable was created for */ HDC hdc; /* DC the drawable was created for */ struct list entry; /* entry in win32u managed list */ + LONG updated; /* has been moved / resized / reparented */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 673d375321e..174e48a67cc 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -411,7 +411,7 @@ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent ) RECT window_rect = {0}, old_screen_rect = {0}, new_screen_rect = {0}; UINT context; WINDOWPOS winpos; - HWND full_handle; + HWND full_handle, new_toplevel, old_toplevel; HWND old_parent = 0; BOOL was_visible; WND *win; @@ -481,6 +481,14 @@ HWND WINAPI NtUserSetParent( HWND hwnd, HWND parent )
user_driver->pSetParent( full_handle, parent, old_parent );
+ new_toplevel = NtUserGetAncestor( parent, GA_ROOT ); + old_toplevel = NtUserGetAncestor( old_parent, GA_ROOT ); + if (new_toplevel != old_toplevel) + { + if (new_toplevel) update_window_state( new_toplevel ); + if (old_toplevel) update_window_state( old_toplevel ); + } + winpos.hwnd = hwnd; winpos.hwndInsertAfter = HWND_TOP; winpos.x = window_rect.left; @@ -4999,7 +5007,7 @@ LRESULT destroy_window( HWND hwnd ) struct window_surface *surface; HMENU menu = 0, sys_menu; WND *win; - HWND *children; + HWND *children, toplevel = NtUserGetAncestor( hwnd, GA_ROOT );
TRACE( "%p\n", hwnd );
@@ -5031,6 +5039,8 @@ LRESULT destroy_window( HWND hwnd )
send_message( hwnd, WM_NCDESTROY, 0, 0 );
+ if (toplevel && toplevel != hwnd) update_window_state( toplevel ); + /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
/* free resources associated with the window */ @@ -5412,7 +5422,7 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name, struct window_surface *surface; struct window_rects new_rects; CBT_CREATEWNDW cbtc; - HWND hwnd, owner = 0; + HWND hwnd, toplevel, owner = 0; CREATESTRUCTW cs; INT sw = SW_SHOW; RECT surface_rect; @@ -5703,6 +5713,10 @@ HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
TRACE( "created window %p\n", hwnd ); set_thread_dpi_awareness_context( context ); + + toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); + if (toplevel && toplevel != hwnd) update_window_state( toplevel ); + return hwnd;
failed:
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 107 +--------------------------------- 1 file changed, 2 insertions(+), 105 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index d7eb99dde13..f27d35c67a8 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -46,14 +46,9 @@ static const struct egl_platform *egl; static const struct opengl_funcs *funcs; static const struct opengl_drawable_funcs wayland_drawable_funcs;
-static pthread_mutex_t gl_object_mutex = PTHREAD_MUTEX_INITIALIZER; -static struct list gl_drawables = LIST_INIT(gl_drawables); -static struct list gl_contexts = LIST_INIT(gl_contexts); - struct wayland_gl_drawable { struct opengl_drawable base; - struct list entry; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; @@ -67,50 +62,14 @@ static struct wayland_gl_drawable *impl_from_opengl_drawable(struct opengl_drawa
struct wayland_context { - struct list entry; EGLConfig config; EGLContext context; - struct wayland_gl_drawable *draw, *read; -}; - -struct wgl_pbuffer -{ - struct list entry; - struct wayland_gl_drawable *gl; - int width, height, pixel_format; - int texture_format, texture_target, texture_binding; - EGLContext tmp_context, prev_context; };
-struct wayland_pbuffer_dc -{ - struct list entry; - HDC hdc; - struct wayland_gl_drawable *gl; -}; - -/* lookup the existing drawable for a window, gl_object_mutex must be held */ -static struct wayland_gl_drawable *find_drawable(HWND hwnd, HDC hdc) -{ - struct wayland_gl_drawable *gl; - LIST_FOR_EACH_ENTRY(gl, &gl_drawables, struct wayland_gl_drawable, entry) - { - if (hwnd && gl->base.hwnd == hwnd) return gl; - if (hdc && gl->base.hdc == hdc) return gl; - } - return NULL; -} - static void wayland_drawable_destroy(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- if (!gl->base.hwnd) - { - pthread_mutex_lock(&gl_object_mutex); - list_remove(&gl->entry); - pthread_mutex_unlock(&gl_object_mutex); - } if (gl->surface) funcs->p_eglDestroySurface(egl->display, gl->surface); if (gl->wl_egl_window) wl_egl_window_destroy(gl->wl_egl_window); if (gl->client) @@ -127,16 +86,7 @@ static void wayland_drawable_destroy(struct opengl_drawable *base)
static void wayland_drawable_detach(struct opengl_drawable *base) { - struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base), *old; - HWND hwnd = base->hwnd; - TRACE("%s\n", debugstr_opengl_drawable(base)); - - pthread_mutex_lock(&gl_object_mutex); - if ((old = find_drawable(hwnd, 0)) && old == gl) list_remove(&gl->entry); - pthread_mutex_unlock(&gl_object_mutex); - - if (gl) opengl_drawable_release(&gl->base); }
static void wayland_drawable_update(struct opengl_drawable *base) @@ -206,20 +156,6 @@ err: return NULL; }
-static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *new) -{ - struct wayland_gl_drawable *old; - - pthread_mutex_lock(&gl_object_mutex); - - if ((old = find_drawable(hwnd, 0))) list_remove(&old->entry); - if (new) list_add_head(&gl_drawables, &new->entry); - - pthread_mutex_unlock(&gl_object_mutex); - - if (old) opengl_drawable_release(&old->base); -} - static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) { int client_width, client_height; @@ -236,9 +172,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) 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 *old_draw = NULL, *old_read = NULL;
TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), private);
@@ -248,26 +182,7 @@ static BOOL wayland_make_current(struct opengl_drawable *draw_base, struct openg return TRUE; }
- pthread_mutex_lock(&gl_object_mutex); - - ret = funcs->p_eglMakeCurrent(egl->display, - draw ? draw->surface : EGL_NO_SURFACE, - read ? read->surface : EGL_NO_SURFACE, - ctx->context); - if (ret) - { - 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(&gl_object_mutex); - - if (old_draw) opengl_drawable_release(&old_draw->base); - if (old_read) opengl_drawable_release(&old_read->base); - - return ret; + return funcs->p_eglMakeCurrent(egl->display, draw->surface, read->surface, ctx->context); }
static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) @@ -283,10 +198,8 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct if (rect.bottom == rect.top) rect.bottom = rect.top + 1;
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) ); + *drawable = &gl->base; return TRUE; }
@@ -365,11 +278,6 @@ static BOOL wayland_context_create(int format, void *share_private, const int *a ctx->context = funcs->p_eglCreateContext(egl->display, EGL_NO_CONFIG_KHR, share ? share->context : EGL_NO_CONTEXT, attribs ? egl_attribs : NULL); - - pthread_mutex_lock(&gl_object_mutex); - list_add_head(&gl_contexts, &ctx->entry); - pthread_mutex_unlock(&gl_object_mutex); - TRACE("ctx=%p egl_context=%p\n", ctx, ctx->context);
*private = ctx; @@ -379,13 +287,7 @@ static BOOL wayland_context_create(int format, void *share_private, const int *a static BOOL wayland_context_destroy(void *private) { struct wayland_context *ctx = private; - - pthread_mutex_lock(&gl_object_mutex); - list_remove(&ctx->entry); - pthread_mutex_unlock(&gl_object_mutex); funcs->p_eglDestroyContext(egl->display, ctx->context); - if (ctx->draw) opengl_drawable_release(&ctx->draw->base); - if (ctx->read) opengl_drawable_release(&ctx->read->base); free(ctx); return TRUE; } @@ -435,11 +337,6 @@ static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum tex
/* Use an unmapped wayland surface as our offscreen "pbuffer" surface. */ if (!(drawable = wayland_gl_drawable_create(0, hdc, format, *width, *height))) return FALSE; - - pthread_mutex_lock(&gl_object_mutex); - list_add_head(&gl_drawables, &drawable->entry); - pthread_mutex_unlock(&gl_object_mutex); - *surface = &drawable->base; return TRUE; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 78 +++------------------------------------ 1 file changed, 6 insertions(+), 72 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 72a9660bdf2..2a5d6599007 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,9 +197,6 @@ struct glx_pixel_format struct x11drv_context { GLXContext ctx; - struct gl_drawable *draw; - struct gl_drawable *read; - struct list entry; };
struct gl_drawable @@ -228,12 +225,6 @@ enum glx_swap_control_method GLX_SWAP_CONTROL_MESA };
-/* X context to associate a struct gl_drawable to an hwnd */ -static XContext gl_hwnd_context; -/* X context to associate a struct gl_drawable to a pbuffer hdc */ -static XContext gl_pbuffer_context; - -static struct list context_list = LIST_INIT( context_list ); static struct glx_pixel_format *pixel_formats; static int nb_pixel_formats, nb_onscreen_formats;
@@ -243,8 +234,6 @@ static enum glx_swap_control_method swap_control_method = GLX_SWAP_CONTROL_NONE; static BOOL has_swap_control_tear = FALSE; static BOOL has_swap_method = FALSE;
-static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER; - static const BOOL is_win64 = sizeof(void *) > sizeof(int);
static BOOL glxRequireVersion(int requiredVersion); @@ -585,8 +574,6 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c ERR( "GLX extension is missing, disabling OpenGL.\n" ); goto failed; } - gl_hwnd_context = XUniqueContext(); - gl_pbuffer_context = XUniqueContext();
/* In case of GLX you have direct and indirect rendering. Most of the time direct rendering is used * as in general only that is hardware accelerated. In some cases like in case of remote X indirect @@ -889,7 +876,7 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); struct opengl_drawable *previous; - struct gl_drawable *gl, *prev; + struct gl_drawable *gl; RECT rect;
if ((previous = *drawable) && previous->format == format) return TRUE; @@ -912,17 +899,10 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl }
TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); - - pthread_mutex_lock( &context_mutex ); - if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) prev = NULL; - XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)gl ); - pthread_mutex_unlock( &context_mutex ); - if (prev) opengl_drawable_release( &prev->base ); - XFlush( gdi_display );
if (previous) opengl_drawable_release( previous ); - opengl_drawable_add_ref( (*drawable = &gl->base) ); + *drawable = &gl->base; return TRUE; }
@@ -1005,17 +985,7 @@ static void x11drv_surface_update( struct opengl_drawable *base )
static void x11drv_surface_detach( struct opengl_drawable *base ) { - struct gl_drawable *gl = impl_from_opengl_drawable( base ), *current; - HWND hwnd = base->hwnd; - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); - - pthread_mutex_lock( &context_mutex ); - if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)¤t )) current = NULL; - else if (current == gl) XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); - pthread_mutex_unlock( &context_mutex ); - - if (current == gl) opengl_drawable_release( ¤t->base ); }
@@ -1215,13 +1185,7 @@ static BOOL x11drv_context_destroy(void *private)
TRACE("(%p)\n", ctx);
- pthread_mutex_lock( &context_mutex ); - list_remove( &ctx->entry ); - pthread_mutex_unlock( &context_mutex ); - if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); - if (ctx->draw) opengl_drawable_release( &ctx->draw->base ); - if (ctx->read) opengl_drawable_release( &ctx->read->base ); free( ctx ); return TRUE; } @@ -1235,9 +1199,9 @@ static void *x11drv_get_proc_address( const char *name )
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 gl_drawable *draw = impl_from_opengl_drawable( draw_base ), *read = impl_from_opengl_drawable( read_base ); struct x11drv_context *ctx = private; - BOOL ret = FALSE; + BOOL ret;
TRACE( "draw %s, read %s, context %p\n", debugstr_opengl_drawable( draw_base ), debugstr_opengl_drawable( read_base ), private );
@@ -1250,20 +1214,8 @@ static BOOL x11drv_make_current( struct opengl_drawable *draw_base, struct openg
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 ); - 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; + return ret; }
static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) @@ -1309,12 +1261,7 @@ static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags )
TRACE( "%s flags %#x\n", debugstr_opengl_drawable( base ), flags );
- if (flags & GL_FLUSH_INTERVAL) - { - pthread_mutex_lock( &context_mutex ); - set_swap_interval( gl, base->interval ); - pthread_mutex_unlock( &context_mutex ); - } + if (flags & GL_FLUSH_INTERVAL) set_swap_interval( gl, base->interval );
update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); @@ -1393,10 +1340,6 @@ static BOOL x11drv_context_create( int format, void *share_private, const int *a free( ret ); return FALSE; } - - pthread_mutex_lock( &context_mutex ); - list_add_head( &context_list, &ret->entry ); - pthread_mutex_unlock( &context_mutex ); }
TRACE( "-> %p\n", ret ); @@ -1440,10 +1383,6 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex SetRect( &rect, 0, 0, *width, *height ); set_dc_drawable( hdc, gl->drawable, &rect, IncludeInferiors );
- pthread_mutex_lock( &context_mutex ); - XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl ); - pthread_mutex_unlock( &context_mutex ); - *drawable = &gl->base; return TRUE; } @@ -1451,14 +1390,9 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); - HDC hdc = gl->base.hdc;
TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
- pthread_mutex_lock( &context_mutex ); - XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); - pthread_mutex_unlock( &context_mutex ); - if (gl->drawable) pglXDestroyPbuffer( gdi_display, gl->drawable ); }