Instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/8496, leaving context sharing for later.
-- v2: win32u: Remove now unnecessary opengl_drawable hdc member. win32u: Implement generic EGL driver pbuffer surface. win32u: Avoid releasing opengl drawable within drawables_lock. win32u: Avoid calling detach, flush or swap on pbuffer drawables. winemac: Remove now unnecessary pbuffer tracking.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/opengl.c | 77 ++++++--------------------------------- 1 file changed, 11 insertions(+), 66 deletions(-)
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index dd3b3e4da59..57b2ed23dd9 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -93,9 +93,6 @@ static struct gl_drawable *impl_from_opengl_drawable(struct opengl_drawable *bas static struct list context_list = LIST_INIT(context_list); static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER;
-static CFMutableDictionaryRef dc_pbuffers; -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; @@ -2370,10 +2367,6 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text return FALSE; }
- pthread_mutex_lock(&dc_pbuffers_mutex); - CFDictionarySetValue(dc_pbuffers, hdc, gl->pbuffer); - pthread_mutex_unlock(&dc_pbuffers_mutex); - *drawable = &gl->base; TRACE(" -> %p\n", gl); return TRUE; @@ -2385,10 +2378,6 @@ static void macdrv_pbuffer_destroy(struct opengl_drawable *base)
TRACE("drawable %s\n", debugstr_opengl_drawable(base));
- pthread_mutex_lock(&dc_pbuffers_mutex); - CFDictionaryRemoveValue(dc_pbuffers, gl->pbuffer); - pthread_mutex_unlock(&dc_pbuffers_mutex); - CGLReleasePBuffer(gl->pbuffer); }
@@ -2439,22 +2428,9 @@ static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl } else { - CGLPBufferObj pbuffer; - - pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, draw->base.hdc); - if (!pbuffer) - { - WARN("no window or pbuffer for DC\n"); - pthread_mutex_unlock(&dc_pbuffers_mutex); - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - context->draw_hwnd = NULL; context->draw_view = NULL; - context->draw_pbuffer = pbuffer; - pthread_mutex_unlock(&dc_pbuffers_mutex); + context->draw_pbuffer = draw->pbuffer; }
context->read_view = NULL; @@ -2476,9 +2452,7 @@ static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl } else { - pthread_mutex_lock(&dc_pbuffers_mutex); - context->read_pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, read->base.hdc); - pthread_mutex_unlock(&dc_pbuffers_mutex); + context->read_pbuffer = read->pbuffer; } }
@@ -2790,13 +2764,6 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co } funcs = opengl_funcs;
- dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); - if (!dc_pbuffers) - { - WARN("CFDictionaryCreateMutable failed\n"); - return STATUS_NOT_SUPPORTED; - } - opengl_handle = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY|RTLD_LOCAL|RTLD_NOLOAD); if (!opengl_handle) { @@ -2951,49 +2918,27 @@ static void *macdrv_get_proc_address(const char *name) static BOOL macdrv_surface_swap(struct opengl_drawable *base) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; + struct macdrv_win_data *data; HWND hwnd = base->hwnd; - HDC hdc = base->hdc; BOOL match = FALSE;
- TRACE("hdc %p context %p/%p/%p\n", hdc, context, (context ? context->context : NULL), + TRACE("%s context %p/%p/%p\n", debugstr_opengl_drawable(base), context, (context ? context->context : NULL), (context ? context->cglcontext : NULL));
- if (hwnd) + if (!(data = get_win_data(hwnd))) { - struct macdrv_win_data *data; - - if (!(data = get_win_data(hwnd))) - { - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (context && context->draw_view == data->client_cocoa_view) - match = TRUE; - - release_win_data(data); + RtlSetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; } - else - { - CGLPBufferObj pbuffer;
- pthread_mutex_lock(&dc_pbuffers_mutex); - pbuffer = (CGLPBufferObj)CFDictionaryGetValue(dc_pbuffers, hdc); - pthread_mutex_unlock(&dc_pbuffers_mutex); + if (context && context->draw_view == data->client_cocoa_view) + match = TRUE;
- if (!pbuffer) - { - RtlSetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (context && context->draw_pbuffer == pbuffer) - match = TRUE; - } + release_win_data(data);
if (!match) { - FIXME("current context %p doesn't match hdc %p; can't swap\n", context, hdc); + FIXME("current context %p doesn't match; can't swap\n", context); return FALSE; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 14 ++++++++++---- dlls/winemac.drv/opengl.c | 16 ---------------- dlls/winex11.drv/opengl.c | 16 ---------------- 3 files changed, 10 insertions(+), 36 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 65318895a65..f89f16c2f48 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -246,9 +246,12 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) const struct opengl_funcs *funcs = &display_funcs; const struct egl_platform *egl = &display_egl;
- pthread_mutex_lock( &drawables_lock ); - opengl_drawable_detach( drawable ); - pthread_mutex_unlock( &drawables_lock ); + if (drawable->hwnd) + { + pthread_mutex_lock( &drawables_lock ); + opengl_drawable_detach( drawable ); + pthread_mutex_unlock( &drawables_lock ); + }
drawable->funcs->destroy( drawable ); if (drawable->surface) funcs->p_eglDestroySurface( egl->display, drawable->surface ); @@ -258,6 +261,8 @@ void opengl_drawable_release( struct opengl_drawable *drawable )
static void opengl_drawable_flush( struct opengl_drawable *drawable, int interval, UINT flags ) { + if (!drawable->hwnd) return; + if (InterlockedCompareExchange( &drawable->updated, 0, 1 )) flags |= GL_FLUSH_UPDATED; if (interval != drawable->interval) { @@ -1658,7 +1663,8 @@ static BOOL win32u_wglSwapBuffers( HDC hdc )
if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; opengl_drawable_flush( draw, interval, 0 ); - ret = draw->funcs->swap( draw ); + if (!draw->hwnd) ret = FALSE; /* pbuffer, nothing to do */ + else ret = draw->funcs->swap( draw ); opengl_drawable_release( draw );
return ret; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 57b2ed23dd9..4d9780c7eb3 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2381,19 +2381,6 @@ 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) -{ -} - -static BOOL macdrv_pbuffer_swap(struct opengl_drawable *base) -{ - return FALSE; -} - static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl_drawable *read_base, void *private) { struct gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); @@ -2973,7 +2960,4 @@ 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/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 547608aa79f..4d100088030 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1428,19 +1428,6 @@ 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 ) -{ -} - -static BOOL x11drv_pbuffer_swap( struct opengl_drawable *base ) -{ - return FALSE; -} - static BOOL x11drv_pbuffer_updated( HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level ) { return GL_TRUE; @@ -1669,9 +1656,6 @@ 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, };
static const struct opengl_drawable_funcs x11drv_egl_surface_funcs =
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index f89f16c2f48..1c89b49b483 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -166,16 +166,9 @@ 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 ) -{ - drawable->funcs->detach( drawable ); - list_remove( &drawable->entry ); - list_init( &drawable->entry ); -} - void detach_opengl_drawables( HWND hwnd ) { + struct list detached = LIST_INIT( detached ); struct opengl_drawable *drawable, *next;
pthread_mutex_lock( &drawables_lock ); @@ -183,10 +176,22 @@ void detach_opengl_drawables( HWND hwnd ) LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &drawables, struct opengl_drawable, entry ) { if (drawable->hwnd != hwnd) continue; - opengl_drawable_detach( drawable ); + + list_remove( &drawable->entry ); + list_add_tail( &detached, &drawable->entry ); + opengl_drawable_add_ref( drawable ); + + drawable->funcs->detach( drawable ); + drawable->hwnd = NULL; }
pthread_mutex_unlock( &drawables_lock ); + + LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &detached, struct opengl_drawable, entry ) + { + list_remove( &drawable->entry ); + opengl_drawable_release( drawable ); + } }
void update_opengl_drawables( HWND hwnd ) @@ -246,12 +251,13 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) const struct opengl_funcs *funcs = &display_funcs; const struct egl_platform *egl = &display_egl;
+ pthread_mutex_lock( &drawables_lock ); if (drawable->hwnd) { - pthread_mutex_lock( &drawables_lock ); - opengl_drawable_detach( drawable ); - pthread_mutex_unlock( &drawables_lock ); + drawable->funcs->detach( drawable ); + list_remove( &drawable->entry ); } + pthread_mutex_unlock( &drawables_lock );
drawable->funcs->destroy( drawable ); if (drawable->surface) funcs->p_eglDestroySurface( egl->display, drawable->surface );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 94 ++++++++++++++++++++++++++++++++--- dlls/winewayland.drv/opengl.c | 43 ++-------------- 2 files changed, 92 insertions(+), 45 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 1c89b49b483..f5071657e23 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -281,6 +281,15 @@ static void opengl_drawable_flush( struct opengl_drawable *drawable, int interva
#ifdef SONAME_LIBEGL
+static const struct opengl_drawable_funcs egldrv_pbuffer_funcs; + +static inline EGLConfig egl_config_for_format( const struct egl_platform *egl, int format ) +{ + assert(format > 0 && format <= 2 * egl->config_count); + if (format <= egl->config_count) return egl->configs[format - 1]; + return egl->configs[format - egl->config_count - 1]; +} + static void *egldrv_get_proc_address( const char *name ) { return display_funcs.p_eglGetProcAddress( name ); @@ -293,7 +302,6 @@ static UINT egldrv_init_pixel_formats( UINT *onscreen_count ) const EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_NONE }; EGLConfig *configs; @@ -420,7 +428,9 @@ static BOOL describe_egl_config( EGLConfig config, struct wgl_pixel_format *fmt, } else fmt->pixel_type = -1;
- fmt->draw_to_pbuffer = TRUE; + if ((fmt->draw_to_pbuffer = !!(surface_type & EGL_PBUFFER_BIT))) + pfd->dwFlags |= PFD_DRAW_TO_BITMAP; + /* Use some arbitrary but reasonable limits (4096 is also Mesa's default) */ fmt->max_pbuffer_width = 4096; fmt->max_pbuffer_height = 4096; @@ -489,19 +499,81 @@ static BOOL egldrv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ) { - FIXME( "stub!\n" ); - return FALSE; + const struct opengl_funcs *funcs = &display_funcs; + const struct egl_platform *egl = &display_egl; + EGLint attribs[13], *attrib = attribs; + struct opengl_drawable *gl; + + TRACE( "hdc %p, format %d, largest %u, texture_format %#x, texture_target %#x, max_level %#x, width %d, height %d, drawable %p\n", + hdc, format, largest, texture_format, texture_target, max_level, *width, *height, drawable ); + + *attrib++ = EGL_WIDTH; + *attrib++ = *width; + *attrib++ = EGL_HEIGHT; + *attrib++ = *height; + if (largest) + { + *attrib++ = EGL_LARGEST_PBUFFER; + *attrib++ = 1; + } + switch (texture_format) + { + case 0: break; + case GL_RGB: + *attrib++ = EGL_TEXTURE_FORMAT; + *attrib++ = EGL_TEXTURE_RGB; + break; + case GL_RGBA: + *attrib++ = EGL_TEXTURE_FORMAT; + *attrib++ = EGL_TEXTURE_RGBA; + break; + default: + FIXME( "Unsupported format %#x\n", texture_format ); + *attrib++ = EGL_TEXTURE_FORMAT; + *attrib++ = EGL_TEXTURE_RGBA; + break; + } + switch (texture_target) + { + case 0: break; + case GL_TEXTURE_2D: + *attrib++ = EGL_TEXTURE_TARGET; + *attrib++ = EGL_TEXTURE_2D; + break; + default: + FIXME( "Unsupported target %#x\n", texture_target ); + *attrib++ = EGL_TEXTURE_TARGET; + *attrib++ = EGL_TEXTURE_2D; + break; + } + if (max_level) + { + *attrib++ = EGL_MIPMAP_TEXTURE; + *attrib++ = GL_TRUE; + } + *attrib++ = EGL_NONE; + + if (!(gl = opengl_drawable_create( sizeof(*gl), &egldrv_pbuffer_funcs, format, 0, hdc ))) return FALSE; + if (!(gl->surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format( egl, gl->format ), attribs ))) + { + opengl_drawable_release( gl ); + return FALSE; + } + + funcs->p_eglQuerySurface( egl->display, gl->surface, EGL_WIDTH, width ); + funcs->p_eglQuerySurface( egl->display, gl->surface, EGL_HEIGHT, height ); + + *drawable = gl; + return TRUE; }
static BOOL egldrv_pbuffer_updated( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level ) { - FIXME( "stub!\n" ); return GL_TRUE; }
static UINT egldrv_pbuffer_bind( HDC hdc, struct opengl_drawable *drawable, GLenum buffer ) { - FIXME( "stub!\n" ); return -1; /* use default implementation */ }
@@ -596,6 +668,16 @@ static BOOL egldrv_make_current( struct opengl_drawable *draw, struct opengl_dra return funcs->p_eglMakeCurrent( egl->display, context ? draw->surface : EGL_NO_SURFACE, context ? read->surface : EGL_NO_SURFACE, context ); }
+static void egldrv_pbuffer_destroy( struct opengl_drawable *drawable ) +{ + TRACE( "%s\n", debugstr_opengl_drawable( drawable ) ); +} + +static const struct opengl_drawable_funcs egldrv_pbuffer_funcs = +{ + .destroy = egldrv_pbuffer_destroy, +}; + static const struct opengl_driver_funcs egldrv_funcs = { .p_get_proc_address = egldrv_get_proc_address, diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9f1660a80a6..3617b5418d2 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -214,38 +214,7 @@ static BOOL wayland_drawable_swap(struct opengl_drawable *base) return TRUE; }
-static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **surface) -{ - struct wayland_gl_drawable *drawable; - - TRACE("hdc %p, format %d, largest %u, texture_format %#x, texture_target %#x, max_level %#x, width %d, height %d, private %p\n", - hdc, format, largest, texture_format, texture_target, max_level, *width, *height, surface); - - /* Use an unmapped wayland surface as our offscreen "pbuffer" surface. */ - if (!(drawable = wayland_gl_drawable_create(0, hdc, format, *width, *height))) return FALSE; - *surface = &drawable->base; - return TRUE; -} - -static BOOL wayland_pbuffer_updated(HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level) -{ - return GL_TRUE; -} - -static UINT wayland_pbuffer_bind(HDC hdc, struct opengl_drawable *base, GLenum buffer) -{ - return -1; /* use default implementation */ -} - -static struct opengl_driver_funcs wayland_driver_funcs = -{ - .p_init_egl_platform = wayland_init_egl_platform, - .p_surface_create = wayland_opengl_surface_create, - .p_pbuffer_create = wayland_pbuffer_create, - .p_pbuffer_updated = wayland_pbuffer_updated, - .p_pbuffer_bind = wayland_pbuffer_bind, -}; +static struct opengl_driver_funcs wayland_driver_funcs;
static const struct opengl_drawable_funcs wayland_drawable_funcs = { @@ -271,13 +240,9 @@ UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, c if (!opengl_funcs->egl_handle) return STATUS_NOT_SUPPORTED; funcs = opengl_funcs;
- 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; - wayland_driver_funcs.p_context_create = (*driver_funcs)->p_context_create; - wayland_driver_funcs.p_context_destroy = (*driver_funcs)->p_context_destroy; - wayland_driver_funcs.p_make_current = (*driver_funcs)->p_make_current; + wayland_driver_funcs = **driver_funcs; + wayland_driver_funcs.p_init_egl_platform = wayland_init_egl_platform; + wayland_driver_funcs.p_surface_create = wayland_opengl_surface_create;
*driver_funcs = &wayland_driver_funcs; return STATUS_SUCCESS;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 5 ++--- dlls/wineandroid.drv/opengl.c | 3 +-- dlls/winemac.drv/opengl.c | 4 ++-- dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 17 +++++++++-------- include/wine/opengl_driver.h | 5 ++--- 6 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index f5071657e23..7b1afb7571a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -210,7 +210,7 @@ void update_opengl_drawables( HWND hwnd ) pthread_mutex_unlock( &drawables_lock ); }
-void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ) +void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd ) { struct opengl_drawable *drawable;
@@ -221,7 +221,6 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun drawable->format = format; drawable->interval = INT_MIN; drawable->hwnd = hwnd; - drawable->hdc = hdc;
if (!hwnd) list_init( &drawable->entry ); /* pbuffer, keep it unlinked */ else @@ -553,7 +552,7 @@ static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } *attrib++ = EGL_NONE;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &egldrv_pbuffer_funcs, format, 0, hdc ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &egldrv_pbuffer_funcs, format, 0 ))) return FALSE; if (!(gl->surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format( egl, gl->format ), attribs ))) { opengl_drawable_release( gl ); diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index ba72dbd4979..fde0e24c02d 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -75,7 +75,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, A static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; struct gl_drawable *gl;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, hwnd, hdc ))) return NULL; + if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, hwnd ))) return NULL;
if (!window) gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); else gl->window = grab_ioctl_window( window ); @@ -134,7 +134,6 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg 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 ) ); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 4d9780c7eb3..f48737c1b43 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1484,7 +1484,7 @@ static BOOL macdrv_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_ data->pixel_format = format; release_win_data(data);
- if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, hwnd, hdc))) return FALSE; + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, hwnd))) return FALSE; *drawable = &gl->base;
return TRUE; @@ -2357,7 +2357,7 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text texture_format = GL_RGB; }
- if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_pbuffer_funcs, format, 0, hdc))) return FALSE; + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_pbuffer_funcs, format, 0))) return FALSE;
err = CGLCreatePBuffer(*width, *height, texture_target, texture_format, max_level, &gl->pbuffer); if (err != kCGLNoError) diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 3617b5418d2..2275cf2bc4d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -114,7 +114,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc } *attrib++ = EGL_NONE;
- if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, hwnd, hdc))) return NULL; + if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, hwnd))) return NULL;
/* 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 diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 4d100088030..8581ace0e6d 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -203,6 +203,7 @@ struct gl_drawable Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ BOOL offscreen; + HDC hdc; HDC hdc_src; HDC hdc_dst; }; @@ -493,16 +494,16 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct op if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, hwnd, hdc ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, hwnd ))) return FALSE; gl->rect = rect; + gl->hdc = hdc;
gl->window = create_client_window( hwnd, &default_visual, default_colormap ); gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(format), (void *)gl->window, NULL ); if (!gl->base.surface) { - destroy_client_window( hwnd, gl->window ); - free( gl ); + opengl_drawable_release( &gl->base ); return FALSE; }
@@ -934,8 +935,9 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd, hdc ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd ))) return FALSE; gl->rect = rect; + gl->hdc = hdc;
gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, (fmt->visual->class == PseudoColor || fmt->visual->class == GrayScale || @@ -1261,15 +1263,14 @@ static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_fin { HWND hwnd = gl->base.hwnd, toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); struct x11drv_win_data *data; - HDC hdc = gl->base.hdc; Drawable window; RECT rect_dst, rect; HRGN region;
if (!gl->offscreen) return;
- window = get_dc_drawable( hdc, &rect ); - region = get_dc_monitor_region( hwnd, hdc ); + window = get_dc_drawable( gl->hdc, &rect ); + region = get_dc_monitor_region( hwnd, gl->hdc );
if (gl_finish) funcs->p_glFinish(); if (flush) XFlush( gdi_display ); @@ -1401,7 +1402,7 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } glx_attribs[count++] = 0;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_pbuffer_funcs, format, 0, hdc ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_pbuffer_funcs, format, 0 ))) return FALSE;
gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 188c7b81249..604bd6d6757 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -154,7 +154,6 @@ struct opengl_drawable int format; /* pixel format of the drawable */ int interval; /* last set surface swap interval */ HWND hwnd; /* window the drawable was created for */ - HDC hdc; /* DC the drawable was created for */ struct list entry; /* entry in win32u managed list */ LONG updated; /* has been moved / resized / reparented */ EGLSurface surface; /* surface for EGL based drivers */ @@ -163,10 +162,10 @@ struct opengl_drawable static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable ) { if (!drawable) return "(null)"; - return wine_dbg_sprintf( "%p (format %u, hwnd %p, hdc %p)", drawable, drawable->format, drawable->hwnd, drawable->hdc ); + return wine_dbg_sprintf( "%p (format %u, hwnd %p)", drawable, drawable->format, drawable->hwnd ); }
-W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd, HDC hdc ); +W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd ); W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable );
v2: Fix some incorrect free of EGL drawable and add missing winex11 specific HDC.
This MR breaks winewayland's support (or to be more accurate emulation) of pbuffers, see https://gitlab.winehq.org/wine/wine/-/merge_requests/6298. Is this planned to be reintroduced later in win32u? I think something along what's described below could be implemented in win32u as a generic pbuffer emulation strategy when the backend doesn't advertise any pbuffer capable formats.
In short, Wayland EGL doesn't support pbuffers, so previously winewayland emulated them through: 1. Backing WGL pbuffers with EGL window surfaces with an offscreen/dummy (i.e., not given any role) Wayland surface. 2. Marking all formats as pbuffer capable, and, additionally, since pbuffers are usually requested as single-buffered, we advertised single-buffered, pbuffer-only variations of all the formats (I think this latter feature was dropped already in some previous MR).
Hmm... I see, quite unfortunate that wayland GL has neither PBuffer nor Pixmaps... *sigh*.