From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 1 + dlls/opengl32/unix_private.h | 1 + dlls/opengl32/unix_thunks.c | 3 +-- dlls/opengl32/unix_wgl.c | 7 +++++++ 4 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index d43ee4abf3e..17e44ec824a 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -197,6 +197,7 @@ my %manual_win_thunks = ); my %manual_unix_thunks = ( + "glClear" => 1, "glDebugMessageCallback" => 1, "glDebugMessageCallbackAMD" => 1, "glDebugMessageCallbackARB" => 1, diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index c15bda2c99a..e51ae08161c 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -82,6 +82,7 @@ extern PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR lpszProc ); extern BOOL wrap_wglMakeCurrent( TEB *teb, HDC hDc, HGLRC newContext ); extern void wrap_glFinish( TEB *teb ); extern void wrap_glFlush( TEB *teb ); +extern void wrap_glClear( TEB *teb, GLbitfield mask ); extern void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ); extern void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ); extern void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height ); diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 91aaadbe9c0..a3c0c5aa817 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -196,8 +196,7 @@ static NTSTATUS gl_glCallLists( void *args ) static NTSTATUS gl_glClear( void *args ) { struct glClear_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glClear( params->mask ); + wrap_glClear( params->teb, params->mask ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index d203f4781a7..7f3fb1f9927 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1010,6 +1010,13 @@ void wrap_glFlush( TEB *teb ) flush_context( teb, funcs->p_glFlush ); }
+void wrap_glClear( TEB *teb, GLbitfield mask ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, NULL ); + funcs->p_glClear( mask ); +} + void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ) { const struct opengl_funcs *funcs = teb->glTable;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 43 ++++++++--------------------------- 1 file changed, 10 insertions(+), 33 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9163f18058b..34b9487d6b6 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -34,7 +34,7 @@ #include "waylanddrv.h" #include "wine/debug.h"
-#if defined(SONAME_LIBEGL) && defined(HAVE_LIBWAYLAND_EGL) +#ifdef HAVE_LIBWAYLAND_EGL
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
@@ -46,10 +46,6 @@ static const struct egl_platform *egl; static const struct opengl_funcs *funcs; static const struct opengl_drawable_funcs wayland_drawable_funcs;
-#define DECL_FUNCPTR(f) static PFN_##f p_##f -DECL_FUNCPTR(glClear); -#undef DECL_FUNCPTR - 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); @@ -447,15 +443,6 @@ static BOOL wayland_context_create(int format, void *share_private, const int *a return TRUE; }
-void wayland_glClear(GLbitfield mask) -{ - struct wayland_context *ctx = NtCurrentTeb()->glReserved2; - /* Since glClear is one of the operations that may latch the native size, - * perform any pending resizes before calling it. */ - if (ctx && ctx->draw) wayland_gl_drawable_sync_size(ctx->draw); - p_glClear(mask); -} - static BOOL wayland_context_destroy(void *private) { struct wayland_context *ctx = private; @@ -477,16 +464,17 @@ static EGLenum wayland_init_egl_platform(const struct egl_platform *platform, EG return EGL_PLATFORM_WAYLAND_KHR; }
-static void *wayland_get_proc_address(const char *name) +static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { - if (!strcmp(name, "glClear")) return wayland_glClear; + struct wayland_context *ctx = private;
- return funcs->p_eglGetProcAddress(name); -} + /* Since context_flush is called from operations that may latch the native size, + * perform any pending resizes before calling them. */ + if (ctx->draw) wayland_gl_drawable_sync_size(ctx->draw);
-static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) -{ - return FALSE; + if (flush) flush(); + + return TRUE; }
static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval) @@ -560,16 +548,9 @@ static UINT wayland_pbuffer_bind(HDC hdc, struct opengl_drawable *base, GLenum b return -1; /* use default implementation */ }
-static BOOL init_opengl_funcs(void) -{ - p_glClear = (void *)funcs->p_eglGetProcAddress("glClear"); - return TRUE; -} - static struct opengl_driver_funcs wayland_driver_funcs = { .p_init_egl_platform = wayland_init_egl_platform, - .p_get_proc_address = wayland_get_proc_address, .p_set_pixel_format = wayland_set_pixel_format, .p_swap_buffers = wayland_swap_buffers, .p_context_create = wayland_context_create, @@ -602,17 +583,13 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c if (!opengl_funcs->egl_handle) return STATUS_NOT_SUPPORTED; funcs = opengl_funcs;
- if (!init_opengl_funcs()) goto err; - + wayland_driver_funcs.p_get_proc_address = (*driver_funcs)->p_get_proc_address; wayland_driver_funcs.p_init_pixel_formats = (*driver_funcs)->p_init_pixel_formats; wayland_driver_funcs.p_describe_pixel_format = (*driver_funcs)->p_describe_pixel_format; wayland_driver_funcs.p_init_wgl_extensions = (*driver_funcs)->p_init_wgl_extensions;
*driver_funcs = &wayland_driver_funcs; return STATUS_SUCCESS; - -err: - return STATUS_NOT_SUPPORTED; }
/**********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 45 +++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 26 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index f7d2b484445..499e906b948 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -202,17 +202,9 @@ struct x11drv_context struct list entry; };
-enum dc_gl_type -{ - DC_GL_NONE, /* no GL support (pixel format not set yet) */ - DC_GL_WINDOW, /* normal top-level window */ - DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */ -}; - struct gl_drawable { struct opengl_drawable base; - enum dc_gl_type type; /* type of GL surface */ RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ Window window; /* window if drawable is a GLXWindow */ @@ -350,7 +342,8 @@ static const GLubyte *(*pglGetString)(GLenum name); static void *opengl_handle; static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs x11drv_driver_funcs; -static const struct opengl_drawable_funcs x11drv_drawable_funcs; +static const struct opengl_drawable_funcs x11drv_surface_funcs; +static const struct opengl_drawable_funcs x11drv_pbuffer_funcs;
/* check if the extension is present in the list */ static BOOL has_extension( const char *list, const char *ext ) @@ -838,20 +831,17 @@ static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl ) static void x11drv_drawable_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable(base); - switch (gl->type) + if (gl->base.funcs == &x11drv_surface_funcs) { - case DC_GL_WINDOW: TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); destroy_client_window( gl->base.hwnd, gl->window ); XFreeColormap( gdi_display, gl->colormap ); - break; - case DC_GL_PBUFFER: + } + else + { TRACE( "destroying pbuffer drawable %lx\n", gl->drawable ); pglXDestroyPbuffer( gdi_display, gl->drawable ); - break; - default: - break; } if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); @@ -937,7 +927,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; - gl->base.funcs = &x11drv_drawable_funcs; + gl->base.funcs = &x11drv_surface_funcs; gl->base.ref = 1; gl->base.hwnd = hwnd; gl->base.hdc = 0; @@ -947,7 +937,6 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) gl->swap_interval = INT_MIN; gl->rect = rect;
- gl->type = DC_GL_WINDOW; gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, (fmt->visual->class == PseudoColor || fmt->visual->class == GrayScale || fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); @@ -1067,12 +1056,12 @@ void sync_gl_drawable( HWND hwnd ) pthread_mutex_lock( &context_mutex ); LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) { - if ((gl = context->draw) && gl->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) + 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->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) + if ((gl = context->read) && gl->base.funcs == &x11drv_surface_funcs && gl->base.hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); @@ -1406,7 +1395,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva struct gl_drawable *gl;
if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; - if (gl->type != DC_GL_WINDOW) + if (gl->base.funcs != &x11drv_surface_funcs) { opengl_drawable_release( &gl->base ); return FALSE; @@ -1533,13 +1522,12 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex glx_attribs[count++] = 0;
if (!(gl = calloc( 1, sizeof(*gl) ))) return FALSE; - gl->base.funcs = &x11drv_drawable_funcs; + gl->base.funcs = &x11drv_pbuffer_funcs; gl->base.ref = 1; gl->base.hwnd = 0; gl->base.hdc = hdc; gl->base.format = format;
- gl->type = DC_GL_PBUFFER; gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); if (!gl->drawable) @@ -1715,10 +1703,10 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } - if (gl->type != DC_GL_WINDOW) + if (gl->base.funcs == &x11drv_pbuffer_funcs) { opengl_drawable_release( &gl->base ); - return FALSE; + return TRUE; }
pthread_mutex_lock( &context_mutex ); @@ -1761,7 +1749,12 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_pbuffer_bind = x11drv_pbuffer_bind, };
-static const struct opengl_drawable_funcs x11drv_drawable_funcs = +static const struct opengl_drawable_funcs x11drv_surface_funcs = +{ + .destroy = x11drv_drawable_destroy, +}; + +static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = { .destroy = x11drv_drawable_destroy, };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 15 +---------- dlls/winemac.drv/opengl.c | 15 ++++++----- dlls/winewayland.drv/opengl.c | 23 +++++----------- dlls/winex11.drv/opengl.c | 50 +++++++++++++++-------------------- include/wine/opengl_driver.h | 1 - 5 files changed, 39 insertions(+), 65 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 921f79a33a5..8d20ff05fce 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -400,12 +400,6 @@ static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex return FALSE; }
-static BOOL egldrv_pbuffer_destroy( HDC hdc, struct opengl_drawable *drawable ) -{ - FIXME( "stub!\n" ); - return FALSE; -} - static BOOL egldrv_pbuffer_updated( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level ) { FIXME( "stub!\n" ); @@ -451,7 +445,6 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_set_pixel_format = egldrv_set_pixel_format, .p_swap_buffers = egldrv_swap_buffers, .p_pbuffer_create = egldrv_pbuffer_create, - .p_pbuffer_destroy = egldrv_pbuffer_destroy, .p_pbuffer_updated = egldrv_pbuffer_updated, .p_pbuffer_bind = egldrv_pbuffer_bind, .p_context_create = egldrv_context_create, @@ -613,11 +606,6 @@ static BOOL nulldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum te return FALSE; }
-static BOOL nulldrv_pbuffer_destroy( HDC hdc, struct opengl_drawable *drawable ) -{ - return FALSE; -} - static BOOL nulldrv_pbuffer_updated( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level ) { return GL_TRUE; @@ -657,7 +645,6 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_set_pixel_format = nulldrv_set_pixel_format, .p_swap_buffers = nulldrv_swap_buffers, .p_pbuffer_create = nulldrv_pbuffer_create, - .p_pbuffer_destroy = nulldrv_pbuffer_destroy, .p_pbuffer_updated = nulldrv_pbuffer_updated, .p_pbuffer_bind = nulldrv_pbuffer_bind, .p_context_create = nulldrv_context_create, @@ -1085,7 +1072,7 @@ static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer )
TRACE( "pbuffer %p\n", pbuffer );
- driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->drawable ); + opengl_drawable_release( pbuffer->drawable ); if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); NtGdiDeleteObjectApp( pbuffer->hdc ); free( pbuffer ); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 8fd32474c7c..1facd278726 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -100,7 +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_drawable_funcs; +static const struct opengl_drawable_funcs macdrv_pbuffer_funcs;
static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); @@ -2384,7 +2384,7 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text }
if (!(gl = calloc(1, sizeof(*gl)))) return FALSE; - gl->base.funcs = &macdrv_drawable_funcs; + gl->base.funcs = &macdrv_pbuffer_funcs; gl->base.ref = 1; gl->base.hwnd = 0; gl->base.hdc = hdc; @@ -2407,11 +2407,11 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text return TRUE; }
-static BOOL macdrv_pbuffer_destroy(HDC hdc, struct opengl_drawable *base) +static void macdrv_pbuffer_destroy(struct opengl_drawable *base) { struct gl_drawable *gl = impl_from_opengl_drawable(base);
- TRACE("hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable(base)); + TRACE("drawable %s\n", debugstr_opengl_drawable(base));
pthread_mutex_lock(&dc_pbuffers_mutex); CFDictionaryRemoveValue(dc_pbuffers, gl->pbuffer); @@ -2419,7 +2419,6 @@ static BOOL macdrv_pbuffer_destroy(HDC hdc, struct opengl_drawable *base)
CGLReleasePBuffer(gl->pbuffer); free(gl); - return TRUE; }
@@ -3064,7 +3063,11 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_context_flush = macdrv_context_flush, .p_context_make_current = macdrv_context_make_current, .p_pbuffer_create = macdrv_pbuffer_create, - .p_pbuffer_destroy = macdrv_pbuffer_destroy, .p_pbuffer_updated = macdrv_pbuffer_updated, .p_pbuffer_bind = macdrv_pbuffer_bind, }; + +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 34b9487d6b6..0dc3f16b9f9 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -124,6 +124,13 @@ static struct wayland_gl_drawable *wayland_gl_drawable_get(HWND hwnd, HDC hdc) 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) @@ -523,21 +530,6 @@ static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum tex return TRUE; }
-static BOOL wayland_pbuffer_destroy(HDC hdc, struct opengl_drawable *base) -{ - struct wayland_gl_drawable *drawable = impl_from_opengl_drawable(base); - - TRACE("hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable(base)); - - pthread_mutex_lock(&gl_object_mutex); - list_remove(&drawable->entry); - pthread_mutex_unlock(&gl_object_mutex); - - opengl_drawable_release(&drawable->base); - - return GL_TRUE; -} - static BOOL wayland_pbuffer_updated(HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level) { return GL_TRUE; @@ -558,7 +550,6 @@ static struct opengl_driver_funcs wayland_driver_funcs = .p_context_flush = wayland_context_flush, .p_context_make_current = wayland_context_make_current, .p_pbuffer_create = wayland_pbuffer_create, - .p_pbuffer_destroy = wayland_pbuffer_destroy, .p_pbuffer_updated = wayland_pbuffer_updated, .p_pbuffer_bind = wayland_pbuffer_bind, }; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 499e906b948..eae594d630d 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -828,21 +828,15 @@ static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl ) return gl; }
-static void x11drv_drawable_destroy( struct opengl_drawable *base ) +static void x11drv_surface_destroy( struct opengl_drawable *base ) { - struct gl_drawable *gl = impl_from_opengl_drawable(base); - if (gl->base.funcs == &x11drv_surface_funcs) - { - TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); - pglXDestroyWindow( gdi_display, gl->drawable ); - destroy_client_window( gl->base.hwnd, gl->window ); - XFreeColormap( gdi_display, gl->colormap ); - } - else - { - TRACE( "destroying pbuffer drawable %lx\n", gl->drawable ); - pglXDestroyPbuffer( gdi_display, gl->drawable ); - } + struct gl_drawable *gl = impl_from_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->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); free( gl ); @@ -1302,17 +1296,17 @@ static void *x11drv_get_proc_address( const char *name ) return pglXGetProcAddressARB( (const GLubyte *)name ); }
-static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawable *draw, - struct gl_drawable *read ) +static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawable **draw, + struct gl_drawable **read ) { struct gl_drawable *old_draw, *old_read;
old_draw = ctx->draw; old_read = ctx->read; - ctx->draw = grab_gl_drawable( draw ); - ctx->read = read ? grab_gl_drawable( read ) : NULL; - if (old_draw) opengl_drawable_release( &old_draw->base ); - if (old_read) opengl_drawable_release( &old_read->base ); + ctx->draw = *draw; + ctx->read = *read; + *draw = old_draw; + *read = old_read; }
static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) @@ -1339,7 +1333,7 @@ static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva else ret = pglXMakeContextCurrent( gdi_display, draw_gl->drawable, read_gl ? read_gl->drawable : 0, ctx->ctx ); if (ret) { - set_context_drawables( ctx, draw_gl, read_gl ); + set_context_drawables( ctx, &draw_gl, &read_gl ); NtCurrentTeb()->glReserved2 = ctx; pthread_mutex_unlock( &context_mutex ); goto done; @@ -1548,18 +1542,19 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex return TRUE; }
-static BOOL x11drv_pbuffer_destroy( HDC hdc, struct opengl_drawable *base ) +static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); + HDC hdc = gl->base.hdc;
- TRACE( "hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable( base ) ); + 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 ); - opengl_drawable_release( &gl->base );
- return GL_TRUE; + pglXDestroyPbuffer( gdi_display, gl->drawable ); + free( gl ); }
static BOOL x11drv_pbuffer_updated( HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level ) @@ -1744,19 +1739,18 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_context_flush = x11drv_context_flush, .p_context_make_current = x11drv_context_make_current, .p_pbuffer_create = x11drv_pbuffer_create, - .p_pbuffer_destroy = x11drv_pbuffer_destroy, .p_pbuffer_updated = x11drv_pbuffer_updated, .p_pbuffer_bind = x11drv_pbuffer_bind, };
static const struct opengl_drawable_funcs x11drv_surface_funcs = { - .destroy = x11drv_drawable_destroy, + .destroy = x11drv_surface_destroy, };
static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = { - .destroy = x11drv_drawable_destroy, + .destroy = x11drv_pbuffer_destroy, };
#else /* no OpenGL includes */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 5101525f744..b4f3d13eca3 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -168,7 +168,6 @@ struct opengl_driver_funcs BOOL (*p_context_make_current)(HDC,HDC,void*); BOOL (*p_pbuffer_create)( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ); - BOOL (*p_pbuffer_destroy)( HDC hdc, struct opengl_drawable *drawable ); BOOL (*p_pbuffer_updated)( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level ); UINT (*p_pbuffer_bind)( HDC hdc, struct opengl_drawable *drawable, GLenum buffer ); };
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 17 +++++++++++++++++ dlls/wineandroid.drv/opengl.c | 9 +-------- dlls/winemac.drv/opengl.c | 10 ++-------- dlls/winewayland.drv/opengl.c | 10 +--------- dlls/winex11.drv/opengl.c | 17 ++--------------- include/wine/opengl_driver.h | 1 + 6 files changed, 24 insertions(+), 40 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 8d20ff05fce..c165f9588c7 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -163,6 +163,22 @@ static void register_extension( char *list, size_t size, const char *name ) } }
+void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ) +{ + struct opengl_drawable *drawable; + + if (!(drawable = calloc( 1, size ))) return NULL; + drawable->funcs = funcs; + drawable->ref = 1; + + drawable->format = format; + drawable->hwnd = hwnd; + drawable->hdc = hdc; + + TRACE( "created %s\n", debugstr_opengl_drawable( drawable ) ); + return drawable; +} + void opengl_drawable_add_ref( struct opengl_drawable *drawable ) { ULONG ref = InterlockedIncrement( &drawable->ref ); @@ -177,6 +193,7 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) if (!ref) { drawable->funcs->destroy( drawable ); + free( drawable ); } }
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index f0b3f76e64e..593b5e448aa 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -105,13 +105,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; struct gl_drawable *gl;
- if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; - gl->base.funcs = &android_drawable_funcs; - gl->base.ref = 1; - gl->base.hwnd = hwnd; - gl->base.hdc = hdc; - gl->base.format = format; - + 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 ); @@ -143,7 +137,6 @@ static void android_drawable_destroy( struct 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 ); - free( gl ); }
static void release_gl_drawable( struct gl_drawable *gl ) diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 1facd278726..bddd6f531f4 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2383,18 +2383,13 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text texture_format = GL_RGB; }
- if (!(gl = calloc(1, sizeof(*gl)))) return FALSE; - gl->base.funcs = &macdrv_pbuffer_funcs; - gl->base.ref = 1; - gl->base.hwnd = 0; - gl->base.hdc = hdc; - gl->base.format = format; + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_pbuffer_funcs, format, 0, hdc))) return FALSE;
err = CGLCreatePBuffer(*width, *height, texture_target, texture_format, max_level, &gl->pbuffer); if (err != kCGLNoError) { WARN("CGLCreatePBuffer failed; err %d %s\n", err, CGLErrorString(err)); - free(gl); + opengl_drawable_release(&gl->base); return FALSE; }
@@ -2418,7 +2413,6 @@ static void macdrv_pbuffer_destroy(struct opengl_drawable *base) pthread_mutex_unlock(&dc_pbuffers_mutex);
CGLReleasePBuffer(gl->pbuffer); - free(gl); }
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 0dc3f16b9f9..a9f0e2d259e 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -143,8 +143,6 @@ static void wayland_drawable_destroy(struct opengl_drawable *base)
if (data) wayland_win_data_release(data); } - - free(gl); }
static inline BOOL is_onscreen_format(int format) @@ -175,13 +173,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc } *attrib++ = EGL_NONE;
- if (!(gl = calloc(1, sizeof(*gl)))) return NULL; - gl->base.funcs = &wayland_drawable_funcs; - gl->base.ref = 1; - gl->base.hwnd = hwnd; - gl->base.hdc = hdc; - gl->base.format = format; - + if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, hwnd, hdc))) return NULL; gl->swap_interval = 1;
/* Get the client surface for the HWND. If don't have a wayland surface diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index eae594d630d..ad82c8d8f7a 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -839,7 +839,6 @@ static void x11drv_surface_destroy( struct opengl_drawable *base ) XFreeColormap( gdi_display, gl->colormap ); if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); - free( gl ); }
static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) @@ -920,13 +919,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format )
NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; - gl->base.funcs = &x11drv_surface_funcs; - gl->base.ref = 1; - gl->base.hwnd = hwnd; - gl->base.hdc = 0; - gl->base.format = format; - + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd, 0 ))) return NULL; /* 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; @@ -1515,12 +1508,7 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } glx_attribs[count++] = 0;
- if (!(gl = calloc( 1, sizeof(*gl) ))) return FALSE; - gl->base.funcs = &x11drv_pbuffer_funcs; - gl->base.ref = 1; - gl->base.hwnd = 0; - gl->base.hdc = hdc; - gl->base.format = format; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_pbuffer_funcs, format, 0, hdc ))) return FALSE;
gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); @@ -1554,7 +1542,6 @@ static void x11drv_pbuffer_destroy( struct opengl_drawable *base ) pthread_mutex_unlock( &context_mutex );
pglXDestroyPbuffer( gdi_display, gl->drawable ); - free( gl ); }
static BOOL x11drv_pbuffer_updated( HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level ) diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index b4f3d13eca3..15f9b26e5cf 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -149,6 +149,7 @@ static inline const char *debugstr_opengl_drawable( struct opengl_drawable *draw return wine_dbg_sprintf( "%p (format %u, hwnd %p, hdc %p)", drawable, drawable->format, drawable->hwnd, drawable->hdc ); }
+W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ); W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 5 +++- dlls/winewayland.drv/vulkan.c | 5 +++- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 41 +++++++++++-------------------- 4 files changed, 23 insertions(+), 29 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index a9f0e2d259e..0b7595c3dcf 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -179,7 +179,8 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc /* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the * target render surface. */ - if (!(gl->client = get_client_surface(hwnd))) goto err; + if (!(gl->client = wayland_client_surface_create(hwnd))) goto err; + set_client_surface(hwnd, gl->client);
gl->wl_egl_window = wl_egl_window_create(gl->client->wl_surface, width, height); if (!gl->wl_egl_window) @@ -493,6 +494,8 @@ static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval
if (ctx) wayland_context_refresh(ctx); ensure_window_surface_contents(toplevel); + set_client_surface(hwnd, gl->client); + /* 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); diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 4774f11771c..e619cfb4fa0 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -74,7 +74,7 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins
TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
- if (!(client = get_client_surface(hwnd))) + if (!(client = wayland_client_surface_create(hwnd))) { ERR("Failed to create client surface for hwnd=%p\n", hwnd); return VK_ERROR_OUT_OF_HOST_MEMORY; @@ -96,6 +96,7 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins return res; }
+ set_client_surface(hwnd, client); *private = client;
TRACE("Created surface=0x%s, private=%p\n", wine_dbgstr_longlong(*surface), *private); @@ -121,8 +122,10 @@ static void wayland_vulkan_surface_update(HWND hwnd, void *private)
static void wayland_vulkan_surface_presented(HWND hwnd, void *private, VkResult result) { + struct wayland_client_surface *client = private; HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); ensure_window_surface_contents(toplevel); + set_client_surface(hwnd, client); }
static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 001cb29e05e..e0be6970b05 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -377,6 +377,7 @@ struct wayland_win_data *wayland_win_data_get_nolock(HWND hwnd); void wayland_win_data_release(struct wayland_win_data *data);
struct wayland_client_surface *get_client_surface(HWND hwnd); +void set_client_surface(HWND hwnd, struct wayland_client_surface *client); BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region); struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd); void ensure_window_surface_contents(HWND hwnd); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index ce5b6bb5143..dbcbd90be00 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -775,42 +775,29 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam, const POINT return ret; }
-/********************************************************************** - * get_client_surface - */ -struct wayland_client_surface *get_client_surface(HWND hwnd) +void set_client_surface(HWND hwnd, struct wayland_client_surface *new_client) { HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); - struct wayland_client_surface *client; + struct wayland_client_surface *old_client; struct wayland_win_data *data;
- if ((data = wayland_win_data_get(hwnd))) - { - /* ownership is shared with one of the callers, the last caller to release - * its reference will also destroy it and clear our pointer. */ - if ((client = data->client_surface)) InterlockedIncrement(&client->ref); - } - else - { - client = NULL; - } + /* ownership is shared with the callers, the last caller to release + * its reference will also destroy it and clear our pointer. */
- if (!client && !(client = wayland_client_surface_create(hwnd))) - { - if (data) wayland_win_data_release(data); - return NULL; - } - if (!data) return client; + if (!(data = wayland_win_data_get(hwnd))) return;
- if (toplevel && NtUserIsWindowVisible(hwnd)) - wayland_client_surface_attach(client, toplevel); - else - wayland_client_surface_detach(client); + if ((old_client = data->client_surface)) + wayland_client_surface_detach(old_client);
- if (!data->client_surface) data->client_surface = client; + if ((data->client_surface = new_client)) + { + if (toplevel && NtUserIsWindowVisible(hwnd)) + wayland_client_surface_attach(new_client, toplevel); + else + wayland_client_surface_detach(new_client); + }
wayland_win_data_release(data); - return client; }
BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region)