And some last bits of cleanup before that.
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 | 110 ++++++++++++++++++++++++++++++++-- dlls/winewayland.drv/opengl.c | 43 ++----------- 2 files changed, 108 insertions(+), 45 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 65318895a65..f7c4a2497f7 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -270,6 +270,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 ); @@ -282,7 +291,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; @@ -409,7 +417,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; @@ -478,19 +488,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 */ }
@@ -585,6 +657,32 @@ 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 void egldrv_pbuffer_detach( struct opengl_drawable *drawable ) +{ +} + +static void egldrv_pbuffer_flush( struct opengl_drawable *drawable, UINT flags ) +{ +} + +static BOOL egldrv_pbuffer_swap( struct opengl_drawable *drawable ) +{ + return FALSE; +} + +static const struct opengl_drawable_funcs egldrv_pbuffer_funcs = +{ + .destroy = egldrv_pbuffer_destroy, + .detach = egldrv_pbuffer_detach, + .flush = egldrv_pbuffer_flush, + .swap = egldrv_pbuffer_swap, +}; + 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 | 13 +++++++------ include/wine/opengl_driver.h | 5 ++--- 6 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index f7c4a2497f7..64c17a6ceb5 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -205,7 +205,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;
@@ -216,7 +216,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 @@ -542,7 +541,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 57b2ed23dd9..766700d9992 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 547608aa79f..14292649e80 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,8 +494,9 @@ 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), @@ -934,7 +936,7 @@ 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->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, @@ -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 );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 64c17a6ceb5..19a4e62711e 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -42,8 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl); struct wgl_context { void *driver_private; - int pixel_format; - struct opengl_drawable *draw; struct opengl_drawable *read; }; @@ -1012,12 +1010,13 @@ static struct opengl_drawable *get_dc_opengl_drawable( HDC hdc, BOOL read ) return drawable; }
-static BOOL create_memory_pbuffer( HDC hdc, int format ) +static BOOL create_memory_pbuffer( HDC hdc ) { const struct opengl_funcs *funcs = &display_funcs; dib_info dib = {.rect = {0, 0, 1, 1}}; BOOL ret = TRUE; BITMAPOBJ *bmp; + int format = 0; DC *dc;
if (!(dc = get_dc_ptr( hdc ))) return FALSE; @@ -1025,6 +1024,7 @@ static BOOL create_memory_pbuffer( HDC hdc, int format ) else if (get_gdi_object_type( hdc ) != NTGDI_OBJ_MEMDC) ret = FALSE; else if ((bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) { + format = dc->pixel_format; init_dib_info_from_bitmapobj( &dib, bmp ); GDI_ReleaseObj( dc->hBitmap ); } @@ -1161,8 +1161,6 @@ 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( format, shared_private, attribs, &context->driver_private )) { free( context ); @@ -1195,7 +1193,7 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H BOOL ret = FALSE, flush; HWND hwnd;
- flush = create_memory_pbuffer( draw_hdc, context->pixel_format ); + flush = create_memory_pbuffer( draw_hdc ); new_draw = get_dc_opengl_drawable( draw_hdc, FALSE ); new_read = get_dc_opengl_drawable( read_hdc, read_hdc != draw_hdc );
@@ -1264,12 +1262,6 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); return FALSE; } - if (context->pixel_format != format) - { - WARN( "Mismatched draw_hdc %p format %u, context %p format %u\n", draw_hdc, format, context, context->pixel_format ); - RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); - return FALSE; - }
if (!context_set_drawables( context, context->driver_private, draw_hdc, read_hdc, TRUE )) return FALSE; NtCurrentTeb()->glContext = context;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 126 +++++++++++++++++------------------ dlls/win32u/opengl.c | 111 +++++++++++------------------- include/wine/opengl_driver.h | 12 +++- 3 files changed, 111 insertions(+), 138 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 471eb4b9003..0ef73061e9c 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -110,8 +110,10 @@ struct hint_state GLenum perspective_correction; };
-struct opengl_context +struct context { + struct wgl_context base; + HDC hdc; /* context creation DC */ HGLRC share; /* context to be shared with */ int *attribs; /* creation attributes */ @@ -120,7 +122,6 @@ struct opengl_context UINT64 debug_user; /* client pointer */ GLubyte *extensions; /* extension string */ GLuint *disabled_exts; /* indices of disabled extensions */ - struct wgl_context *drv_ctx; /* driver context */ GLubyte *wow64_version; /* wow64 GL version override */
/* semi-stub state tracker for wglCopyContext */ @@ -139,7 +140,7 @@ struct wgl_handle const struct opengl_funcs *funcs; union { - struct opengl_context *context; /* for HANDLE_CONTEXT */ + struct wgl_context *context; /* for HANDLE_CONTEXT */ struct wgl_pbuffer *pbuffer; /* for HANDLE_PBUFFER */ GLsync sync; /* for HANDLE_GLSYNC */ struct wgl_handle *next; /* for free handles */ @@ -151,11 +152,16 @@ static struct wgl_handle wgl_handles[MAX_WGL_HANDLES]; static struct wgl_handle *next_free; static unsigned int handle_count;
+static struct context *context_from_wgl_context( struct wgl_context *context ) +{ + return CONTAINING_RECORD( context, struct context, base ); +} + /* the current context is assumed valid and doesn't need locking */ -static struct opengl_context *get_current_context( TEB *teb ) +static struct context *get_current_context( TEB *teb ) { if (!teb->glCurrentRC) return NULL; - return wgl_handles[LOWORD(teb->glCurrentRC) & ~HANDLE_TYPE_MASK].u.context; + return context_from_wgl_context( wgl_handles[LOWORD(teb->glCurrentRC) & ~HANDLE_TYPE_MASK].u.context ); }
static inline HANDLE next_handle( struct wgl_handle *ptr, enum wgl_handle_type type ) @@ -186,7 +192,7 @@ struct context_attribute_desc
static struct context_attribute_desc context_attributes[] = { -#define CONTEXT_ATTRIBUTE_DESC(bit, name, field) [name] = { bit, offsetof(struct opengl_context, field), sizeof(((struct opengl_context *)0)->field) } +#define CONTEXT_ATTRIBUTE_DESC(bit, name, field) [name] = { bit, offsetof(struct context, field), sizeof(((struct context *)0)->field) } CONTEXT_ATTRIBUTE_DESC( GL_COLOR_BUFFER_BIT, GL_COLOR_CLEAR_VALUE, color_buffer.clear_color ), CONTEXT_ATTRIBUTE_DESC( GL_DEPTH_BUFFER_BIT, GL_DEPTH_FUNC, depth_buffer.depth_func ), CONTEXT_ATTRIBUTE_DESC( GL_ENABLE_BIT, GL_CULL_FACE, enable.cull_face ), @@ -208,7 +214,7 @@ C_ASSERT( sizeof(context_attributes) <= 64 * 1024 );
void set_context_attribute( TEB *teb, GLenum name, const void *value, size_t size ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); GLbitfield bit;
if (!(ctx = get_current_context( teb ))) return; @@ -221,11 +227,11 @@ void set_context_attribute( TEB *teb, GLenum name, const void *value, size_t siz ctx->used |= bit; }
-static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, HGLRC dst_handle, struct opengl_context *dst, - HGLRC src_handle, struct opengl_context *src, GLbitfield mask ) +static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, HGLRC dst_handle, struct context *dst, + HGLRC src_handle, struct context *src, GLbitfield mask ) { HDC draw_hdc = teb->glReserved1[0], read_hdc = teb->glReserved1[1]; - struct opengl_context *old_ctx = get_current_context( teb ); + struct context *old_ctx = get_current_context( teb ); const struct opengl_funcs *old_funcs = teb->glTable;
if (dst == old_ctx) @@ -238,7 +244,7 @@ static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, if (src->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", src_handle, src ); if (src != dst && dst->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", dst_handle, dst );
- funcs->p_wglMakeCurrent( dst->hdc, dst->drv_ctx ); + funcs->p_wglMakeCurrent( dst->hdc, &dst->base );
if (mask & GL_COLOR_BUFFER_BIT) { @@ -287,46 +293,40 @@ static BOOL copy_context_attributes( TEB *teb, const struct opengl_funcs *funcs, dst->used |= (src->used & mask);
if (!old_ctx) funcs->p_wglMakeCurrent( NULL, NULL ); - else if (!old_funcs->p_wglMakeContextCurrentARB) old_funcs->p_wglMakeCurrent( draw_hdc, old_ctx->drv_ctx ); - else old_funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, old_ctx->drv_ctx ); + else if (!old_funcs->p_wglMakeContextCurrentARB) old_funcs->p_wglMakeCurrent( draw_hdc, &old_ctx->base ); + else old_funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, &old_ctx->base );
return dst->used != -1 && src->used != -1; }
-static struct opengl_context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs ); +static struct context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs );
/* update handle context if it has been re-shared with another one */ static void update_handle_context( TEB *teb, HGLRC handle, struct wgl_handle *ptr ) { - struct opengl_context *ctx = ptr->u.context, *shared; + struct context *ctx = context_from_wgl_context( ptr->u.context ), *shared; const struct opengl_funcs *funcs = ptr->funcs, *share_funcs; - struct wgl_context *(*func)( HDC hDC, struct wgl_context * hShareContext, const int *attribList ); - struct wgl_context *prev = ctx->drv_ctx, *drv_ctx;
if (ctx->tid) return; /* currently in use */ if (ctx->share == (HGLRC)-1) return; /* not re-shared */ - if (!(func = funcs->p_wglCreateContextAttribsARB)) func = (void *)funcs->p_wglGetProcAddress( "wglCreateContextAttribsARB" ); - if (!func) return; /* not supported */
shared = ctx->share ? opengl_context_from_handle( teb, ctx->share, &share_funcs ) : NULL; - if (!(drv_ctx = func( ctx->hdc, shared ? shared->drv_ctx : NULL, ctx->attribs ))) + if (!funcs->p_wgl_context_reset( &ctx->base, ctx->hdc, shared ? &shared->base : NULL, ctx->attribs )) { WARN( "Failed to re-create context for wglShareLists\n" ); return; } ctx->share = (HGLRC)-1; /* initial shared context */ - ctx->drv_ctx = drv_ctx; copy_context_attributes( teb, funcs, handle, ctx, handle, ctx, ctx->used ); - funcs->p_wglDeleteContext( prev ); }
-static struct opengl_context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs ) +static struct context *opengl_context_from_handle( TEB *teb, HGLRC handle, const struct opengl_funcs **funcs ) { struct wgl_handle *entry; if (!(entry = get_handle_ptr( handle ))) return NULL; update_handle_context( teb, handle, entry ); *funcs = entry->funcs; - return entry->u.context; + return context_from_wgl_context( entry->u.context ); }
static struct wgl_pbuffer *wgl_pbuffer_from_handle( HPBUFFERARB handle, const struct opengl_funcs **funcs ) @@ -701,7 +701,7 @@ static BOOL filter_extensions( TEB * teb, const char *extensions, GLubyte **exts
static const GLuint *disabled_extensions_index( TEB *teb ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); GLuint **disabled = &ctx->disabled_exts; if (*disabled || filter_extensions( teb, NULL, NULL, disabled )) return *disabled; return NULL; @@ -795,14 +795,14 @@ const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { if (name == GL_EXTENSIONS) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); GLubyte **extensions = &ctx->extensions; GLuint **disabled = &ctx->disabled_exts; if (*extensions || filter_extensions( teb, (const char *)ret, extensions, disabled )) return *extensions; } else if (name == GL_VERSION && is_win64 && is_wow64()) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); GLubyte **str = &ctx->wow64_version; int major, minor;
@@ -871,7 +871,7 @@ static char *build_extension_list( TEB *teb )
static UINT get_context_major_version( TEB *teb ) { - struct opengl_context *ctx; + struct context *ctx;
if (!(ctx = get_current_context( teb ))) return TRUE; for (const int *attr = ctx->attribs; attr && attr[0]; attr += 2) @@ -967,7 +967,7 @@ PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR name ) BOOL wrap_wglCopyContext( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct opengl_context *src, *dst; + struct context *src, *dst; BOOL ret = FALSE;
if (!(src = opengl_context_from_handle( teb, hglrcSrc, &src_funcs ))) return FALSE; @@ -980,27 +980,26 @@ BOOL wrap_wglCopyContext( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) HGLRC wrap_wglCreateContext( TEB *teb, HDC hdc ) { HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct opengl_context *context; + struct context *context; const struct opengl_funcs *funcs = get_dc_funcs( hdc );
if (!funcs) return 0; - if (!(drv_ctx = funcs->p_wglCreateContext( hdc ))) return 0; - if ((context = calloc( 1, sizeof(*context) ))) - { - context->hdc = hdc; - context->share = (HGLRC)-1; /* initial shared context */ - context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) free( context ); + if (!(context = calloc( 1, sizeof(*context) ))) return 0; + context->hdc = hdc; + context->share = (HGLRC)-1; /* initial shared context */ + if (!funcs->p_wgl_context_reset( &context->base, hdc, NULL, NULL )) free( context ); + else if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) + { + funcs->p_wgl_context_reset( &context->base, NULL, NULL, NULL ); + free( context ); } - if (!ret) funcs->p_wglDeleteContext( drv_ctx ); return ret; }
BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); - struct opengl_context *ctx, *prev = get_current_context( teb ); + struct context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (hglrc) @@ -1012,7 +1011,7 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) return FALSE; }
- if (!funcs->p_wglMakeCurrent( hdc, ctx->drv_ctx )) return FALSE; + if (!funcs->p_wglMakeCurrent( hdc, &ctx->base )) return FALSE; if (prev) prev->tid = 0; ctx->tid = tid; teb->glReserved1[0] = hdc; @@ -1040,18 +1039,18 @@ BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) { struct wgl_handle *ptr; - struct opengl_context *ctx; + struct context *ctx; DWORD tid = HandleToULong(teb->ClientId.UniqueThread);
if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; - ctx = ptr->u.context; + ctx = context_from_wgl_context( ptr->u.context ); if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; } if (hglrc == teb->glCurrentRC) wrap_wglMakeCurrent( teb, 0, 0 ); - ptr->funcs->p_wglDeleteContext( ctx->drv_ctx ); + ptr->funcs->p_wgl_context_reset( &ctx->base, NULL, NULL, NULL ); free( ctx->wow64_version ); free( ctx->disabled_exts ); free( ctx->extensions ); @@ -1063,10 +1062,10 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc )
static void flush_context( TEB *teb, void (*flush)(void) ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
- if (!ctx || !funcs->p_wgl_context_flush( ctx->drv_ctx, flush )) + if (!ctx || !funcs->p_wgl_context_flush( &ctx->base, flush )) { /* default implementation: call the functions directly */ if (flush) flush(); @@ -1130,7 +1129,7 @@ BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) BOOL wrap_wglShareLists( TEB *teb, HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct opengl_context *src, *dst; + struct context *src, *dst; BOOL ret = FALSE;
if (!(src = opengl_context_from_handle( teb, hglrcSrc, &src_funcs ))) return FALSE; @@ -1153,8 +1152,7 @@ BOOL wrap_wglBindTexImageARB( TEB *teb, HPBUFFERARB handle, int buffer ) HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int *attribs ) { HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct opengl_context *context, *share_ctx = NULL; + struct context *context, *share_ctx = NULL; const struct opengl_funcs *funcs = get_dc_funcs( hdc ), *share_funcs;
if (!funcs) @@ -1162,25 +1160,23 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC share, const int RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); return 0; } - if (!funcs->p_wglCreateContextAttribsARB) return 0; if (share && !(share_ctx = opengl_context_from_handle( teb, share, &share_funcs ))) { RtlSetLastWin32Error( ERROR_INVALID_OPERATION ); return 0; } - if ((drv_ctx = funcs->p_wglCreateContextAttribsARB( hdc, share_ctx ? share_ctx->drv_ctx : NULL, attribs ))) + if ((context = calloc( 1, sizeof(*context) ))) { - if ((context = calloc( 1, sizeof(*context) ))) + context->hdc = hdc; + context->share = (HGLRC)-1; /* initial shared context */ + context->attribs = memdup_attribs( attribs ); + if (!(funcs->p_wgl_context_reset( &context->base, hdc, share_ctx ? &share_ctx->base : NULL, attribs ))) free( context ); + else if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) { - context->hdc = hdc; - context->share = (HGLRC)-1; /* initial shared context */ - context->attribs = memdup_attribs( attribs ); - context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) free( context ); + funcs->p_wgl_context_reset( &context->base, NULL, NULL, NULL ); + free( context ); } - if (!ret) funcs->p_wglDeleteContext( drv_ctx ); } - return ret; }
@@ -1220,7 +1216,7 @@ HDC wrap_wglGetPbufferDCARB( TEB *teb, HPBUFFERARB handle ) BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); - struct opengl_context *ctx, *prev = get_current_context( teb ); + struct context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (hglrc) @@ -1233,7 +1229,7 @@ BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC }
if (!funcs->p_wglMakeContextCurrentARB) return FALSE; - if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ctx->drv_ctx )) return FALSE; + if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, &ctx->base )) return FALSE; if (prev) prev->tid = 0; ctx->tid = tid; teb->glReserved1[0] = draw_hdc; @@ -1290,7 +1286,7 @@ static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GL struct gl_debug_message_callback_params *params; void *ret_ptr; ULONG ret_len; - struct opengl_context *ctx = (struct opengl_context *)user; + struct context *ctx = (struct context *)user; UINT len = strlen( message ) + 1, size;
if (!ctx->debug_callback) return; @@ -1319,7 +1315,7 @@ static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GL
void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (!funcs->p_glDebugMessageCallback) return; @@ -1332,7 +1328,7 @@ void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const void *us
void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (!funcs->p_glDebugMessageCallbackAMD) return; @@ -1345,7 +1341,7 @@ void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, void *us
void wrap_glDebugMessageCallbackARB( TEB *teb, GLDEBUGPROCARB callback, const void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (!funcs->p_glDebugMessageCallbackARB) return; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 19a4e62711e..ae37402d32f 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -39,13 +39,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(wgl);
-struct wgl_context -{ - void *driver_private; - struct opengl_drawable *draw; - struct opengl_drawable *read; -}; - struct wgl_pbuffer { struct opengl_drawable *drawable; @@ -58,7 +51,7 @@ struct wgl_pbuffer GLint mipmap_level; GLenum cube_face;
- struct wgl_context *tmp_context; + void *tmp_context; struct wgl_context *prev_context; };
@@ -1030,7 +1023,7 @@ static BOOL create_memory_pbuffer( HDC hdc ) } release_dc_ptr( dc );
- if (ret) + if (ret && format) { int width = dib.rect.right - dib.rect.left, height = dib.rect.bottom - dib.rect.top; struct wgl_pbuffer *pbuffer; @@ -1146,47 +1139,6 @@ static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max *num_onscreen_formats = onscreen_count; }
-static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, const int *attribs ) -{ - void *shared_private = shared ? shared->driver_private : NULL; - struct wgl_context *context; - int format; - - TRACE( "hdc %p, shared %p, attribs %p\n", hdc, shared, attribs ); - - if ((format = get_dc_pixel_format( hdc, TRUE )) <= 0) - { - if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); - return NULL; - } - - if (!(context = calloc( 1, sizeof(*context) ))) return NULL; - if (!driver_funcs->p_context_create( format, shared_private, attribs, &context->driver_private )) - { - free( context ); - return NULL; - } - - TRACE( "created context %p, format %u for driver context %p\n", context, format, context->driver_private ); - return context; -} - -static struct wgl_context *win32u_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *shared, const int *attribs ) -{ - static const int empty_attribs = {0}; - - TRACE( "hdc %p, shared %p, attribs %p\n", hdc, shared, attribs ); - - if (!attribs) attribs = &empty_attribs; - return context_create( hdc, shared, attribs ); -} - -static struct wgl_context *win32u_wglCreateContext( HDC hdc ) -{ - TRACE( "hdc %p\n", hdc ); - return context_create( hdc, NULL, NULL ); -} - static BOOL context_set_drawables( struct wgl_context *context, void *private, HDC draw_hdc, HDC read_hdc, BOOL force ) { struct opengl_drawable *new_draw, *new_read, *old_draw = context->draw, *old_read = context->read; @@ -1229,18 +1181,6 @@ static BOOL context_set_drawables( struct wgl_context *context, void *private, H return ret; }
-static BOOL win32u_wglDeleteContext( struct wgl_context *context ) -{ - BOOL ret; - - TRACE( "context %p\n", context ); - - ret = driver_funcs->p_context_destroy( context->driver_private ); - free( context ); - - return ret; -} - static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context ) { struct wgl_context *prev_context = NtCurrentTeb()->glContext; @@ -1406,12 +1346,10 @@ failed:
static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer ) { - const struct opengl_funcs *funcs = &display_funcs; - TRACE( "pbuffer %p\n", pbuffer );
opengl_drawable_release( pbuffer->drawable ); - if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); + if (pbuffer->tmp_context) driver_funcs->p_context_destroy( pbuffer->tmp_context ); NtGdiDeleteObjectApp( pbuffer->hdc ); free( pbuffer );
@@ -1597,15 +1535,15 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer )
if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) { - if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); - pbuffer->tmp_context = funcs->p_wglCreateContextAttribsARB( pbuffer->hdc, prev_context, NULL ); + if (pbuffer->tmp_context) driver_funcs->p_context_destroy( pbuffer->tmp_context ); + driver_funcs->p_context_create( format, prev_context, NULL, &pbuffer->tmp_context ); pbuffer->prev_context = prev_context; }
funcs->p_glGetIntegerv( binding_from_target( pbuffer->texture_target ), &prev_texture );
/* Switch to our pbuffer */ - funcs->p_wglMakeCurrent( pbuffer->hdc, pbuffer->tmp_context ); + driver_funcs->p_make_current( pbuffer->drawable, pbuffer->drawable, pbuffer->tmp_context );
/* Make sure that the prev_texture is set as the current texture state isn't shared * between contexts. After that copy the pbuffer texture data. */ @@ -1702,6 +1640,36 @@ static int get_window_swap_interval( HWND hwnd ) return interval; }
+static BOOL win32u_wgl_context_reset( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ) +{ + void *share_private = share ? share->driver_private : NULL; + int format; + + TRACE( "context %p, hdc %p, share %p, attribs %p\n", context, hdc, share, attribs ); + + if (context->driver_private && !driver_funcs->p_context_destroy( context->driver_private )) + { + WARN( "Failed to destroy driver context %p\n", context->driver_private ); + return FALSE; + } + context->driver_private = NULL; + if (!hdc) return TRUE; + + if ((format = get_dc_pixel_format( hdc, TRUE )) <= 0) + { + if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + return FALSE; + } + if (!driver_funcs->p_context_create( format, share_private, attribs, &context->driver_private )) + { + WARN( "Failed to create driver context for context %p\n", context ); + return FALSE; + } + + TRACE( "reset context %p, format %u for driver context %p\n", context, format, context->driver_private ); + return TRUE; +} + static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void) ) { HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; @@ -1827,13 +1795,14 @@ static void display_funcs_init(void) display_funcs.p_wglGetPixelFormat = win32u_wglGetPixelFormat; display_funcs.p_wglSetPixelFormat = win32u_wglSetPixelFormat;
- display_funcs.p_wglCreateContext = win32u_wglCreateContext; - display_funcs.p_wglDeleteContext = win32u_wglDeleteContext; + display_funcs.p_wglCreateContext = (void *)1; /* never called */ + display_funcs.p_wglDeleteContext = (void *)1; /* never called */ display_funcs.p_wglCopyContext = (void *)1; /* never called */ display_funcs.p_wglShareLists = (void *)1; /* never called */ display_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
display_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; + display_funcs.p_wgl_context_reset = win32u_wgl_context_reset; display_funcs.p_wgl_context_flush = win32u_wgl_context_flush;
if (display_egl.has_EGL_EXT_pixel_format_float) @@ -1862,7 +1831,7 @@ static void display_funcs_init(void) register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context" ); register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context_no_error" ); register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_create_context_profile" ); - display_funcs.p_wglCreateContextAttribsARB = win32u_wglCreateContextAttribsARB; + display_funcs.p_wglCreateContextAttribsARB = (void *)1; /* never called */
register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_make_current_read" ); display_funcs.p_wglGetCurrentReadDCARB = (void *)1; /* never called */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 604bd6d6757..fb9dc36873e 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -66,12 +66,21 @@ struct wgl_pixel_format /* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ #define WINE_OPENGL_DRIVER_VERSION 36
+struct opengl_drawable; struct wgl_context; struct wgl_pbuffer;
+struct wgl_context +{ + void *driver_private; + struct opengl_drawable *draw; + struct opengl_drawable *read; +}; + /* interface between opengl32 and win32u */ struct opengl_funcs { + BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void) ); BOOL (*p_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ); struct wgl_context * (*p_wglCreateContext)( HDC hDc ); @@ -126,8 +135,6 @@ struct egl_platform BOOL has_EGL_EXT_pixel_format_float; };
-/* a driver opengl drawable, either a client surface of a pbuffer */ -struct opengl_drawable; struct opengl_drawable_funcs { void (*destroy)( struct opengl_drawable *iface ); @@ -146,6 +153,7 @@ struct opengl_drawable_funcs #define GL_FLUSH_INTERVAL 0x02 #define GL_FLUSH_UPDATED 0x04
+/* a driver opengl drawable, either a client surface of a pbuffer */ struct opengl_drawable { const struct opengl_drawable_funcs *funcs;