[PATCH 0/5] MR9991: Draft: opengl32: Avoid using context HDC after context creation.
There's no guarantee that the HDCs are still valid. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 8 ++++---- dlls/opengl32/unix_thunks.c | 8 ++++---- dlls/opengl32/unix_wgl.c | 14 +++++++------- dlls/win32u/opengl.c | 34 +++++++++++++++++----------------- include/wine/opengl_driver.h | 10 +++++----- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index be1c67a9bfa..4448c1076ba 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -1630,12 +1630,12 @@ foreach (sort keys %wgl_functions) print OUT generate_null_func($_, $wgl_functions{$_}); } -printf OUT "static BOOL null_wgl_context_reset( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs )\n"; +printf OUT "static BOOL null_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs )\n"; printf OUT "{\n"; printf OUT " WARN( \"unsupported\\n\" );\n"; printf OUT " return FALSE;\n"; printf OUT "}\n"; -printf OUT "static BOOL null_wgl_context_flush( struct wgl_context *context, void (*flush)(void), UINT flags )\n"; +printf OUT "static BOOL null_context_flush( struct opengl_context *context, void (*flush)(void), UINT flags )\n"; printf OUT "{\n"; printf OUT " WARN( \"unsupported\\n\" );\n"; printf OUT " return FALSE;\n"; @@ -1655,8 +1655,8 @@ print OUT "\n"; print OUT "struct opengl_funcs null_opengl_funcs =\n"; print OUT "{\n"; -print OUT " .p_wgl_context_reset = null_wgl_context_reset,\n"; -print OUT " .p_wgl_context_flush = null_wgl_context_flush,\n"; +print OUT " .p_context_reset = null_context_reset,\n"; +print OUT " .p_context_flush = null_context_flush,\n"; print OUT " .p_get_pixel_formats = null_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 07314125675..83aba143ccc 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -89988,12 +89988,12 @@ static BOOL null_wglSwapBuffers( HDC hdc ) WARN( "unsupported\n" ); return 0; } -static BOOL null_wgl_context_reset( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ) +static BOOL null_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ) { WARN( "unsupported\n" ); return FALSE; } -static BOOL null_wgl_context_flush( struct wgl_context *context, void (*flush)(void), UINT flags ) +static BOOL null_context_flush( struct opengl_context *context, void (*flush)(void), UINT flags ) { WARN( "unsupported\n" ); return FALSE; @@ -91359,8 +91359,8 @@ static void null_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) struct opengl_funcs null_opengl_funcs = { - .p_wgl_context_reset = null_wgl_context_reset, - .p_wgl_context_flush = null_wgl_context_flush, + .p_context_reset = null_context_reset, + .p_context_flush = null_context_flush, .p_get_pixel_formats = null_get_pixel_formats, .p_wglCopyContext = null_wglCopyContext, .p_wglCreateContext = null_wglCreateContext, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 09b1bbf063b..73092486ce8 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -120,7 +120,7 @@ struct buffers struct context { - struct wgl_context base; + struct opengl_context base; HDC hdc; /* context creation DC */ HGLRC client; /* client-side context handle */ @@ -211,7 +211,7 @@ static void opengl_client_context_init( HGLRC client_context, struct context *co /* the current context is assumed valid and doesn't need locking */ static struct context *get_current_context( TEB *teb, struct opengl_drawable **draw, struct opengl_drawable **read ) { - struct wgl_context *base; + struct opengl_context *base; struct context *context; if (!(base = teb->glContext)) return NULL; @@ -382,7 +382,7 @@ static void release_buffers( const struct opengl_funcs *funcs, struct buffers *b static struct context *context_from_client_context( HGLRC client_context ) { - struct wgl_context *base = opengl_context_from_handle( client_context ); + struct opengl_context *base = opengl_context_from_handle( client_context ); return base ? CONTAINING_RECORD( base, struct context, base ) : NULL; } @@ -398,7 +398,7 @@ static struct context *update_context( TEB *teb, HGLRC client_context, struct co if (ctx->share == (HGLRC)-1) return ctx; /* not re-shared */ share = ctx->share ? get_updated_context( teb, ctx->share ) : NULL; - if (!funcs->p_wgl_context_reset( &ctx->base, ctx->hdc, share ? &share->base : NULL, ctx->attribs )) + if (!funcs->p_context_reset( &ctx->base, ctx->hdc, share ? &share->base : NULL, ctx->attribs )) { WARN( "Failed to re-create context for wglShareLists\n" ); return ctx; @@ -1326,7 +1326,7 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC client_context ) return FALSE; } - funcs->p_wgl_context_reset( &ctx->base, NULL, NULL, NULL ); + funcs->p_context_reset( &ctx->base, NULL, NULL, NULL ); free_context( ctx ); return TRUE; } @@ -1386,7 +1386,7 @@ static void flush_context( TEB *teb, void (*flush)(void) ) if (flush && ctx && !ctx->draw_fbo && context_draws_front( ctx ) && draw->client) flags |= GL_FLUSH_PRESENT; if ((flags & GL_FLUSH_PRESENT) && draw->buffer_map[0] == GL_BACK_LEFT) flags |= GL_FLUSH_FORCE_SWAP; - if (!ctx || !funcs->p_wgl_context_flush( &ctx->base, flush, flags )) + if (!ctx || !funcs->p_context_flush( &ctx->base, flush, flags )) { /* default implementation: call the functions directly */ if (flush) flush(); @@ -1519,7 +1519,7 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c } } - if (!(funcs->p_wgl_context_reset( &context->base, hdc, shared ? &shared->base : NULL, attribs ))) + if (!(funcs->p_context_reset( &context->base, hdc, shared ? &shared->base : NULL, attribs ))) { free_context( context ); return 0; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 8e5b708a500..e655b034cfe 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -152,7 +152,7 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) } } -static void opengl_drawable_set_context( struct opengl_drawable *drawable, struct wgl_context *context ) +static void opengl_drawable_set_context( struct opengl_drawable *drawable, struct opengl_context *context ) { if (!drawable->funcs->set_context) return; drawable->funcs->set_context( drawable, context ? context->driver_private : NULL ); @@ -1603,7 +1603,7 @@ static BOOL create_memory_pbuffer( HDC hdc ) return ret; } -static BOOL flush_memory_dc( struct wgl_context *context, HDC hdc, BOOL write, void (*flush)(void) ) +static BOOL flush_memory_dc( struct opengl_context *context, HDC hdc, BOOL write, void (*flush)(void) ) { const struct opengl_funcs *funcs = &display_funcs; BOOL ret = TRUE; @@ -1749,7 +1749,7 @@ static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max *num_onscreen_formats = onscreen_count; } -static void context_exchange_drawables( struct wgl_context *context, struct opengl_drawable **draw, struct opengl_drawable **read ) +static void context_exchange_drawables( struct opengl_context *context, struct opengl_drawable **draw, struct opengl_drawable **read ) { struct opengl_drawable *old_draw = context->draw, *old_read = context->read; context->draw = *draw; @@ -1758,7 +1758,7 @@ static void context_exchange_drawables( struct wgl_context *context, struct open *read = old_read; } -static BOOL context_unset_current( struct wgl_context *context ) +static BOOL context_unset_current( struct opengl_context *context ) { struct opengl_drawable *old_draw = context->draw, *old_read = context->read; @@ -1797,10 +1797,10 @@ static struct opengl_drawable *get_updated_drawable( HDC hdc, int format, struct return get_window_unused_drawable( hwnd, format ); } -static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, HDC read_hdc ) +static BOOL context_sync_drawables( struct opengl_context *context, HDC draw_hdc, HDC read_hdc ) { struct opengl_drawable *new_draw, *new_read, *old_draw = NULL, *old_read = NULL; - struct wgl_context *previous = NtCurrentTeb()->glContext; + struct opengl_context *previous = NtCurrentTeb()->glContext; BOOL ret = FALSE; if (!(new_draw = get_updated_drawable( draw_hdc, context->format, context->draw ))) return FALSE; @@ -1863,7 +1863,7 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H return ret; } -static void push_internal_context( struct wgl_context *context, HDC hdc, int format ) +static void push_internal_context( struct opengl_context *context, HDC hdc, int format ) { TRACE( "context %p, hdc %p\n", context, hdc ); @@ -1876,7 +1876,7 @@ static void push_internal_context( struct wgl_context *context, HDC hdc, int for driver_funcs->p_make_current( context->draw, context->read, context->internal_context ); } -static void pop_internal_context( struct wgl_context *context ) +static void pop_internal_context( struct opengl_context *context ) { TRACE( "context %p\n", context ); driver_funcs->p_make_current( context->draw, context->read, context->driver_private ); @@ -1884,8 +1884,8 @@ static void pop_internal_context( struct wgl_context *context ) static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, HGLRC client_context ) { - struct wgl_context *context = opengl_context_from_handle( client_context ); - struct wgl_context *prev_context = NtCurrentTeb()->glContext; + struct opengl_context *context = opengl_context_from_handle( client_context ); + struct opengl_context *prev_context = NtCurrentTeb()->glContext; BOOL created; int format; @@ -2259,7 +2259,7 @@ 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 ) +static BOOL win32u_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ) { void *share_private = share ? share->driver_private : NULL; int format; @@ -2300,7 +2300,7 @@ static BOOL win32u_wgl_context_reset( struct wgl_context *context, HDC hdc, stru static BOOL flush_memory_pbuffer( void (*flush)(void) ) { HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; - struct wgl_context *context = NtCurrentTeb()->glContext; + struct opengl_context *context = NtCurrentTeb()->glContext; BOOL created; TRACE( "context %p, draw_hdc %p, read_hdc %p, flush %p\n", context, draw_hdc, read_hdc, flush ); @@ -2311,7 +2311,7 @@ static BOOL flush_memory_pbuffer( void (*flush)(void) ) return flush_memory_dc( context, draw_hdc, FALSE, flush ); } -static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush)(void), UINT flags ) +static BOOL win32u_context_flush( struct opengl_context *context, void (*flush)(void), UINT flags ) { const struct opengl_funcs *funcs = &display_funcs; struct opengl_drawable *draw = context->draw; @@ -2336,7 +2336,7 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) static BOOL win32u_wglSwapBuffers( HDC hdc ) { - struct wgl_context *context = NtCurrentTeb()->glContext; + struct opengl_context *context = NtCurrentTeb()->glContext; const struct opengl_funcs *funcs = &display_funcs; struct opengl_drawable *draw; int interval; @@ -2411,7 +2411,7 @@ static void set_gl_error( GLenum error ) { const struct opengl_funcs *funcs = &display_funcs; struct opengl_client_context *client; - struct wgl_context *ctx; + struct opengl_context *ctx; if (!(ctx = NtCurrentTeb()->glContext)) return; if (!(client = opengl_client_context_from_client( ctx->client_context ))) return; @@ -2704,8 +2704,8 @@ static void display_funcs_init(void) 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; + display_funcs.p_context_reset = win32u_context_reset; + display_funcs.p_context_flush = win32u_context_flush; register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format" ); display_funcs.p_wglChoosePixelFormatARB = (void *)1; /* never called */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index f740303f4de..61c006270ba 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -99,7 +99,7 @@ struct __GLsync struct opengl_drawable; -struct wgl_context +struct opengl_context { HGLRC client_context; /* client side context pointer */ void *driver_private; /* driver context / private data */ @@ -109,10 +109,10 @@ struct wgl_context struct opengl_drawable *read; /* currently bound read surface */ }; -static inline struct wgl_context *opengl_context_from_handle( HGLRC client_context ) +static inline struct opengl_context *opengl_context_from_handle( HGLRC client_context ) { struct opengl_client_context *client = opengl_client_context_from_client( client_context ); - return client_context ? (struct wgl_context *)(UINT_PTR)client->unix_handle : NULL; + return client_context ? (struct opengl_context *)(UINT_PTR)client->unix_handle : NULL; } /* interface between opengl32 and win32u */ @@ -128,8 +128,8 @@ struct opengl_funcs #undef USE_GL_FUNC void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); BOOL (*p_query_renderer)( UINT attribute, void *value ); - BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void), UINT flags ); - BOOL (*p_wgl_context_reset)( struct wgl_context *context, HDC hdc, struct wgl_context *share, const int *attribs ); + BOOL (*p_context_flush)( struct opengl_context *context, void (*flush)(void), UINT flags ); + BOOL (*p_context_reset)( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ); void *egl_handle; }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 12 ------------ dlls/opengl32/unix_thunks.c | 12 ------------ dlls/opengl32/unix_wgl.c | 1 + 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 4448c1076ba..47785e3531a 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -1630,16 +1630,6 @@ foreach (sort keys %wgl_functions) print OUT generate_null_func($_, $wgl_functions{$_}); } -printf OUT "static BOOL null_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs )\n"; -printf OUT "{\n"; -printf OUT " WARN( \"unsupported\\n\" );\n"; -printf OUT " return FALSE;\n"; -printf OUT "}\n"; -printf OUT "static BOOL null_context_flush( struct opengl_context *context, void (*flush)(void), UINT flags )\n"; -printf OUT "{\n"; -printf OUT " WARN( \"unsupported\\n\" );\n"; -printf OUT " return FALSE;\n"; -printf OUT "}\n"; printf OUT "static void null_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats,\n"; printf OUT " UINT *num_formats, UINT *num_onscreen_formats )\n"; printf OUT "{\n"; @@ -1655,8 +1645,6 @@ print OUT "\n"; print OUT "struct opengl_funcs null_opengl_funcs =\n"; print OUT "{\n"; -print OUT " .p_context_reset = null_context_reset,\n"; -print OUT " .p_context_flush = null_context_flush,\n"; print OUT " .p_get_pixel_formats = null_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 83aba143ccc..16afcb68bc6 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -89988,16 +89988,6 @@ static BOOL null_wglSwapBuffers( HDC hdc ) WARN( "unsupported\n" ); return 0; } -static BOOL null_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ) -{ - WARN( "unsupported\n" ); - return FALSE; -} -static BOOL null_context_flush( struct opengl_context *context, void (*flush)(void), UINT flags ) -{ - WARN( "unsupported\n" ); - return FALSE; -} static void null_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ) { @@ -91359,8 +91349,6 @@ static void null_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) struct opengl_funcs null_opengl_funcs = { - .p_context_reset = null_context_reset, - .p_context_flush = null_context_flush, .p_get_pixel_formats = null_get_pixel_formats, .p_wglCopyContext = null_wglCopyContext, .p_wglCreateContext = null_wglCreateContext, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 73092486ce8..c5dbbd3e9fd 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1489,6 +1489,7 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c const struct opengl_funcs *funcs = get_dc_funcs( hdc ); struct context *context, *shared = get_updated_context( teb, client_shared ); + if (!funcs->p_context_reset) return 0; if (!(context = calloc( 1, sizeof(*context) ))) { RtlSetLastWin32Error( ERROR_OUTOFMEMORY ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/make_opengl | 7 ------- dlls/opengl32/unix_thunks.c | 7 ------- 2 files changed, 14 deletions(-) diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 47785e3531a..a8d8f51e3b0 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -1630,12 +1630,6 @@ foreach (sort keys %wgl_functions) print OUT generate_null_func($_, $wgl_functions{$_}); } -printf OUT "static void null_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats,\n"; -printf OUT " UINT *num_formats, UINT *num_onscreen_formats )\n"; -printf OUT "{\n"; -printf OUT " WARN( \"unsupported\\n\" );\n"; -printf OUT " *num_formats = *num_onscreen_formats = 0;\n"; -printf OUT "}\n"; foreach (sort keys %norm_functions) { next if defined $manual_win_functions{$_}; @@ -1645,7 +1639,6 @@ print OUT "\n"; print OUT "struct opengl_funcs null_opengl_funcs =\n"; print OUT "{\n"; -print OUT " .p_get_pixel_formats = null_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 16afcb68bc6..438d5705ea1 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -89988,12 +89988,6 @@ static BOOL null_wglSwapBuffers( HDC hdc ) WARN( "unsupported\n" ); return 0; } -static void null_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, - UINT *num_formats, UINT *num_onscreen_formats ) -{ - WARN( "unsupported\n" ); - *num_formats = *num_onscreen_formats = 0; -} static void null_glAccum( GLenum op, GLfloat value ) { WARN( "unsupported\n" ); @@ -91349,7 +91343,6 @@ static void null_glViewport( GLint x, GLint y, GLsizei width, GLsizei height ) struct opengl_funcs null_opengl_funcs = { - .p_get_pixel_formats = null_get_pixel_formats, .p_wglCopyContext = null_wglCopyContext, .p_wglCreateContext = null_wglCreateContext, .p_wglDeleteContext = null_wglDeleteContext, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
From: Rémi Bernon <rbernon@codeweavers.com> There's no guarantee that the HDC passed at context creation is still valid. --- dlls/opengl32/unix_wgl.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index c5dbbd3e9fd..053a5e46e0a 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -271,6 +271,10 @@ static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context struct context *old_ctx = CONTAINING_RECORD( teb->glContext, struct context, base ); HDC draw_hdc = teb->glReserved1[0], read_hdc = teb->glReserved1[1]; const struct opengl_funcs *old_funcs = teb->glTable, *funcs; + static const WCHAR staticW[] = {'s','t','a','t','i','c',0}; + UNICODE_STRING static_us = RTL_CONSTANT_STRING( staticW ); + HDC hdc = NULL; + HWND hwnd; if (dst == old_ctx || !(funcs = get_context_funcs( client_dst ))) { @@ -282,7 +286,17 @@ static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context if (src->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", client_src, src ); if (src != dst && dst->used == -1) FIXME( "Unsupported attributes on context %p/%p\n", client_dst, dst ); - funcs->p_wglMakeCurrent( dst->hdc, client_dst ); + if (!(hwnd = NtUserCreateWindowEx( 0, &static_us, NULL, &static_us, WS_POPUP, 0, 0, 0, 0, + NULL, NULL, NULL, NULL, 0, NULL, NULL, FALSE )) || + !(hdc = NtUserGetWindowDC( hwnd )) || !funcs->p_wglSetPixelFormat( hdc, dst->base.format, NULL )) + { + WARN( "Failed to create dummy window to update context attributes\n" ); + if (hdc) NtUserReleaseDC( hwnd, hdc ); + if (hwnd) NtUserDestroyWindow( hwnd ); + return FALSE; + } + + funcs->p_wglMakeCurrent( hdc, client_dst ); if (mask & GL_COLOR_BUFFER_BIT) { @@ -334,6 +348,9 @@ static BOOL copy_context_attributes( TEB *teb, HGLRC client_dst, struct context else if (!old_funcs->p_wglMakeContextCurrentARB) old_funcs->p_wglMakeCurrent( draw_hdc, old_ctx->client ); else old_funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, old_ctx->client ); + NtUserReleaseDC( hwnd, hdc ); + NtUserDestroyWindow( hwnd ); + return dst->used != -1 && src->used != -1; } @@ -959,13 +976,9 @@ PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR name ) BOOL wrap_wglCopyContext( TEB *teb, HGLRC client_src, HGLRC client_dst, UINT mask ) { struct context *src, *dst; - BOOL ret = FALSE; - if (!(src = get_updated_context( teb, client_src ))) return FALSE; if (!(dst = get_updated_context( teb, client_dst ))) return FALSE; - else ret = copy_context_attributes( teb, client_dst, dst, client_src, src, mask ); - - return ret; + return copy_context_attributes( teb, client_dst, dst, client_src, src, mask ); } static BOOL initialize_vk_device( TEB *teb, struct context *ctx ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/opengl32/unix_wgl.c | 10 +++----- dlls/win32u/opengl.c | 50 ++++++++++++++++++++++++------------ include/wine/opengl_driver.h | 4 ++- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 053a5e46e0a..2b05e48e726 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -122,7 +122,6 @@ struct context { struct opengl_context base; - HDC hdc; /* context creation DC */ HGLRC client; /* client-side context handle */ HGLRC share; /* context to be shared with */ int *attribs; /* creation attributes */ @@ -415,7 +414,7 @@ static struct context *update_context( TEB *teb, HGLRC client_context, struct co if (ctx->share == (HGLRC)-1) return ctx; /* not re-shared */ share = ctx->share ? get_updated_context( teb, ctx->share ) : NULL; - if (!funcs->p_context_reset( &ctx->base, ctx->hdc, share ? &share->base : NULL, ctx->attribs )) + if (!funcs->p_context_reset( &ctx->base, share ? &share->base : NULL, ctx->attribs )) { WARN( "Failed to re-create context for wglShareLists\n" ); return ctx; @@ -1339,7 +1338,7 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC client_context ) return FALSE; } - funcs->p_context_reset( &ctx->base, NULL, NULL, NULL ); + funcs->p_context_destroy( &ctx->base ); free_context( ctx ); return TRUE; } @@ -1502,14 +1501,13 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c const struct opengl_funcs *funcs = get_dc_funcs( hdc ); struct context *context, *shared = get_updated_context( teb, client_shared ); - if (!funcs->p_context_reset) return 0; + if (!funcs->p_context_create) return 0; if (!(context = calloc( 1, sizeof(*context) ))) { RtlSetLastWin32Error( ERROR_OUTOFMEMORY ); return 0; } context->base.client_context = client_context; - context->hdc = hdc; context->share = (HGLRC)-1; /* initial shared context */ context->attribs = memdup_attribs( attribs ); @@ -1533,7 +1531,7 @@ HGLRC wrap_wglCreateContextAttribsARB( TEB *teb, HDC hdc, HGLRC client_shared, c } } - if (!(funcs->p_context_reset( &context->base, hdc, shared ? &shared->base : NULL, attribs ))) + if (!(funcs->p_context_create( &context->base, hdc, shared ? &shared->base : NULL, attribs ))) { free_context( context ); return 0; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index e655b034cfe..3558b66c792 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -2259,26 +2259,13 @@ static int get_window_swap_interval( HWND hwnd ) return interval; } -static BOOL win32u_context_reset( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ) +static BOOL win32u_context_create( struct opengl_context *context, HDC hdc, struct opengl_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->internal_context) - { - driver_funcs->p_context_destroy( context->internal_context ); - context->internal_context = NULL; - } - 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 )) <= 0 && (format = get_window_pixel_format( NtUserWindowFromDC( hdc ) )) <= 0) { @@ -2293,10 +2280,39 @@ static BOOL win32u_context_reset( struct opengl_context *context, HDC hdc, struc } context->format = format; - TRACE( "reset context %p, format %u for driver context %p\n", context, format, context->driver_private ); + TRACE( "created context %p, format %u for driver context %p\n", context, format, context->driver_private ); + return TRUE; +} + +static BOOL win32u_context_destroy( struct opengl_context *context ) +{ + TRACE( "context %p\n", context ); + + if (context->internal_context) + { + driver_funcs->p_context_destroy( context->internal_context ); + context->internal_context = NULL; + } + 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; + return TRUE; } +static BOOL win32u_context_reset( struct opengl_context *context, struct opengl_context *share, const int *attribs ) +{ + void *share_private = share ? share->driver_private : NULL; + + TRACE( "context %p, share %p, attribs %p\n", context, share, attribs ); + + if (!win32u_context_destroy( context )) return FALSE; + return driver_funcs->p_context_create( context->format, share_private, attribs, &context->driver_private ); +} + static BOOL flush_memory_pbuffer( void (*flush)(void) ) { HDC draw_hdc = NtCurrentTeb()->glReserved1[0], read_hdc = NtCurrentTeb()->glReserved1[1]; @@ -2704,8 +2720,10 @@ static void display_funcs_init(void) display_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent; display_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - display_funcs.p_context_reset = win32u_context_reset; display_funcs.p_context_flush = win32u_context_flush; + display_funcs.p_context_create = win32u_context_create; + display_funcs.p_context_destroy = win32u_context_destroy; + display_funcs.p_context_reset = win32u_context_reset; register_extension( wgl_extensions, ARRAY_SIZE(wgl_extensions), "WGL_ARB_pixel_format" ); display_funcs.p_wglChoosePixelFormatARB = (void *)1; /* never called */ diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 61c006270ba..0ca0a4708fc 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -129,7 +129,9 @@ struct opengl_funcs void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); BOOL (*p_query_renderer)( UINT attribute, void *value ); BOOL (*p_context_flush)( struct opengl_context *context, void (*flush)(void), UINT flags ); - BOOL (*p_context_reset)( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ); + BOOL (*p_context_create)( struct opengl_context *context, HDC hdc, struct opengl_context *share, const int *attribs ); + BOOL (*p_context_destroy)( struct opengl_context *context ); + BOOL (*p_context_reset)( struct opengl_context *context, struct opengl_context *share, const int *attribs ); void *egl_handle; }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9991
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)