From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 112 ++++++++------------------------------ 1 file changed, 22 insertions(+), 90 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index b1ba10587b1..3c0e7f08442 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,7 +197,6 @@ struct glx_pixel_format struct x11drv_context { HDC hdc; - const struct glx_pixel_format *fmt; GLXContext ctx; struct gl_drawable *draw; struct gl_drawable *read; @@ -221,7 +220,6 @@ struct gl_drawable Window window; /* window if drawable is a GLXWindow */ Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ - const struct glx_pixel_format *format; /* pixel format for the drawable */ int swap_interval; BOOL offscreen; HDC hdc_src; @@ -679,17 +677,6 @@ failed: return STATUS_NOT_SUPPORTED; }
-static const char *debugstr_fbconfig( GLXFBConfig fbconfig ) -{ - int id, visual, drawable; - - if (pglXGetFBConfigAttrib( gdi_display, fbconfig, GLX_FBCONFIG_ID, &id )) - return "*** invalid fbconfig"; - pglXGetFBConfigAttrib( gdi_display, fbconfig, GLX_VISUAL_ID, &visual ); - pglXGetFBConfigAttrib( gdi_display, fbconfig, GLX_DRAWABLE_TYPE, &drawable ); - return wine_dbg_sprintf( "fbconfig %#x visual id %#x drawable type %#x", id, visual, drawable ); -} - static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig) { int render_type, render_type_bit; @@ -832,33 +819,10 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) return size; }
-static inline BOOL is_valid_pixel_format( int format ) -{ - return format > 0 && format <= nb_pixel_formats; -} - -static inline BOOL is_onscreen_pixel_format( int format ) +static struct glx_pixel_format *glx_pixel_format_from_format( int format ) { - return format > 0 && format <= nb_onscreen_formats; -} - -/* GLX can advertise dozens of different pixelformats including offscreen and onscreen ones. - * In our WGL implementation we only support a subset of these formats namely the format of - * Wine's main visual and offscreen formats (if they are available). - * This function converts a WGL format to its corresponding GLX one. - */ -static const struct glx_pixel_format *get_pixel_format(Display *display, int iPixelFormat, BOOL AllowOffscreen) -{ - /* Check if the pixelformat is valid. Note that it is legal to pass an invalid - * iPixelFormat in case of probing the number of pixelformats. - */ - if (is_valid_pixel_format( iPixelFormat ) && - (is_onscreen_pixel_format( iPixelFormat ) || AllowOffscreen)) { - TRACE("Returning fmt_id=%#x for iPixelFormat=%d\n", - pixel_formats[iPixelFormat-1].fmt_id, iPixelFormat); - return &pixel_formats[iPixelFormat-1]; - } - return NULL; + assert( format > 0 && format <= nb_pixel_formats ); + return &pixel_formats[format - 1]; }
static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl ) @@ -945,16 +909,14 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) return gl; }
-static GLXContext create_glxcontext(Display *display, struct x11drv_context *context, GLXContext shareList, const int *attribs) +static GLXContext create_glxcontext( struct x11drv_context *context, int format, GLXContext share, const int *attribs ) { + struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); GLXContext ctx;
- if(attribs) - ctx = pglXCreateContextAttribsARB(gdi_display, context->fmt->fbconfig, shareList, GL_TRUE, attribs); - else if(context->fmt->visual) - ctx = pglXCreateContext(gdi_display, context->fmt->visual, shareList, GL_TRUE); - else /* Create a GLX Context for a pbuffer */ - ctx = pglXCreateNewContext(gdi_display, context->fmt->fbconfig, context->fmt->render_type, shareList, TRUE); + if (attribs) ctx = pglXCreateContextAttribsARB( gdi_display, fmt->fbconfig, share, TRUE, attribs ); + else if (fmt->visual) ctx = pglXCreateContext( gdi_display, fmt->visual, share, TRUE ); + else ctx = pglXCreateNewContext( gdi_display, fmt->fbconfig, fmt->render_type, share, TRUE );
return ctx; } @@ -962,10 +924,10 @@ static GLXContext create_glxcontext(Display *display, struct x11drv_context *con /*********************************************************************** * create_gl_drawable */ -static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel_format *format ) +static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) { + struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); struct gl_drawable *gl, *prev; - XVisualInfo *visual = format->visual; RECT rect;
NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) ); @@ -974,18 +936,17 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
/* 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->format = format; gl->ref = 1; gl->hwnd = hwnd; gl->rect = rect;
gl->type = DC_GL_WINDOW; - gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual->visual, - (visual->class == PseudoColor || visual->class == GrayScale || - visual->class == DirectColor) ? AllocAll : AllocNone ); - gl->window = create_client_window( hwnd, visual, gl->colormap ); - if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); + 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 ); + gl->window = create_client_window( hwnd, fmt->visual, gl->colormap ); + if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, gl->window, NULL ); + TRACE( "%p created client %lx drawable %lx, format %d\n", hwnd, gl->window, gl->drawable, format );
if (!gl->drawable) { @@ -1003,7 +964,6 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) { - const struct glx_pixel_format *fmt; struct gl_drawable *gl;
/* Even for internal pixel format fail setting it if the app has already set a @@ -1012,17 +972,8 @@ static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format, * than blitting from backup context. */ if (old_format) return old_format == new_format;
- if (!(fmt = get_pixel_format(gdi_display, new_format, FALSE /* Offscreen */))) - { - ERR( "Invalid format %d\n", new_format ); - return FALSE; - } - - if (!(gl = create_gl_drawable( hwnd, fmt ))) return FALSE; - - TRACE( "created GL drawable %lx for win %p %s\n", - gl->drawable, hwnd, debugstr_fbconfig( fmt->fbconfig )); - + if (!(gl = create_gl_drawable( hwnd, new_format ))) return FALSE; + TRACE( "created GL drawable %lx for win %p\n", gl->drawable, hwnd); XFlush( gdi_display ); release_gl_drawable( gl );
@@ -1140,21 +1091,11 @@ void destroy_gl_drawable( HWND hwnd ) }
-static BOOL x11drv_describe_pixel_format( int iPixelFormat, struct wgl_pixel_format *pf ) +static BOOL x11drv_describe_pixel_format( int format, struct wgl_pixel_format *pf ) { int value, drawable_type = 0, render_type = 0; + struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); int rb, gb, bb, ab; - const struct glx_pixel_format *fmt; - - /* Look for the iPixelFormat in our list of supported formats. If it is - * supported we get the index in the FBConfig table and the number of - * supported formats back */ - fmt = get_pixel_format( gdi_display, iPixelFormat, TRUE /* Offscreen */); - if (!fmt) - { - WARN( "unexpected format %d\n", iPixelFormat ); - return FALSE; - }
/* If we can't get basic information, there is no point continuing */ if (pglXGetFBConfigAttrib( gdi_display, fmt->fbconfig, GLX_DRAWABLE_TYPE, &drawable_type )) return 0; @@ -1495,7 +1436,6 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con if ((ret = calloc( 1, sizeof(*ret) ))) { ret->hdc = hdc; - ret->fmt = &pixel_formats[format - 1]; if (attribList) { /* attribList consists of pairs {token, value] terminated with 0 */ @@ -1544,7 +1484,7 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con }
X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL); - ret->ctx = create_glxcontext( gdi_display, ret, hShareContext ? hShareContext->ctx : NULL, + ret->ctx = create_glxcontext( ret, format, hShareContext ? hShareContext->ctx : NULL, attribList ? glx_attribs : NULL ); XSync(gdi_display, False); if ((err = X11DRV_check_error()) || !ret->ctx) @@ -1568,7 +1508,7 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, GLint max_level, GLsizei *width, GLsizei *height, void **private ) { - const struct glx_pixel_format *fmt; + const struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); int glx_attribs[7], count = 0; struct gl_drawable *surface; RECT rect; @@ -1576,13 +1516,6 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex 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, private );
- /* Convert the WGL pixelformat to a GLX format, if it fails then the format is invalid */ - if (!(fmt = get_pixel_format( gdi_display, format, TRUE /* Offscreen */ ))) - { - ERR( "(%p): invalid pixel format %d\n", hdc, format ); - return FALSE; - } - glx_attribs[count++] = GLX_PBUFFER_WIDTH; glx_attribs[count++] = *width; glx_attribs[count++] = GLX_PBUFFER_HEIGHT; @@ -1596,7 +1529,6 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex
if (!(surface = calloc( 1, sizeof(*surface) ))) return FALSE; surface->type = DC_GL_PBUFFER; - surface->format = fmt; surface->ref = 1;
surface->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 6 +++--- dlls/wineandroid.drv/opengl.c | 4 ++-- dlls/winemac.drv/opengl.c | 4 ++-- dlls/winewayland.drv/opengl.c | 4 ++-- dlls/winex11.drv/opengl.c | 14 +++++--------- include/wine/opengl_driver.h | 2 +- 6 files changed, 15 insertions(+), 19 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index b997ea4a8a8..50a81a22a52 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -401,7 +401,7 @@ static UINT egldrv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) return -1; /* use default implementation */ }
-static BOOL egldrv_context_create( HDC hdc, int format, void *share, const int *attribs, void **private ) +static BOOL egldrv_context_create( int format, void *share, const int *attribs, void **private ) { FIXME( "stub!\n" ); return TRUE; @@ -611,7 +611,7 @@ static UINT nulldrv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) return -1; /* use default implementation */ }
-static BOOL nulldrv_context_create( HDC hdc, int format, void *share, const int *attribs, void **private ) +static BOOL nulldrv_context_create( int format, void *share, const int *attribs, void **private ) { return FALSE; } @@ -848,7 +848,7 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, if (!(context = calloc( 1, sizeof(*context) ))) return NULL; context->pixel_format = format;
- if (!driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) + if (!driver_funcs->p_context_create( format, shared_private, attribs, &context->driver_private )) { free( context ); return NULL; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 60cdd419f62..9075e7d4ac2 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -205,7 +205,7 @@ static BOOL android_set_pixel_format( HWND hwnd, int old_format, int new_format, return TRUE; }
-static BOOL android_context_create( HDC hdc, int format, void *share, const int *attribs, void **private ) +static BOOL android_context_create( int format, void *share, const int *attribs, void **private ) { struct android_context *ctx, *shared_ctx = share; int count = 0, egl_attribs[3]; @@ -248,7 +248,7 @@ static BOOL android_context_create( HDC hdc, int format, void *share, const int ctx->surface = 0; ctx->refresh = FALSE; ctx->context = funcs->p_eglCreateContext( egl->display, ctx->config, shared_ctx ? shared_ctx->context : EGL_NO_CONTEXT, attribs ); - TRACE( "%p fmt %d ctx %p\n", hdc, format, ctx->context ); + TRACE( "fmt %d ctx %p\n", format, ctx->context ); list_add_head( &gl_contexts, &ctx->entry );
*private = ctx; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index c55ecc0976a..89e6adff3e4 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2190,7 +2190,7 @@ static UINT macdrv_pbuffer_bind(HDC hdc, void *private, GLenum source) * * WGL_ARB_create_context: wglCreateContextAttribsARB */ -static BOOL macdrv_context_create(HDC hdc, int format, void *shared, const int *attrib_list, void **private) +static BOOL macdrv_context_create(int format, void *shared, const int *attrib_list, void **private) { struct macdrv_context *share_context = shared; struct macdrv_context *context; @@ -2199,7 +2199,7 @@ static BOOL macdrv_context_create(HDC hdc, int format, void *shared, const int * BOOL core = FALSE; GLint renderer_id = 0;
- TRACE("hdc %p, format %d, share_context %p, attrib_list %p\n", hdc, format, share_context, attrib_list); + TRACE("format %d, share_context %p, attrib_list %p\n", format, share_context, attrib_list);
for (iptr = attrib_list; iptr && *iptr; iptr += 2) { diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 5b995f6b6ab..ce93fd1f432 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -356,12 +356,12 @@ static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, return TRUE; }
-static BOOL wayland_context_create(HDC hdc, int format, void *share_private, const int *attribs, void **private) +static BOOL wayland_context_create(int format, void *share_private, const int *attribs, void **private) { struct wayland_context *share = share_private, *ctx; EGLint egl_attribs[16], *attribs_end = egl_attribs;
- TRACE("hdc=%p format=%d share=%p attribs=%p\n", hdc, format, share, attribs); + TRACE("format=%d share=%p attribs=%p\n", format, share, attribs);
for (; attribs && attribs[0] != 0; attribs += 2) { diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3c0e7f08442..5f7cc9a9276 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -196,7 +196,6 @@ struct glx_pixel_format
struct x11drv_context { - HDC hdc; GLXContext ctx; struct gl_drawable *draw; struct gl_drawable *read; @@ -1342,7 +1341,6 @@ 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) { - ctx->hdc = draw_hdc; set_context_drawables( ctx, draw_gl, read_gl ); NtCurrentTeb()->glReserved2 = ctx; pthread_mutex_unlock( &context_mutex ); @@ -1397,7 +1395,6 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct gl_drawable *gl; - struct x11drv_context *ctx = private;
if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; if (gl->type != DC_GL_WINDOW) @@ -1417,7 +1414,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva update_gl_drawable_offscreen( gl ); pthread_mutex_unlock( &context_mutex );
- present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != funcs->p_glFinish ); + present_gl_drawable( hwnd, hdc, gl, TRUE, flush != funcs->p_glFinish ); release_gl_drawable( gl ); return TRUE; } @@ -1425,17 +1422,16 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva /*********************************************************************** * X11DRV_wglCreateContextAttribsARB */ -static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, const int *attribList, void **private ) +static BOOL x11drv_context_create( int format, void *share_private, const int *attribList, void **private ) { struct x11drv_context *ret, *hShareContext = share_private; int glx_attribs[16] = {0}, *pContextAttribList = glx_attribs; int err = 0;
- TRACE("(%p %d %p %p)\n", hdc, format, hShareContext, attribList); + TRACE("(%d %p %p)\n", format, hShareContext, attribList);
if ((ret = calloc( 1, sizeof(*ret) ))) { - ret->hdc = hdc; if (attribList) { /* attribList consists of pairs {token, value] terminated with 0 */ @@ -1500,7 +1496,7 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con pthread_mutex_unlock( &context_mutex ); }
- TRACE( "%p -> %p\n", hdc, ret ); + TRACE( "-> %p\n", ret ); *private = ret; return TRUE; } @@ -1731,7 +1727,7 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval update_gl_drawable_offscreen( gl ); pthread_mutex_unlock( &context_mutex );
- present_gl_drawable( hwnd, ctx ? ctx->hdc : hdc, gl, !pglXWaitForSbcOML, FALSE ); + present_gl_drawable( hwnd, hdc, gl, !pglXWaitForSbcOML, FALSE ); release_gl_drawable( gl ); return TRUE; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index b850f45215e..ff8f3e6e339 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -133,7 +133,7 @@ struct opengl_driver_funcs const char *(*p_init_wgl_extensions)(struct opengl_funcs *funcs); BOOL (*p_set_pixel_format)(HWND,int,int,BOOL); BOOL (*p_swap_buffers)(void*,HWND,HDC,int); - BOOL (*p_context_create)(HDC,int,void*,const int*,void**); + BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); BOOL (*p_context_flush)(void*,HWND,HDC,int,void(*)(void)); BOOL (*p_context_make_current)(HDC,HDC,void*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/opengl.c | 28 +++++++++++++++------------- dlls/winewayland.drv/opengl.c | 19 +++++++++---------- dlls/winex11.drv/opengl.c | 29 ++++++++++++++++++----------- include/wine/opengl_driver.h | 15 +++++++++++++++ 4 files changed, 57 insertions(+), 34 deletions(-)
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 9075e7d4ac2..ae1cf6fa3f8 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -67,10 +67,8 @@ struct android_context
struct gl_drawable { + struct opengl_drawable base; struct list entry; - HWND hwnd; - HDC hdc; - int format; ANativeWindow *window; EGLSurface surface; EGLSurface pbuffer; @@ -93,16 +91,20 @@ static inline EGLConfig egl_config_for_format(int format) 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 = malloc( sizeof(*gl) ); + struct gl_drawable *gl; + + if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL; + gl->base.hwnd = hwnd; + gl->base.hdc = hdc; + gl->base.format = format;
- gl->hwnd = hwnd; - gl->hdc = hdc; - gl->format = format; gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); gl->surface = 0; - gl->pbuffer = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->format), attribs ); + gl->pbuffer = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format(gl->base.format), attribs ); pthread_mutex_lock( &drawable_mutex ); list_add_head( &gl_drawables, &gl->entry ); + + TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; }
@@ -113,8 +115,8 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) pthread_mutex_lock( &drawable_mutex ); LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) { - if (hwnd && gl->hwnd == hwnd) return gl; - if (hdc && gl->hdc == hdc) return gl; + if (hwnd && gl->base.hwnd == hwnd) return gl; + if (hdc && gl->base.hdc == hdc) return gl; } pthread_mutex_unlock( &drawable_mutex ); return NULL; @@ -132,7 +134,7 @@ void destroy_gl_drawable( HWND hwnd ) pthread_mutex_lock( &drawable_mutex ); LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) { - if (gl->hwnd != hwnd) continue; + if (gl->base.hwnd != hwnd) continue; list_remove( &gl->entry ); if (gl->surface) funcs->p_eglDestroySurface( egl->display, gl->surface ); if (gl->pbuffer) funcs->p_eglDestroySurface( egl->display, gl->pbuffer ); @@ -164,7 +166,7 @@ void update_gl_drawable( HWND hwnd ) if ((gl = get_gl_drawable( hwnd, 0 ))) { if (!gl->surface && - (gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->format), + (gl->surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(gl->base.format), gl->window, NULL ))) { LIST_FOR_EACH_ENTRY( ctx, &gl_contexts, struct android_context, entry ) @@ -196,7 +198,7 @@ static BOOL android_set_pixel_format( HWND hwnd, int old_format, int new_format, EGLint pf; funcs->p_eglGetConfigAttrib( egl->display, egl_config_for_format(new_format), EGL_NATIVE_VISUAL_ID, &pf ); gl->window->perform( gl->window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, pf ); - gl->format = new_format; + gl->base.format = new_format; } } else gl = create_gl_drawable( hwnd, 0, new_format ); diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index ce93fd1f432..ea4c542d770 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -55,10 +55,9 @@ static struct list gl_contexts = LIST_INIT(gl_contexts);
struct wayland_gl_drawable { + struct opengl_drawable base; struct list entry; LONG ref; - HWND hwnd; - HDC hdc; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; @@ -97,8 +96,8 @@ 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->hwnd == hwnd) return gl; - if (hdc && gl->hdc == hdc) return gl; + if (hwnd && gl->base.hwnd == hwnd) return gl; + if (hdc && gl->base.hdc == hdc) return gl; } return NULL; } @@ -168,12 +167,12 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc } *attrib++ = EGL_NONE;
- gl = calloc(1, sizeof(*gl)); - if (!gl) return NULL; + if (!(gl = calloc(1, sizeof(*gl)))) return NULL; + gl->base.hwnd = hwnd; + gl->base.hdc = hdc; + gl->base.format = format;
gl->ref = 1; - gl->hwnd = hwnd; - gl->hdc = hdc; gl->swap_interval = 1;
/* Get the client surface for the HWND. If don't have a wayland surface @@ -198,7 +197,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc
gl->double_buffered = is_onscreen_format(format);
- TRACE("hwnd=%p egl_surface=%p\n", gl->hwnd, gl->surface); + TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->surface);
return gl;
@@ -241,7 +240,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl)
if (InterlockedCompareExchange(&gl->resized, FALSE, TRUE)) { - NtUserGetClientRect(gl->hwnd, &client_rect, NtUserGetDpiForWindow(gl->hwnd)); + 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; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 5f7cc9a9276..35c750c91f7 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -211,9 +211,9 @@ enum dc_gl_type
struct gl_drawable { + struct opengl_drawable base; LONG ref; /* reference count */ enum dc_gl_type type; /* type of GL surface */ - HWND hwnd; RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ Window window; /* window if drawable is a GLXWindow */ @@ -838,7 +838,7 @@ static void release_gl_drawable( struct gl_drawable *gl ) case DC_GL_WINDOW: TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); - destroy_client_window( gl->hwnd, gl->window ); + destroy_client_window( gl->base.hwnd, gl->window ); XFreeColormap( gdi_display, gl->colormap ); break; case DC_GL_PBUFFER: @@ -932,11 +932,13 @@ 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.hwnd = hwnd; + gl->base.hdc = 0; + gl->base.format = format;
/* 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->ref = 1; - gl->hwnd = hwnd; gl->rect = rect;
gl->type = DC_GL_WINDOW; @@ -945,7 +947,6 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); gl->window = create_client_window( hwnd, fmt->visual, gl->colormap ); if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, gl->window, NULL ); - TRACE( "%p created client %lx drawable %lx, format %d\n", hwnd, gl->window, gl->drawable, format );
if (!gl->drawable) { @@ -953,6 +954,8 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format ) return NULL; }
+ 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 )) release_gl_drawable( prev ); @@ -984,7 +987,7 @@ static void update_gl_drawable_size( struct gl_drawable *gl ) XWindowChanges changes; RECT rect;
- NtUserGetClientRect( gl->hwnd, &rect, NtUserGetDpiForWindow( gl->hwnd ) ); + NtUserGetClientRect( gl->base.hwnd, &rect, NtUserGetDpiForWindow( gl->base.hwnd ) ); if (EqualRect( &gl->rect, &rect )) return;
changes.width = min( max( 1, rect.right ), 65535 ); @@ -995,12 +998,12 @@ static void update_gl_drawable_size( struct gl_drawable *gl )
static void update_gl_drawable_offscreen( struct gl_drawable *gl ) { - BOOL offscreen = needs_offscreen_rendering( gl->hwnd ); + BOOL offscreen = needs_offscreen_rendering( gl->base.hwnd ); struct x11drv_win_data *data;
if (offscreen == gl->offscreen) { - if (!offscreen && (data = get_win_data( gl->hwnd ))) + if (!offscreen && (data = get_win_data( gl->base.hwnd ))) { attach_client_window( data, gl->window ); release_win_data( data ); @@ -1009,7 +1012,7 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) } gl->offscreen = offscreen;
- TRACE( "Moving hwnd %p client %lx drawable %lx %sscreen\n", gl->hwnd, gl->window, gl->drawable, offscreen ? "off" : "on" ); + TRACE( "Moving hwnd %p client %lx drawable %lx %sscreen\n", gl->base.hwnd, gl->window, gl->drawable, offscreen ? "off" : "on" );
if (!gl->offscreen) { @@ -1039,7 +1042,7 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) #endif }
- if ((data = get_win_data( gl->hwnd ))) + if ((data = get_win_data( gl->base.hwnd ))) { if (gl->offscreen) detach_client_window( data, gl->window ); else attach_client_window( data, gl->window ); @@ -1058,12 +1061,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->hwnd == hwnd) + if ((gl = context->draw) && gl->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); } - if ((gl = context->read) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + if ((gl = context->read) && gl->type == DC_GL_WINDOW && gl->base.hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); @@ -1524,6 +1527,10 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex glx_attribs[count++] = 0;
if (!(surface = calloc( 1, sizeof(*surface) ))) return FALSE; + surface->base.hwnd = 0; + surface->base.hdc = hdc; + surface->base.format = format; + surface->type = DC_GL_PBUFFER; surface->ref = 1;
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index ff8f3e6e339..cab2b8cc422 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -27,6 +27,7 @@ #include <wingdi.h>
#include "wine/wgl.h" +#include "wine/debug.h"
struct wgl_pixel_format { @@ -123,6 +124,20 @@ struct egl_platform BOOL has_EGL_EXT_pixel_format_float; };
+/* a driver opengl drawable, either a client surface of a pbuffer */ +struct opengl_drawable +{ + int format; /* pixel format of the drawable */ + HWND hwnd; /* window the drawable was created for */ + HDC hdc; /* DC the drawable was created for */ +}; + +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 ); +} + /* interface between win32u and the user drivers */ struct opengl_driver_funcs {
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 30 +++++++++--------- dlls/winemac.drv/opengl.c | 59 ++++++++++++++++++++++++----------- dlls/winewayland.drv/opengl.c | 23 ++++++++------ dlls/winex11.drv/opengl.c | 57 +++++++++++++++++---------------- include/wine/opengl_driver.h | 9 +++--- 5 files changed, 104 insertions(+), 74 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 50a81a22a52..404eec56d1a 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -50,7 +50,7 @@ struct wgl_context
struct wgl_pbuffer { - void *driver_private; + struct opengl_drawable *drawable;
HDC hdc; GLsizei width; @@ -377,25 +377,25 @@ static BOOL egldrv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval }
static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, void **private ) + GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ) { FIXME( "stub!\n" ); return FALSE; }
-static BOOL egldrv_pbuffer_destroy( HDC hdc, void *private ) +static BOOL egldrv_pbuffer_destroy( HDC hdc, struct opengl_drawable *drawable ) { FIXME( "stub!\n" ); return FALSE; }
-static BOOL egldrv_pbuffer_updated( HDC hdc, void *private, GLenum cube_face, GLint mipmap_level ) +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, void *private, GLenum buffer ) +static UINT egldrv_pbuffer_bind( HDC hdc, struct opengl_drawable *drawable, GLenum buffer ) { FIXME( "stub!\n" ); return -1; /* use default implementation */ @@ -591,22 +591,22 @@ static BOOL nulldrv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interva }
static BOOL nulldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, void **private ) + GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ) { return FALSE; }
-static BOOL nulldrv_pbuffer_destroy( HDC hdc, void *private ) +static BOOL nulldrv_pbuffer_destroy( HDC hdc, struct opengl_drawable *drawable ) { return FALSE; }
-static BOOL nulldrv_pbuffer_updated( HDC hdc, void *private, GLenum cube_face, GLint mipmap_level ) +static BOOL nulldrv_pbuffer_updated( HDC hdc, struct opengl_drawable *drawable, GLenum cube_face, GLint mipmap_level ) { return GL_TRUE; }
-static UINT nulldrv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) +static UINT nulldrv_pbuffer_bind( HDC hdc, struct opengl_drawable *drawable, GLenum buffer ) { return -1; /* use default implementation */ } @@ -1052,7 +1052,7 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int
if (driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, pbuffer->texture_target, max_level, &pbuffer->width, - &pbuffer->height, &pbuffer->driver_private )) + &pbuffer->height, &pbuffer->drawable )) return pbuffer;
failed: @@ -1068,7 +1068,7 @@ static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer )
TRACE( "pbuffer %p\n", pbuffer );
- driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->driver_private ); + driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->drawable ); if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); NtGdiDeleteObjectApp( pbuffer->hdc ); free( pbuffer ); @@ -1250,7 +1250,7 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) return GL_FALSE; }
- if ((ret = driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, source )) != -1) + if ((ret = driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->drawable, source )) != -1) return ret;
if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) @@ -1286,7 +1286,7 @@ static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffe return GL_FALSE; }
- return !!driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, GL_NONE ); + return !!driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->drawable, GL_NONE ); }
static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const int *attribs ) @@ -1344,8 +1344,8 @@ static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const in } }
- return driver_funcs->p_pbuffer_updated( pbuffer->hdc, pbuffer->driver_private, - pbuffer->cube_face, max( pbuffer->mipmap_level, 0 ) ); + return driver_funcs->p_pbuffer_updated( pbuffer->hdc, pbuffer->drawable, pbuffer->cube_face, + max( pbuffer->mipmap_level, 0 ) ); }
static int get_window_swap_interval( HWND hwnd ) diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 89e6adff3e4..00342e05382 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -80,6 +80,17 @@ struct macdrv_context UINT major; };
+struct gl_drawable +{ + struct opengl_drawable base; + CGLPBufferObj pbuffer; +}; + +static struct gl_drawable *impl_from_opengl_drawable(struct opengl_drawable *base) +{ + return CONTAINING_RECORD(base, struct gl_drawable, base); +} + static struct list context_list = LIST_INIT(context_list); static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -2163,13 +2174,14 @@ static void macdrv_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) * * WGL_ARB_render_texture: wglBindTexImageARB */ -static UINT macdrv_pbuffer_bind(HDC hdc, void *private, GLenum source) +static UINT macdrv_pbuffer_bind(HDC hdc, struct opengl_drawable *base, GLenum source) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; - CGLPBufferObj pbuffer = private; + struct gl_drawable *gl = impl_from_opengl_drawable(base); + CGLPBufferObj pbuffer = gl->pbuffer; CGLError err;
- TRACE("hdc %p pbuffer %p source 0x%x\n", hdc, pbuffer, source); + TRACE("hdc %p drawable %s source 0x%x\n", hdc, debugstr_opengl_drawable(base), source);
if (!context->draw_view && context->draw_pbuffer == pbuffer && source != GL_NONE) funcs->p_glFlush(); @@ -2355,12 +2367,13 @@ static BOOL macdrv_context_create(int format, void *shared, const int *attrib_li }
static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, void **private) + GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable) { + struct gl_drawable *gl; CGLError err;
- 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, private); + 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);
if (!texture_target || !texture_format) { @@ -2369,31 +2382,41 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text texture_format = GL_RGB; }
- err = CGLCreatePBuffer(*width, *height, texture_target, texture_format, max_level, (CGLPBufferObj *)private); + if (!(gl = calloc(1, sizeof(*gl)))) return FALSE; + gl->base.hwnd = 0; + gl->base.hdc = hdc; + gl->base.format = format; + + 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); return FALSE; }
pthread_mutex_lock(&dc_pbuffers_mutex); - CFDictionarySetValue(dc_pbuffers, hdc, private); + CFDictionarySetValue(dc_pbuffers, hdc, gl->pbuffer); pthread_mutex_unlock(&dc_pbuffers_mutex);
- TRACE(" -> %p\n", *private); + *drawable = &gl->base; + TRACE(" -> %p\n", gl); return TRUE; }
-static BOOL macdrv_pbuffer_destroy(HDC hdc, void *private) +static BOOL macdrv_pbuffer_destroy(HDC hdc, struct opengl_drawable *base) { - TRACE("private %p\n", private); + struct gl_drawable *gl = impl_from_opengl_drawable(base); + + TRACE("hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable(base));
pthread_mutex_lock(&dc_pbuffers_mutex); - CFDictionaryRemoveValue(dc_pbuffers, hdc); + CFDictionaryRemoveValue(dc_pbuffers, gl->pbuffer); pthread_mutex_unlock(&dc_pbuffers_mutex);
- CGLReleasePBuffer(private); - return GL_TRUE; + CGLReleasePBuffer(gl->pbuffer); + free(gl); + return TRUE; }
@@ -2695,13 +2718,13 @@ done: return ret; }
- -static BOOL macdrv_pbuffer_updated(HDC hdc, void *private, GLenum cube_face, GLint mipmap_level) +static BOOL macdrv_pbuffer_updated(HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; - CGLPBufferObj pbuffer = private; + struct gl_drawable *gl = impl_from_opengl_drawable(base); + CGLPBufferObj pbuffer = gl->pbuffer;
- TRACE("hdc %p pbuffer %p cube_face %#x mipmap_level %d\n", hdc, pbuffer, cube_face, mipmap_level); + TRACE("hdc %p drawable %s cube_face %#x mipmap_level %d\n", hdc, debugstr_opengl_drawable(base), cube_face, mipmap_level);
if (context && context->draw_pbuffer == pbuffer) { diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index ea4c542d770..cd66cde5485 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -66,6 +66,11 @@ struct wayland_gl_drawable BOOL double_buffered; };
+static struct wayland_gl_drawable *impl_from_opengl_drawable(struct opengl_drawable *base) +{ + return CONTAINING_RECORD(base, struct wayland_gl_drawable, base); +} + struct wayland_context { struct list entry; @@ -511,12 +516,12 @@ static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval }
static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, void **private) + 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, private); + 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; @@ -525,15 +530,15 @@ static BOOL wayland_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum tex list_add_head(&gl_drawables, &drawable->entry); pthread_mutex_unlock(&gl_object_mutex);
- *private = drawable; + *surface = &drawable->base; return TRUE; }
-static BOOL wayland_pbuffer_destroy(HDC hdc, void *private) +static BOOL wayland_pbuffer_destroy(HDC hdc, struct opengl_drawable *base) { - struct wayland_gl_drawable *drawable = private; + struct wayland_gl_drawable *drawable = impl_from_opengl_drawable(base);
- TRACE("hdc %p, private %p\n", hdc, private); + TRACE("hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable(base));
pthread_mutex_lock(&gl_object_mutex); list_remove(&drawable->entry); @@ -544,15 +549,13 @@ static BOOL wayland_pbuffer_destroy(HDC hdc, void *private) return GL_TRUE; }
-static BOOL wayland_pbuffer_updated(HDC hdc, void *private, GLenum cube_face, GLint mipmap_level) +static BOOL wayland_pbuffer_updated(HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level) { - TRACE("hdc %p, private %p, cube_face %#x, mipmap_level %d\n", hdc, private, cube_face, mipmap_level); return GL_TRUE; }
-static UINT wayland_pbuffer_bind(HDC hdc, void *private, GLenum buffer) +static UINT wayland_pbuffer_bind(HDC hdc, struct opengl_drawable *base, GLenum buffer) { - TRACE("hdc %p, private %p, buffer %#x\n", hdc, private, buffer); return -1; /* use default implementation */ }
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 35c750c91f7..0c34d858b0a 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -225,6 +225,11 @@ struct gl_drawable HDC hdc_dst; };
+static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) +{ + return CONTAINING_RECORD( base, struct gl_drawable, base ); +} + enum glx_swap_control_method { GLX_SWAP_CONTROL_NONE, @@ -1505,15 +1510,15 @@ static BOOL x11drv_context_create( int format, void *share_private, const int *a }
static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum texture_format, GLenum texture_target, - GLint max_level, GLsizei *width, GLsizei *height, void **private ) + GLint max_level, GLsizei *width, GLsizei *height, struct opengl_drawable **drawable ) { const struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); int glx_attribs[7], count = 0; - struct gl_drawable *surface; + struct gl_drawable *gl; RECT rect;
- 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, private ); + 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 );
glx_attribs[count++] = GLX_PBUFFER_WIDTH; glx_attribs[count++] = *width; @@ -1526,57 +1531,55 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } glx_attribs[count++] = 0;
- if (!(surface = calloc( 1, sizeof(*surface) ))) return FALSE; - surface->base.hwnd = 0; - surface->base.hdc = hdc; - surface->base.format = format; + if (!(gl = calloc( 1, sizeof(*gl) ))) return FALSE; + gl->base.hwnd = 0; + gl->base.hdc = hdc; + gl->base.format = format;
- surface->type = DC_GL_PBUFFER; - surface->ref = 1; + gl->type = DC_GL_PBUFFER; + gl->ref = 1;
- surface->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); - TRACE( "new Pbuffer drawable as %p (%lx)\n", surface, surface->drawable ); - if (!surface->drawable) + gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); + TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); + if (!gl->drawable) { - free( surface ); + free( gl ); return FALSE; } - pglXQueryDrawable( gdi_display, surface->drawable, GLX_WIDTH, (unsigned int *)width ); - pglXQueryDrawable( gdi_display, surface->drawable, GLX_HEIGHT, (unsigned int *)height ); + pglXQueryDrawable( gdi_display, gl->drawable, GLX_WIDTH, (unsigned int *)width ); + pglXQueryDrawable( gdi_display, gl->drawable, GLX_HEIGHT, (unsigned int *)height ); SetRect( &rect, 0, 0, *width, *height ); - set_dc_drawable( hdc, surface->drawable, &rect, IncludeInferiors ); + set_dc_drawable( hdc, gl->drawable, &rect, IncludeInferiors );
pthread_mutex_lock( &context_mutex ); - XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)surface ); + XSaveContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char *)gl ); pthread_mutex_unlock( &context_mutex );
- *private = surface; + *drawable = &gl->base; return TRUE; }
-static BOOL x11drv_pbuffer_destroy( HDC hdc, void *private ) +static BOOL x11drv_pbuffer_destroy( HDC hdc, struct opengl_drawable *base ) { - struct gl_drawable *surface = private; + struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "hdc %p, private %p\n", hdc, surface ); + TRACE( "hdc %p, drawable %s\n", hdc, debugstr_opengl_drawable( base ) );
pthread_mutex_lock( &context_mutex ); XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); pthread_mutex_unlock( &context_mutex ); - release_gl_drawable( surface ); + release_gl_drawable( gl );
return GL_TRUE; }
-static BOOL x11drv_pbuffer_updated( HDC hdc, void *private, GLenum cube_face, GLint mipmap_level ) +static BOOL x11drv_pbuffer_updated( HDC hdc, struct opengl_drawable *base, GLenum cube_face, GLint mipmap_level ) { - TRACE( "hdc %p, private %p, cube_face %#x, mipmap_level %d\n", hdc, private, cube_face, mipmap_level ); return GL_TRUE; }
-static UINT x11drv_pbuffer_bind( HDC hdc, void *private, GLenum buffer ) +static UINT x11drv_pbuffer_bind( HDC hdc, struct opengl_drawable *base, GLenum buffer ) { - TRACE( "hdc %p, private %p, buffer %#x\n", hdc, private, buffer ); return -1; /* use default implementation */ }
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index cab2b8cc422..4e2cb84c829 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -152,10 +152,11 @@ struct opengl_driver_funcs BOOL (*p_context_destroy)(void*); BOOL (*p_context_flush)(void*,HWND,HDC,int,void(*)(void)); BOOL (*p_context_make_current)(HDC,HDC,void*); - BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLenum,GLenum,GLint,GLsizei*,GLsizei*,void **); - BOOL (*p_pbuffer_destroy)(HDC,void*); - BOOL (*p_pbuffer_updated)(HDC,void*,GLenum,GLint); - UINT (*p_pbuffer_bind)(HDC,void*,GLenum); + 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 ); };
#endif /* WINE_UNIX_LIB */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/opengl.c | 36 ++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index ae1cf6fa3f8..13b798c35ec 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -68,6 +68,7 @@ struct android_context struct gl_drawable { struct opengl_drawable base; + LONG ref; struct list entry; ANativeWindow *window; EGLSurface surface; @@ -88,6 +89,12 @@ static inline EGLConfig egl_config_for_format(int format) return egl->configs[format - egl->config_count - 1]; }
+static struct gl_drawable *gl_drawable_grab( struct gl_drawable *gl ) +{ + InterlockedIncrement( &gl->ref ); + return gl; +} + 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 }; @@ -98,11 +105,13 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) gl->base.hdc = hdc; gl->base.format = format;
+ gl->ref = 1; 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 ); pthread_mutex_lock( &drawable_mutex ); list_add_head( &gl_drawables, &gl->entry ); + gl_drawable_grab( gl );
TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; @@ -115,16 +124,25 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) pthread_mutex_lock( &drawable_mutex ); LIST_FOR_EACH_ENTRY( gl, &gl_drawables, struct gl_drawable, entry ) { - if (hwnd && gl->base.hwnd == hwnd) return gl; - if (hdc && gl->base.hdc == hdc) return gl; + if (hwnd && gl->base.hwnd == hwnd) return gl_drawable_grab( gl ); + if (hdc && gl->base.hdc == hdc) return gl_drawable_grab( gl ); } pthread_mutex_unlock( &drawable_mutex ); return NULL; }
+static void gl_drawable_destroy( struct gl_drawable *gl ) +{ + 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 ) { - if (gl) pthread_mutex_unlock( &drawable_mutex ); + if (!InterlockedDecrement( &gl->ref )) gl_drawable_destroy( gl ); + pthread_mutex_unlock( &drawable_mutex ); }
void destroy_gl_drawable( HWND hwnd ) @@ -136,11 +154,7 @@ void destroy_gl_drawable( HWND hwnd ) { if (gl->base.hwnd != hwnd) continue; list_remove( &gl->entry ); - 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 ); - break; + return release_gl_drawable( gl ); } pthread_mutex_unlock( &drawable_mutex ); } @@ -201,7 +215,7 @@ static BOOL android_set_pixel_format( HWND hwnd, int old_format, int new_format, gl->base.format = new_format; } } - else gl = create_gl_drawable( hwnd, 0, new_format ); + else if (!(gl = create_gl_drawable( hwnd, 0, new_format ))) return FALSE; release_gl_drawable( gl );
return TRUE; @@ -295,8 +309,8 @@ static BOOL android_context_make_current( HDC draw_hdc, HDC read_hdc, void *priv RtlSetLastWin32Error( ERROR_INVALID_HANDLE );
done: - release_gl_drawable( read_gl ); - release_gl_drawable( draw_gl ); + if (read_gl) release_gl_drawable( read_gl ); + if (draw_gl) release_gl_drawable( draw_gl ); return ret; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 17 +++++++++++++ dlls/wineandroid.drv/opengl.c | 24 +++++++++++++----- dlls/winemac.drv/opengl.c | 3 +++ dlls/winewayland.drv/opengl.c | 38 +++++++++++++++------------ dlls/winex11.drv/opengl.c | 48 ++++++++++++++++++++--------------- include/wine/opengl_driver.h | 14 ++++++++++ 6 files changed, 101 insertions(+), 43 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 404eec56d1a..921f79a33a5 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -163,6 +163,23 @@ static void register_extension( char *list, size_t size, const char *name ) } }
+void opengl_drawable_add_ref( struct opengl_drawable *drawable ) +{ + ULONG ref = InterlockedIncrement( &drawable->ref ); + TRACE( "%s increasing refcount to %u\n", debugstr_opengl_drawable( drawable ), ref ); +} + +void opengl_drawable_release( struct opengl_drawable *drawable ) +{ + ULONG ref = InterlockedDecrement( &drawable->ref ); + TRACE( "%s decreasing refcount to %u\n", debugstr_opengl_drawable( drawable ), ref ); + + if (!ref) + { + drawable->funcs->destroy( drawable ); + } +} + #ifdef SONAME_LIBEGL
static void *egldrv_get_proc_address( const char *name ) diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 13b798c35ec..f0b3f76e64e 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(android);
static const struct egl_platform *egl; static const struct opengl_funcs *funcs; +static const struct opengl_drawable_funcs android_drawable_funcs; static const int egl_client_version = 2;
struct egl_pixel_format @@ -68,7 +69,6 @@ struct android_context struct gl_drawable { struct opengl_drawable base; - LONG ref; struct list entry; ANativeWindow *window; EGLSurface surface; @@ -76,6 +76,11 @@ struct gl_drawable int swap_interval; };
+static struct gl_drawable *impl_from_opengl_drawable( struct opengl_drawable *base ) +{ + return CONTAINING_RECORD( base, struct gl_drawable, base ); +} + static void *opengl_handle; static struct list gl_contexts = LIST_INIT( gl_contexts ); static struct list gl_drawables = LIST_INIT( gl_drawables ); @@ -91,7 +96,7 @@ static inline EGLConfig egl_config_for_format(int format)
static struct gl_drawable *gl_drawable_grab( struct gl_drawable *gl ) { - InterlockedIncrement( &gl->ref ); + opengl_drawable_add_ref( &gl->base ); return gl; }
@@ -101,17 +106,18 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format ) 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;
- gl->ref = 1; 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 ); pthread_mutex_lock( &drawable_mutex ); list_add_head( &gl_drawables, &gl->entry ); - gl_drawable_grab( gl ); + opengl_drawable_add_ref( &gl->base );
TRACE( "Created drawable %s with client window %p\n", debugstr_opengl_drawable( &gl->base ), gl->window ); return gl; @@ -131,8 +137,9 @@ static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) return NULL; }
-static void gl_drawable_destroy( struct gl_drawable *gl ) +static void android_drawable_destroy( struct opengl_drawable *base ) { + struct gl_drawable *gl = impl_from_opengl_drawable( base ); if (gl->surface) funcs->p_eglDestroySurface( egl->display, gl->surface ); if (gl->pbuffer) funcs->p_eglDestroySurface( egl->display, gl->pbuffer ); release_ioctl_window( gl->window ); @@ -141,7 +148,7 @@ static void gl_drawable_destroy( struct gl_drawable *gl )
static void release_gl_drawable( struct gl_drawable *gl ) { - if (!InterlockedDecrement( &gl->ref )) gl_drawable_destroy( gl ); + opengl_drawable_release( &gl->base ); pthread_mutex_unlock( &drawable_mutex ); }
@@ -405,6 +412,11 @@ static struct opengl_driver_funcs android_driver_funcs = .p_context_make_current = android_context_make_current, };
+static const struct opengl_drawable_funcs android_drawable_funcs = +{ + .destroy = android_drawable_destroy, +}; + /********************************************************************** * ANDROID_OpenGLInit */ diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 00342e05382..8fd32474c7c 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -100,6 +100,7 @@ static pthread_mutex_t dc_pbuffers_mutex = PTHREAD_MUTEX_INITIALIZER; static void *opengl_handle; static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs macdrv_driver_funcs; +static const struct opengl_drawable_funcs macdrv_drawable_funcs;
static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); @@ -2383,6 +2384,8 @@ 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.ref = 1; gl->base.hwnd = 0; gl->base.hdc = hdc; gl->base.format = format; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index cd66cde5485..9163f18058b 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -44,6 +44,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
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); @@ -57,7 +58,6 @@ struct wayland_gl_drawable { struct opengl_drawable base; struct list entry; - LONG ref; struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; EGLSurface surface; @@ -109,7 +109,7 @@ static struct wayland_gl_drawable *find_drawable(HWND hwnd, HDC hdc)
static struct wayland_gl_drawable *wayland_gl_drawable_acquire(struct wayland_gl_drawable *gl) { - InterlockedIncrement(&gl->ref); + opengl_drawable_add_ref(&gl->base); return gl; }
@@ -125,9 +125,9 @@ static struct wayland_gl_drawable *wayland_gl_drawable_get(HWND hwnd, HDC hdc) return ret; }
-static void wayland_gl_drawable_release(struct wayland_gl_drawable *gl) +static void wayland_drawable_destroy(struct opengl_drawable *base) { - if (InterlockedDecrement(&gl->ref)) return; + struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base); 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) @@ -173,11 +173,12 @@ 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;
- gl->ref = 1; gl->swap_interval = 1;
/* Get the client surface for the HWND. If don't have a wayland surface @@ -207,7 +208,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, HDC hdc return gl;
err: - wayland_gl_drawable_release(gl); + opengl_drawable_release(&gl->base); return NULL; }
@@ -235,7 +236,7 @@ static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *ne
pthread_mutex_unlock(&gl_object_mutex);
- if (old) wayland_gl_drawable_release(old); + if (old) opengl_drawable_release(&old->base); }
static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) @@ -305,8 +306,8 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva
pthread_mutex_unlock(&gl_object_mutex);
- if (old_draw) wayland_gl_drawable_release(old_draw); - if (old_read) wayland_gl_drawable_release(old_read); + if (old_draw) opengl_drawable_release(&old_draw->base); + if (old_read) opengl_drawable_release(&old_read->base);
return ret; } @@ -336,8 +337,8 @@ static void wayland_context_refresh(struct wayland_context *ctx)
pthread_mutex_unlock(&gl_object_mutex);
- if (old_draw) wayland_gl_drawable_release(old_draw); - if (old_read) wayland_gl_drawable_release(old_read); + if (old_draw) opengl_drawable_release(&old_draw->base); + if (old_read) opengl_drawable_release(&old_read->base); }
static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, BOOL internal) @@ -463,8 +464,8 @@ static BOOL wayland_context_destroy(void *private) list_remove(&ctx->entry); pthread_mutex_unlock(&gl_object_mutex); funcs->p_eglDestroyContext(egl->display, ctx->context); - if (ctx->draw) wayland_gl_drawable_release(ctx->draw); - if (ctx->read) wayland_gl_drawable_release(ctx->read); + if (ctx->draw) opengl_drawable_release(&ctx->draw->base); + if (ctx->read) opengl_drawable_release(&ctx->read->base); free(ctx); return TRUE; } @@ -510,7 +511,7 @@ static BOOL wayland_swap_buffers(void *private, HWND hwnd, HDC hdc, int interval if (gl->double_buffered) funcs->p_eglSwapBuffers(egl->display, gl->surface); wayland_gl_drawable_sync_size(gl);
- wayland_gl_drawable_release(gl); + opengl_drawable_release(&gl->base);
return TRUE; } @@ -544,7 +545,7 @@ static BOOL wayland_pbuffer_destroy(HDC hdc, struct opengl_drawable *base) list_remove(&drawable->entry); pthread_mutex_unlock(&gl_object_mutex);
- wayland_gl_drawable_release(drawable); + opengl_drawable_release(&drawable->base);
return GL_TRUE; } @@ -581,6 +582,11 @@ static struct opengl_driver_funcs wayland_driver_funcs = .p_pbuffer_bind = wayland_pbuffer_bind, };
+static const struct opengl_drawable_funcs wayland_drawable_funcs = +{ + .destroy = wayland_drawable_destroy, +}; + /********************************************************************** * WAYLAND_OpenGLInit */ @@ -628,7 +634,7 @@ void wayland_resize_gl_drawable(HWND hwnd) /* 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); - wayland_gl_drawable_release(gl); + opengl_drawable_release(&gl->base); }
#else /* No GL */ diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 0c34d858b0a..f7d2b484445 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -212,7 +212,6 @@ enum dc_gl_type struct gl_drawable { struct opengl_drawable base; - LONG ref; /* reference count */ enum dc_gl_type type; /* type of GL surface */ RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ @@ -351,6 +350,7 @@ 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;
/* check if the extension is present in the list */ static BOOL has_extension( const char *list, const char *ext ) @@ -831,13 +831,13 @@ static struct glx_pixel_format *glx_pixel_format_from_format( int format )
static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl ) { - InterlockedIncrement( &gl->ref ); + opengl_drawable_add_ref( &gl->base ); return gl; }
-static void release_gl_drawable( struct gl_drawable *gl ) +static void x11drv_drawable_destroy( struct opengl_drawable *base ) { - if (InterlockedDecrement( &gl->ref )) return; + struct gl_drawable *gl = impl_from_opengl_drawable(base); switch (gl->type) { case DC_GL_WINDOW: @@ -937,13 +937,14 @@ 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.ref = 1; gl->base.hwnd = hwnd; gl->base.hdc = 0; gl->base.format = format;
/* 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->ref = 1; gl->rect = rect;
gl->type = DC_GL_WINDOW; @@ -963,7 +964,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, int format )
pthread_mutex_lock( &context_mutex ); if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&prev )) - release_gl_drawable( prev ); + opengl_drawable_release( &prev->base ); XSaveContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char *)grab_gl_drawable(gl) ); pthread_mutex_unlock( &context_mutex ); return gl; @@ -982,7 +983,7 @@ static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format, if (!(gl = create_gl_drawable( hwnd, new_format ))) return FALSE; TRACE( "created GL drawable %lx for win %p\n", gl->drawable, hwnd); XFlush( gdi_display ); - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base );
return TRUE; } @@ -1092,7 +1093,7 @@ void destroy_gl_drawable( HWND hwnd ) if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) { XDeleteContext( gdi_display, (XID)hwnd, gl_hwnd_context ); - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base ); } pthread_mutex_unlock( &context_mutex ); } @@ -1299,8 +1300,8 @@ static BOOL x11drv_context_destroy(void *private) pthread_mutex_unlock( &context_mutex );
if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); - if (ctx->draw) release_gl_drawable( ctx->draw ); - if (ctx->read) release_gl_drawable( ctx->read ); + if (ctx->draw) opengl_drawable_release( &ctx->draw->base ); + if (ctx->read) opengl_drawable_release( &ctx->read->base ); free( ctx ); return TRUE; } @@ -1321,8 +1322,8 @@ static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawabl old_read = ctx->read; ctx->draw = grab_gl_drawable( draw ); ctx->read = read ? grab_gl_drawable( read ) : NULL; - if (old_draw) release_gl_drawable( old_draw ); - if (old_read) release_gl_drawable( old_read ); + if (old_draw) opengl_drawable_release( &old_draw->base ); + if (old_read) opengl_drawable_release( &old_read->base ); }
static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) @@ -1358,8 +1359,8 @@ static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva } RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); done: - if (read_gl) release_gl_drawable( read_gl ); - if (draw_gl) release_gl_drawable( draw_gl ); + if (read_gl) opengl_drawable_release( &read_gl->base ); + if (draw_gl) opengl_drawable_release( &draw_gl->base ); TRACE( "%p,%p,%p returning %d\n", draw_hdc, read_hdc, ctx, ret ); return ret; } @@ -1407,7 +1408,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; if (gl->type != DC_GL_WINDOW) { - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base ); return FALSE; }
@@ -1423,7 +1424,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva pthread_mutex_unlock( &context_mutex );
present_gl_drawable( hwnd, hdc, gl, TRUE, flush != funcs->p_glFinish ); - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base ); return TRUE; }
@@ -1532,13 +1533,13 @@ 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.ref = 1; gl->base.hwnd = 0; gl->base.hdc = hdc; gl->base.format = format;
gl->type = DC_GL_PBUFFER; - gl->ref = 1; - gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); if (!gl->drawable) @@ -1568,7 +1569,7 @@ static BOOL x11drv_pbuffer_destroy( HDC hdc, struct opengl_drawable *base ) pthread_mutex_lock( &context_mutex ); XDeleteContext( gdi_display, (XID)hdc, gl_pbuffer_context ); pthread_mutex_unlock( &context_mutex ); - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base );
return GL_TRUE; } @@ -1716,7 +1717,7 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval } if (gl->type != DC_GL_WINDOW) { - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base ); return FALSE; }
@@ -1738,7 +1739,7 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval pthread_mutex_unlock( &context_mutex );
present_gl_drawable( hwnd, hdc, gl, !pglXWaitForSbcOML, FALSE ); - release_gl_drawable( gl ); + opengl_drawable_release( &gl->base ); return TRUE; }
@@ -1760,6 +1761,11 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_pbuffer_bind = x11drv_pbuffer_bind, };
+static const struct opengl_drawable_funcs x11drv_drawable_funcs = +{ + .destroy = x11drv_drawable_destroy, +}; + #else /* no OpenGL includes */
/********************************************************************** diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 4e2cb84c829..5101525f744 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -61,6 +61,8 @@ struct wgl_pixel_format
#ifdef WINE_UNIX_LIB
+#include "wine/gdi_driver.h" + /* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ #define WINE_OPENGL_DRIVER_VERSION 36
@@ -125,8 +127,17 @@ struct egl_platform };
/* a driver opengl drawable, either a client surface of a pbuffer */ +struct opengl_drawable; +struct opengl_drawable_funcs +{ + void (*destroy)( struct opengl_drawable *iface ); +}; + struct opengl_drawable { + const struct opengl_drawable_funcs *funcs; + LONG ref; + int format; /* pixel format of the drawable */ HWND hwnd; /* window the drawable was created for */ HDC hdc; /* DC the drawable was created for */ @@ -138,6 +149,9 @@ 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_add_ref( struct opengl_drawable *drawable ); +W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable ); + /* interface between win32u and the user drivers */ struct opengl_driver_funcs {