-- v2: win32u: Drop now unnecessary wglShareList implementation. opengl32: Implement wglShareLists directly. opengl32: Cache context creation attributes. opengl32: Share wgl_context struct definition with win32u. opengl32: Simplify wglMake(Context)Current control flow. opengl32: Move glFlush/glFinish hooking from win32u.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 15 +++++++++- dlls/opengl32/unix_thunks.c | 28 ++----------------- dlls/opengl32/unix_wgl.c | 53 ++++++++++++++++++++++++++++++++++++ dlls/win32u/opengl.c | 50 ++++------------------------------ include/wine/opengl_driver.h | 1 + 5 files changed, 76 insertions(+), 71 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index fa4983384a5..5fa0f449e27 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -195,6 +195,19 @@ my %manual_win_thunks = "wglQueryRendererStringWINE" => 1, "wglSwapBuffers" => 1, ); +my %manual_unix_thunks = + ( + "glDebugMessageCallback" => 1, + "glDebugMessageCallbackAMD" => 1, + "glDebugMessageCallbackARB" => 1, + "glFinish" => 1, + "glFlush" => 1, + "glGetIntegerv" => 1, + "glGetString" => 1, + "glGetStringi" => 1, + "wglGetProcAddress" => 1, + "wglSwapBuffers" => 1, + ); my %manual_wow64_thunks = ( "glClientWaitSync" => 1, @@ -742,7 +755,7 @@ sub needs_wrapper($$) { my ($name, $func) = @_;
- return 1 if $name =~ /^glDebugMessageCallback|^glGetString|^glGetIntegerv|^wglGetProcAddress/; + return 1 if defined $manual_unix_thunks{$name};
# check if return value needs special handling (my $type = $func->[0]->textContent()) =~ s/ $//; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 26f89bfc1eb..d79709e57e0 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -29,6 +29,9 @@ extern NTSTATUS wgl_wglDeleteContext( void *args ); extern NTSTATUS wgl_wglGetProcAddress( void *args ); extern NTSTATUS wgl_wglMakeCurrent( void *args ); extern NTSTATUS wgl_wglShareLists( void *args ); +extern NTSTATUS wgl_wglSwapBuffers( void *args ); +extern NTSTATUS gl_glFinish( void *args ); +extern NTSTATUS gl_glFlush( void *args ); extern NTSTATUS gl_glGetIntegerv( void *args ); extern NTSTATUS gl_glGetString( void *args ); extern NTSTATUS ext_glDebugMessageCallback( void *args ); @@ -64,15 +67,6 @@ static NTSTATUS wgl_wglSetPixelFormat( void *args ) return STATUS_SUCCESS; }
-static NTSTATUS wgl_wglSwapBuffers( void *args ) -{ - struct wglSwapBuffers_params *params = args; - const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); - if (!funcs || !funcs->p_wglSwapBuffers) return STATUS_NOT_IMPLEMENTED; - params->ret = funcs->p_wglSwapBuffers( params->hdc ); - return STATUS_SUCCESS; -} - static NTSTATUS gl_glAccum( void *args ) { struct glAccum_params *params = args; @@ -785,22 +779,6 @@ static NTSTATUS gl_glFeedbackBuffer( void *args ) return STATUS_SUCCESS; }
-static NTSTATUS gl_glFinish( void *args ) -{ - struct glFinish_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFinish(); - return STATUS_SUCCESS; -} - -static NTSTATUS gl_glFlush( void *args ) -{ - struct glFlush_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFlush(); - return STATUS_SUCCESS; -} - static NTSTATUS gl_glFogf( void *args ) { struct glFogf_params *params = args; diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index f143eb3cd07..3792e9cb11f 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -767,6 +767,59 @@ static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) return TRUE; }
+static void flush_context( TEB *teb, struct opengl_context *context, BOOL finish ) +{ + const struct opengl_funcs *funcs = teb->glTable; + HDC hdc = teb->glReserved1[0]; + + if (!funcs->p_wgl_context_flush( hdc, context->drv_ctx, finish )) + { + /* default implementation: call the functions directly */ + if (finish) funcs->p_glFinish(); + else funcs->p_glFlush(); + } +} + +NTSTATUS gl_glFinish( void *args ) +{ + struct glFinish_params *params = args; + const struct opengl_funcs *funcs = params->teb->glTable; + struct opengl_context *ctx = get_current_context( params->teb ); + + if (ctx) flush_context( params->teb, ctx, TRUE ); + else funcs->p_glFinish(); + + return STATUS_SUCCESS; +} + +NTSTATUS gl_glFlush( void *args ) +{ + struct glFlush_params *params = args; + const struct opengl_funcs *funcs = params->teb->glTable; + struct opengl_context *ctx = get_current_context( params->teb ); + + if (ctx) flush_context( params->teb, ctx, FALSE ); + else funcs->p_glFlush(); + + return STATUS_SUCCESS; +} + +NTSTATUS wgl_wglSwapBuffers( void *args ) +{ + struct wglSwapBuffers_params *params = args; + const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); + if (!funcs || !funcs->p_wglSwapBuffers) return STATUS_NOT_IMPLEMENTED; + + if (!(params->ret = funcs->p_wglSwapBuffers( params->hdc ))) + { + struct opengl_context *ctx = get_current_context( params->teb ); + /* default implementation: implicitly flush the context */ + if (ctx) flush_context( params->teb, ctx, FALSE ); + } + + return STATUS_SUCCESS; +} + static BOOL wrap_wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index e29fe97f4a7..c7d185cf130 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -45,10 +45,6 @@ struct wgl_context const struct opengl_funcs *funcs; void *driver_private; int pixel_format; - - /* hooked host function pointers */ - PFN_glFinish p_glFinish; - PFN_glFlush p_glFlush; };
struct wgl_pbuffer @@ -74,9 +70,6 @@ static struct egl_platform display_egl; static struct opengl_funcs display_funcs; static struct opengl_funcs memory_funcs;
-static PFN_glFinish p_memory_glFinish, p_display_glFinish; -static PFN_glFlush p_memory_glFlush, p_display_glFlush; - static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs );
static const struct @@ -1084,8 +1077,6 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, context->driver_funcs = driver_funcs; context->funcs = funcs; context->pixel_format = format; - context->p_glFinish = funcs == &display_funcs ? p_display_glFinish : p_memory_glFinish; - context->p_glFlush = funcs == &display_funcs ? p_display_glFlush : p_memory_glFlush;
if (!driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) { @@ -1612,9 +1603,8 @@ static int get_window_swap_interval( HWND hwnd ) return interval; }
-static void wgl_context_flush( struct wgl_context *context, BOOL finish ) +static BOOL win32u_wgl_context_flush( HDC hdc, struct wgl_context *context, BOOL finish ) { - HDC hdc = NtCurrentTeb()->glReserved1[0]; int interval; HWND hwnd;
@@ -1623,12 +1613,7 @@ static void wgl_context_flush( struct wgl_context *context, BOOL finish )
TRACE( "context %p, hwnd %p, hdc %p, interval %d, finish %u\n", context, hwnd, hdc, interval, finish );
- if (!context->driver_funcs->p_context_flush( context->driver_private, hwnd, hdc, interval, finish )) - { - /* default implementation: call the hooked functions */ - if (finish) context->p_glFinish(); - else context->p_glFlush(); - } + return context->driver_funcs->p_context_flush( context->driver_private, hwnd, hdc, interval, finish ); }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1649,14 +1634,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- if (!driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval )) - { - /* default implementation: implicitly flush the context */ - if (context) wgl_context_flush( context, FALSE ); - return FALSE; - } - - return TRUE; + return driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); }
static BOOL win32u_wglSwapIntervalEXT( int interval ) @@ -1705,18 +1683,6 @@ static int win32u_wglGetSwapIntervalEXT(void) return interval; }
-static void win32u_glFlush(void) -{ - struct wgl_context *context = NtCurrentTeb()->glContext; - if (context) wgl_context_flush( context, FALSE ); -} - -static void win32u_glFinish(void) -{ - struct wgl_context *context = NtCurrentTeb()->glContext; - if (context) wgl_context_flush( context, TRUE ); -} - static void init_opengl_funcs( struct opengl_funcs *funcs, const struct opengl_driver_funcs *driver_funcs ) { #define USE_GL_FUNC(func) \ @@ -1749,10 +1715,7 @@ static void memory_funcs_init(void) memory_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
memory_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - p_memory_glFinish = memory_funcs.p_glFinish; - memory_funcs.p_glFinish = win32u_glFinish; - p_memory_glFlush = memory_funcs.p_glFlush; - memory_funcs.p_glFlush = win32u_glFlush; + memory_funcs.p_wgl_context_flush = win32u_wgl_context_flush; }
static void display_funcs_init(void) @@ -1782,10 +1745,7 @@ static void display_funcs_init(void) display_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
display_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - p_display_glFinish = display_funcs.p_glFinish; - display_funcs.p_glFinish = win32u_glFinish; - p_display_glFlush = display_funcs.p_glFlush; - display_funcs.p_glFlush = win32u_glFlush; + display_funcs.p_wgl_context_flush = win32u_wgl_context_flush;
if (display_egl.has_EGL_EXT_pixel_format_float) { diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 2de585d8ce5..697b08fc99d 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -78,6 +78,7 @@ struct opengl_funcs BOOL (*p_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); BOOL (*p_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); BOOL (*p_wglSwapBuffers)( HDC hdc ); + BOOL (*p_wgl_context_flush)( HDC hdc, struct wgl_context *context, BOOL finish ); void (*p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); void * (*p_wglAllocateMemoryNV)( GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority ); BOOL (*p_wglBindTexImageARB)( struct wgl_pbuffer * hPbuffer, int iBuffer );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 69 +++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 39 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 3792e9cb11f..920c1fc535a 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -702,7 +702,6 @@ static HGLRC wrap_wglCreateContext( HDC hdc )
static BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) { - BOOL ret = TRUE; DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct opengl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable; @@ -710,38 +709,35 @@ static BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) if (hglrc) { if (!(ctx = opengl_context_from_handle( hglrc, &funcs ))) return FALSE; - if (!ctx->tid || ctx->tid == tid) - { - ret = funcs->p_wglMakeCurrent( hdc, ctx->drv_ctx ); - if (ret) - { - if (prev) prev->tid = 0; - ctx->tid = tid; - teb->glReserved1[0] = hdc; - teb->glReserved1[1] = hdc; - teb->glCurrentRC = hglrc; - teb->glTable = (void *)funcs; - } - } - else + if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); - ret = FALSE; + return FALSE; } + + if (!funcs->p_wglMakeCurrent( hdc, ctx->drv_ctx )) return FALSE; + if (prev) prev->tid = 0; + ctx->tid = tid; + teb->glReserved1[0] = hdc; + teb->glReserved1[1] = hdc; + teb->glCurrentRC = hglrc; + teb->glTable = (void *)funcs; + return TRUE; } - else if (prev) + if (prev) { if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; + return TRUE; } - else if (!hdc) + if (!hdc) { RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - ret = FALSE; + return FALSE; } - return ret; + return TRUE; }
static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) @@ -922,7 +918,6 @@ static HDC wrap_wglGetPbufferDCARB( HPBUFFERARB handle )
static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, HGLRC hglrc ) { - BOOL ret = TRUE; DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct opengl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable; @@ -930,34 +925,30 @@ static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, if (hglrc) { if (!(ctx = opengl_context_from_handle( hglrc, &funcs ))) return FALSE; - if (!ctx->tid || ctx->tid == tid) - { - ret = (funcs->p_wglMakeContextCurrentARB && - funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ctx->drv_ctx )); - if (ret) - { - if (prev) prev->tid = 0; - ctx->tid = tid; - teb->glReserved1[0] = draw_hdc; - teb->glReserved1[1] = read_hdc; - teb->glCurrentRC = hglrc; - teb->glTable = (void *)funcs; - } - } - else + if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); - ret = FALSE; + return FALSE; } + + if (!funcs->p_wglMakeContextCurrentARB) return FALSE; + if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ctx->drv_ctx )) return FALSE; + if (prev) prev->tid = 0; + ctx->tid = tid; + teb->glReserved1[0] = draw_hdc; + teb->glReserved1[1] = read_hdc; + teb->glCurrentRC = hglrc; + teb->glTable = (void *)funcs; + return TRUE; } - else if (prev) + if (prev) { if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; prev->tid = 0; teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; } - return ret; + return TRUE; }
static BOOL wrap_wglQueryPbufferARB( HPBUFFERARB handle, int attrib, int *value )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 121 +++++++++++++++-------------------- dlls/win32u/opengl.c | 34 ++++++---- include/wine/opengl_driver.h | 11 +++- 3 files changed, 83 insertions(+), 83 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 920c1fc535a..a68e9fa0b56 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -65,24 +65,13 @@ enum wgl_handle_type HANDLE_TYPE_MASK = 15 << 12, };
-struct opengl_context -{ - DWORD tid; /* thread that the context is current in */ - UINT64 debug_callback; /* client pointer */ - 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 */ -}; - struct wgl_handle { UINT 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 */ @@ -95,7 +84,7 @@ static struct wgl_handle *next_free; static unsigned int handle_count;
/* the current context is assumed valid and doesn't need locking */ -static struct opengl_context *get_current_context( TEB *teb ) +static struct wgl_context *get_current_context( TEB *teb ) { if (!teb->glCurrentRC) return NULL; return wgl_handles[LOWORD(teb->glCurrentRC) & ~HANDLE_TYPE_MASK].u.context; @@ -120,7 +109,7 @@ static struct wgl_handle *get_handle_ptr( HANDLE handle ) return NULL; }
-static struct opengl_context *opengl_context_from_handle( HGLRC handle, const struct opengl_funcs **funcs ) +static struct wgl_context *wgl_context_from_handle( HGLRC handle, const struct opengl_funcs **funcs ) { struct wgl_handle *entry; if (!(entry = get_handle_ptr( handle ))) return NULL; @@ -410,7 +399,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 wgl_context *ctx = get_current_context( teb ); GLuint **disabled = &ctx->disabled_exts; if (*disabled || filter_extensions( teb, NULL, NULL, disabled )) return *disabled; return NULL; @@ -504,14 +493,14 @@ static const GLubyte *wrap_glGetString( TEB *teb, GLenum name ) { if (name == GL_EXTENSIONS) { - struct opengl_context *ctx = get_current_context( teb ); + struct wgl_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 wgl_context *ctx = get_current_context( teb ); GLubyte **str = &ctx->wow64_version; int major, minor;
@@ -672,50 +661,45 @@ static PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR name ) static BOOL wrap_wglCopyContext( HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct opengl_context *src, *dst; + struct wgl_context *src, *dst; BOOL ret = FALSE;
- if (!(src = opengl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = opengl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; + if (!(src = wgl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; + if (!(dst = wgl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; if (src_funcs != dst_funcs) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - else ret = src_funcs->p_wglCopyContext( src->drv_ctx, dst->drv_ctx, mask ); + else ret = src_funcs->p_wglCopyContext( src, dst, mask ); return ret; }
static HGLRC wrap_wglCreateContext( HDC hdc ) { HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct opengl_context *context; + struct wgl_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->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( HANDLE_CONTEXT, funcs, context ))) free( context ); - } - if (!ret) funcs->p_wglDeleteContext( drv_ctx ); + if (!(context = funcs->p_wglCreateContext( hdc ))) return 0; + ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); + if (!ret) funcs->p_wglDeleteContext( context ); return ret; }
static 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 wgl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (hglrc) { - if (!(ctx = opengl_context_from_handle( hglrc, &funcs ))) return FALSE; + if (!(ctx = wgl_context_from_handle( hglrc, &funcs ))) return FALSE; if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; }
- if (!funcs->p_wglMakeCurrent( hdc, ctx->drv_ctx )) return FALSE; + if (!funcs->p_wglMakeCurrent( hdc, ctx )) return FALSE; if (prev) prev->tid = 0; ctx->tid = tid; teb->glReserved1[0] = hdc; @@ -743,7 +727,7 @@ static BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) { struct wgl_handle *ptr; - struct opengl_context *ctx; + struct wgl_context *ctx; DWORD tid = HandleToULong(teb->ClientId.UniqueThread);
if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; @@ -754,21 +738,20 @@ static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) return FALSE; } if (hglrc == teb->glCurrentRC) wrap_wglMakeCurrent( teb, 0, 0 ); - ptr->funcs->p_wglDeleteContext( ctx->drv_ctx ); free( ctx->wow64_version ); free( ctx->disabled_exts ); free( ctx->extensions ); - free( ctx ); + ptr->funcs->p_wglDeleteContext( ctx ); free_handle_ptr( ptr ); return TRUE; }
-static void flush_context( TEB *teb, struct opengl_context *context, BOOL finish ) +static void flush_context( TEB *teb, struct wgl_context *context, BOOL finish ) { const struct opengl_funcs *funcs = teb->glTable; HDC hdc = teb->glReserved1[0];
- if (!funcs->p_wgl_context_flush( hdc, context->drv_ctx, finish )) + if (!funcs->p_wgl_context_flush( hdc, context, finish )) { /* default implementation: call the functions directly */ if (finish) funcs->p_glFinish(); @@ -780,7 +763,7 @@ NTSTATUS gl_glFinish( void *args ) { struct glFinish_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; - struct opengl_context *ctx = get_current_context( params->teb ); + struct wgl_context *ctx = get_current_context( params->teb );
if (ctx) flush_context( params->teb, ctx, TRUE ); else funcs->p_glFinish(); @@ -792,7 +775,7 @@ NTSTATUS gl_glFlush( void *args ) { struct glFlush_params *params = args; const struct opengl_funcs *funcs = params->teb->glTable; - struct opengl_context *ctx = get_current_context( params->teb ); + struct wgl_context *ctx = get_current_context( params->teb );
if (ctx) flush_context( params->teb, ctx, FALSE ); else funcs->p_glFlush(); @@ -808,7 +791,7 @@ NTSTATUS wgl_wglSwapBuffers( void *args )
if (!(params->ret = funcs->p_wglSwapBuffers( params->hdc ))) { - struct opengl_context *ctx = get_current_context( params->teb ); + struct wgl_context *ctx = get_current_context( params->teb ); /* default implementation: implicitly flush the context */ if (ctx) flush_context( params->teb, ctx, FALSE ); } @@ -819,13 +802,13 @@ NTSTATUS wgl_wglSwapBuffers( void *args ) static BOOL wrap_wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct opengl_context *src, *dst; + struct wgl_context *src, *dst; BOOL ret = FALSE;
- if (!(src = opengl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = opengl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; + if (!(src = wgl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; + if (!(dst = wgl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; if (src_funcs != dst_funcs) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - else ret = src_funcs->p_wglShareLists( src->drv_ctx, dst->drv_ctx ); + else ret = src_funcs->p_wglShareLists( src, dst ); return ret; }
@@ -840,8 +823,7 @@ static BOOL wrap_wglBindTexImageARB( HPBUFFERARB handle, int buffer ) static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *attribs ) { HGLRC ret = 0; - struct wgl_context *drv_ctx; - struct opengl_context *context, *share_ctx = NULL; + struct wgl_context *context, *share_ctx = NULL; const struct opengl_funcs *funcs = get_dc_funcs( hdc ), *share_funcs;
if (!funcs) @@ -850,34 +832,31 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a return 0; } if (!funcs->p_wglCreateContextAttribsARB) return 0; - if (share && !(share_ctx = opengl_context_from_handle( share, &share_funcs ))) + + if (share && !(share_ctx = wgl_context_from_handle( 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 = funcs->p_wglCreateContextAttribsARB( hdc, share_ctx, attribs ))) { - if ((context = calloc( 1, sizeof(*context) ))) - { - enum wgl_handle_type type = HANDLE_CONTEXT; + enum wgl_handle_type type = HANDLE_CONTEXT;
- if (attribs) + if (attribs) + { + while (*attribs) { - while (*attribs) + if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) { - if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) - { - if (attribs[1] >= 3) type = HANDLE_CONTEXT_V3; - break; - } - attribs += 2; + if (attribs[1] >= 3) type = HANDLE_CONTEXT_V3; + break; } + attribs += 2; } - - context->drv_ctx = drv_ctx; - if (!(ret = alloc_handle( type, funcs, context ))) free( context ); } - if (!ret) funcs->p_wglDeleteContext( drv_ctx ); + + ret = alloc_handle( type, funcs, context ); + if (!ret) funcs->p_wglDeleteContext( context ); }
return ret; @@ -919,12 +898,12 @@ static HDC wrap_wglGetPbufferDCARB( HPBUFFERARB handle ) static 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 wgl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (hglrc) { - if (!(ctx = opengl_context_from_handle( hglrc, &funcs ))) return FALSE; + if (!(ctx = wgl_context_from_handle( hglrc, &funcs ))) return FALSE; if (ctx->tid && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); @@ -932,7 +911,7 @@ static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, }
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 )) return FALSE; if (prev) prev->tid = 0; ctx->tid = tid; teb->glReserved1[0] = draw_hdc; @@ -989,7 +968,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 wgl_context *ctx = (struct wgl_context *)user; UINT len = strlen( message ) + 1, size;
if (!ctx->debug_callback) return; @@ -1018,7 +997,7 @@ static void gl_debug_message_callback( GLenum source, GLenum type, GLuint id, GL
static void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct wgl_context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (!funcs->p_glDebugMessageCallback) return; @@ -1030,7 +1009,7 @@ static void wrap_glDebugMessageCallback( TEB *teb, GLDEBUGPROC callback, const v
static void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct wgl_context *ctx = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable;
if (!funcs->p_glDebugMessageCallbackAMD) return; @@ -1042,7 +1021,7 @@ static void wrap_glDebugMessageCallbackAMD( TEB *teb, GLDEBUGPROCAMD callback, v
static void wrap_glDebugMessageCallbackARB( TEB *teb, GLDEBUGPROCARB callback, const void *user ) { - struct opengl_context *ctx = get_current_context( teb ); + struct wgl_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 c7d185cf130..986178ceb8f 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -39,14 +39,20 @@
WINE_DEFAULT_DEBUG_CHANNEL(wgl);
-struct wgl_context +struct context { + struct wgl_context base; const struct opengl_driver_funcs *driver_funcs; const struct opengl_funcs *funcs; void *driver_private; int pixel_format; };
+static struct context *context_from_wgl_context( struct wgl_context *base ) +{ + return CONTAINING_RECORD( base, struct context, base ); +} + struct wgl_pbuffer { const struct opengl_driver_funcs *driver_funcs; @@ -1054,12 +1060,13 @@ static void win32u_memory_get_pixel_formats( struct wgl_pixel_format *formats, U *num_onscreen_formats = memory_onscreen_count; }
-static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, const int *attribs ) +static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared_base, const int *attribs ) { + struct context *shared = context_from_wgl_context( shared_base ); void *shared_private = shared ? shared->driver_private : NULL; const struct opengl_driver_funcs *driver_funcs; const struct opengl_funcs *funcs; - struct wgl_context *context; + struct context *context; int format;
TRACE( "hdc %p, shared %p, attribs %p\n", hdc, shared, attribs ); @@ -1085,7 +1092,7 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, }
TRACE( "created context %p, format %u for driver context %p\n", context, format, context->driver_private ); - return context; + return &context->base; }
static struct wgl_context *win32u_wglCreateContextAttribsARB( HDC hdc, struct wgl_context *shared, const int *attribs ) @@ -1104,8 +1111,9 @@ static struct wgl_context *win32u_wglCreateContext( HDC hdc ) return context_create( hdc, NULL, NULL ); }
-static BOOL win32u_wglDeleteContext( struct wgl_context *context ) +static BOOL win32u_wglDeleteContext( struct wgl_context *base ) { + struct context *context = context_from_wgl_context( base ); const struct opengl_driver_funcs *funcs = context->driver_funcs; BOOL ret;
@@ -1117,8 +1125,9 @@ static BOOL win32u_wglDeleteContext( struct wgl_context *context ) return ret; }
-static BOOL win32u_wglCopyContext( struct wgl_context *src, struct wgl_context *dst, UINT mask ) +static BOOL win32u_wglCopyContext( struct wgl_context *src_base, struct wgl_context *dst_base, UINT mask ) { + struct context *src = context_from_wgl_context( src_base ), *dst = context_from_wgl_context( dst_base ); const struct opengl_driver_funcs *funcs = src->driver_funcs;
TRACE( "src %p, dst %p, mask %#x\n", src, dst, mask ); @@ -1127,8 +1136,9 @@ static BOOL win32u_wglCopyContext( struct wgl_context *src, struct wgl_context * return funcs->p_context_copy( src->driver_private, dst->driver_private, mask ); }
-static BOOL win32u_wglShareLists( struct wgl_context *src, struct wgl_context *dst ) +static BOOL win32u_wglShareLists( struct wgl_context *src_base, struct wgl_context *dst_base ) { + struct context *src = context_from_wgl_context( src_base ), *dst = context_from_wgl_context( dst_base ); const struct opengl_driver_funcs *funcs = src->driver_funcs;
TRACE( "src %p, dst %p\n", src, dst ); @@ -1137,8 +1147,9 @@ static BOOL win32u_wglShareLists( struct wgl_context *src, struct wgl_context *d return funcs->p_context_share( src->driver_private, dst->driver_private ); }
-static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context ) +static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *base ) { + struct context *context = context_from_wgl_context( base ); const struct opengl_driver_funcs *funcs; int format;
@@ -1168,7 +1179,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct
funcs = context->driver_funcs; if (!funcs->p_context_make_current( draw_hdc, read_hdc, context->driver_private )) return FALSE; - NtCurrentTeb()->glContext = context; + NtCurrentTeb()->glContext = &context->base; return TRUE; }
@@ -1603,8 +1614,9 @@ static int get_window_swap_interval( HWND hwnd ) return interval; }
-static BOOL win32u_wgl_context_flush( HDC hdc, struct wgl_context *context, BOOL finish ) +static BOOL win32u_wgl_context_flush( HDC hdc, struct wgl_context *base, BOOL finish ) { + struct context *context = context_from_wgl_context( base ); int interval; HWND hwnd;
@@ -1618,7 +1630,7 @@ static BOOL win32u_wgl_context_flush( HDC hdc, struct wgl_context *context, BOOL
static BOOL win32u_wglSwapBuffers( HDC hdc ) { - struct wgl_context *context = NtCurrentTeb()->glContext; + struct context *context = context_from_wgl_context( NtCurrentTeb()->glContext ); const struct opengl_driver_funcs *driver_funcs; const struct opengl_funcs *funcs; int interval; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 697b08fc99d..b48f2351b17 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -63,7 +63,16 @@ struct wgl_pixel_format /* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ #define WINE_OPENGL_DRIVER_VERSION 35
-struct wgl_context; +struct wgl_context +{ + DWORD tid; /* thread that the context is current in */ + UINT64 debug_callback; /* client pointer */ + UINT64 debug_user; /* client pointer */ + GLubyte *extensions; /* extension string */ + GLuint *disabled_exts; /* indices of disabled extensions */ + GLubyte *wow64_version; /* wow64 GL version override */ +}; + struct wgl_pbuffer;
/* interface between opengl32 and win32u */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/unix_wgl.c | 70 ++++++++++++++++++++++-------------- include/wine/opengl_driver.h | 3 ++ 2 files changed, 47 insertions(+), 26 deletions(-)
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index a68e9fa0b56..f2cc34006e1 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -60,8 +60,7 @@ enum wgl_handle_type { HANDLE_PBUFFER = 0 << 12, HANDLE_CONTEXT = 1 << 12, - HANDLE_CONTEXT_V3 = 3 << 12, - HANDLE_GLSYNC = 4 << 12, + HANDLE_GLSYNC = 2 << 12, HANDLE_TYPE_MASK = 15 << 12, };
@@ -454,6 +453,19 @@ static BOOL check_extension_support( TEB *teb, const char *extension, const char return FALSE; }
+static int *memdup_attribs( const int *attribs ) +{ + const int *attr; + int *copy; + + if (!(attr = attribs)) return NULL; + while (*attr++) { /* nothing */ } + + if (!(copy = malloc( attr - attribs ))) return NULL; + memcpy( copy, attribs, (attr - attribs) * sizeof(*attr) ); + return copy; +} + static void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ) { const struct opengl_funcs *funcs = teb->glTable; @@ -567,20 +579,24 @@ static char *build_extension_list( TEB *teb ) return available_extensions; }
-static inline enum wgl_handle_type get_current_context_type( TEB *teb ) +static BOOL is_legacy_context( TEB *teb ) { - if (!teb->glCurrentRC) return HANDLE_CONTEXT; - return LOWORD(teb->glCurrentRC) & HANDLE_TYPE_MASK; + struct wgl_context *ctx; + + if (!(ctx = get_current_context( teb ))) return TRUE; + for (const int *attr = ctx->attribs; attr && attr[0]; attr += 2) + if (attr[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) return attr[1] < 3; + + return TRUE; }
/* Check if a GL extension is supported */ static BOOL is_extension_supported( TEB *teb, const char *extension ) { - enum wgl_handle_type type = get_current_context_type( teb ); char *available_extensions = NULL; BOOL ret = FALSE;
- if (type == HANDLE_CONTEXT) available_extensions = strdup( (const char *)wrap_glGetString( teb, GL_EXTENSIONS ) ); + if (is_legacy_context( teb )) available_extensions = strdup( (const char *)wrap_glGetString( teb, GL_EXTENSIONS ) ); if (!available_extensions) available_extensions = build_extension_list( teb );
if (!available_extensions) ERR( "No OpenGL extensions found, check if your OpenGL setup is correct!\n" ); @@ -679,6 +695,8 @@ static HGLRC wrap_wglCreateContext( HDC hdc )
if (!funcs) return 0; if (!(context = funcs->p_wglCreateContext( hdc ))) return 0; + context->hdc = hdc; + ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); if (!ret) funcs->p_wglDeleteContext( context ); return ret; @@ -741,6 +759,7 @@ static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) free( ctx->wow64_version ); free( ctx->disabled_exts ); free( ctx->extensions ); + free( ctx->attribs ); ptr->funcs->p_wglDeleteContext( ctx ); free_handle_ptr( ptr ); return TRUE; @@ -802,13 +821,23 @@ NTSTATUS wgl_wglSwapBuffers( void *args ) static BOOL wrap_wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) { const struct opengl_funcs *src_funcs, *dst_funcs; - struct wgl_context *src, *dst; + struct wgl_handle *src_ptr, *dst_ptr; BOOL ret = FALSE;
- if (!(src = wgl_context_from_handle( hglrcSrc, &src_funcs ))) return FALSE; - if (!(dst = wgl_context_from_handle( hglrcDst, &dst_funcs ))) return FALSE; + if (!(src_ptr = get_handle_ptr( hglrcSrc ))) return FALSE; + src_funcs = src_ptr->funcs; + if (!(dst_ptr = get_handle_ptr( hglrcDst ))) return FALSE; + dst_funcs = dst_ptr->funcs; + if (src_funcs != dst_funcs) RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - else ret = src_funcs->p_wglShareLists( src, dst ); + else + { + struct wgl_context *src = src_ptr->u.context, *dst = dst_ptr->u.context; + if (!src->share) src->share = hglrcDst; + if (!dst->share) dst->share = hglrcSrc; + ret = src_funcs->p_wglShareLists( src, dst ); + } + return ret; }
@@ -840,22 +869,11 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a } if ((context = funcs->p_wglCreateContextAttribsARB( hdc, share_ctx, attribs ))) { - enum wgl_handle_type type = HANDLE_CONTEXT; - - if (attribs) - { - while (*attribs) - { - if (attribs[0] == WGL_CONTEXT_MAJOR_VERSION_ARB) - { - if (attribs[1] >= 3) type = HANDLE_CONTEXT_V3; - break; - } - attribs += 2; - } - } + context->hdc = hdc; + context->share = share; + context->attribs = memdup_attribs( attribs );
- ret = alloc_handle( type, funcs, context ); + ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); if (!ret) funcs->p_wglDeleteContext( context ); }
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index b48f2351b17..656caa1754b 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -65,6 +65,9 @@ struct wgl_pixel_format
struct wgl_context { + HDC hdc; /* context creation DC */ + HGLRC share; /* context to be shared with */ + int *attribs; /* creation attributes */ DWORD tid; /* thread that the context is current in */ UINT64 debug_callback; /* client pointer */ UINT64 debug_user; /* client pointer */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/tests/opengl.c | 3 +- dlls/opengl32/unix_wgl.c | 61 ++++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 899b695e518..63e05a397f5 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1145,12 +1145,11 @@ static void test_sharelists(HDC winhdc) if (dest_sharing) { res = wglShareLists(other, dest); - todo_wine_if(source_sharing && dest_current) ok(res, "Sharing of display lists from other to dest failed\n"); }
res = wglShareLists(source, dest); - todo_wine_if((source_current || source_sharing) && (dest_current || dest_sharing)) + todo_wine_if(source_current && dest_current) ok(res || broken(nvidia && !source_sharing && dest_sharing), "Sharing of display lists from source to dest failed\n");
diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index f2cc34006e1..c80144c6a27 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -696,29 +696,52 @@ static HGLRC wrap_wglCreateContext( HDC hdc ) if (!funcs) return 0; if (!(context = funcs->p_wglCreateContext( hdc ))) return 0; context->hdc = hdc; + context->share = (HGLRC)-1; /* initial shared context */
ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); if (!ret) funcs->p_wglDeleteContext( context ); return ret; }
+static struct wgl_context *wgl_handle_update_context( struct wgl_handle *ptr, DWORD tid ) +{ + struct wgl_context *context, *prev = ptr->u.context, *shared; + const struct opengl_funcs *funcs = ptr->funcs, *share_funcs; + + if (!funcs->p_wglCreateContextAttribsARB) return prev; /* not supported */ + if (prev->share == (HGLRC)-1) return prev; /* hasn't been re-shared */ + + shared = prev->share ? wgl_context_from_handle( prev->share, &share_funcs ) : NULL; + if (!(context = funcs->p_wglCreateContextAttribsARB( prev->hdc, shared, prev->attribs ))) return prev; + *context = *prev; + funcs->p_wglDeleteContext( prev ); + + return context; +} + static BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) { DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct wgl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable; + struct wgl_handle *ptr;
if (hglrc) { - if (!(ctx = wgl_context_from_handle( hglrc, &funcs ))) return FALSE; - if (ctx->tid && ctx->tid != tid) + if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; + ctx = ptr->u.context; + funcs = ptr->funcs; + + if (ctx->tid && ctx->tid != -1 && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; } + /* update the context now with new shared context if it hasn't been current yet */ + if (!ctx->tid) ctx = wgl_handle_update_context( ptr, tid );
if (!funcs->p_wglMakeCurrent( hdc, ctx )) return FALSE; - if (prev) prev->tid = 0; + if (prev) prev->tid = -1; /* has been current */ ctx->tid = tid; teb->glReserved1[0] = hdc; teb->glReserved1[1] = hdc; @@ -729,7 +752,7 @@ static BOOL wrap_wglMakeCurrent( TEB *teb, HDC hdc, HGLRC hglrc ) if (prev) { if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; - prev->tid = 0; + prev->tid = -1; /* has been current */ teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; return TRUE; @@ -750,7 +773,7 @@ static BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc )
if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; ctx = ptr->u.context; - if (ctx->tid && ctx->tid != tid) + if (ctx->tid && ctx->tid != -1 && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; @@ -833,9 +856,15 @@ static BOOL wrap_wglShareLists( HGLRC hglrcSrc, HGLRC hglrcDst ) else { struct wgl_context *src = src_ptr->u.context, *dst = dst_ptr->u.context; - if (!src->share) src->share = hglrcDst; - if (!dst->share) dst->share = hglrcSrc; - ret = src_funcs->p_wglShareLists( src, dst ); + if (!src->tid) src->share = hglrcDst; + if (!dst->tid) dst->share = hglrcSrc; + if (src->share != hglrcDst && dst->share != hglrcSrc) + { + ERR( "Could not share display lists because both of the contexts have already been current\n" ); + RtlSetLastWin32Error( ERROR_BUSY ); + return FALSE; + } + ret = TRUE; }
return ret; @@ -870,7 +899,7 @@ static HGLRC wrap_wglCreateContextAttribsARB( HDC hdc, HGLRC share, const int *a if ((context = funcs->p_wglCreateContextAttribsARB( hdc, share_ctx, attribs ))) { context->hdc = hdc; - context->share = share; + context->share = (HGLRC)-1; /* initial shared context */ context->attribs = memdup_attribs( attribs );
ret = alloc_handle( HANDLE_CONTEXT, funcs, context ); @@ -918,19 +947,25 @@ static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, DWORD tid = HandleToULong(teb->ClientId.UniqueThread); struct wgl_context *ctx, *prev = get_current_context( teb ); const struct opengl_funcs *funcs = teb->glTable; + struct wgl_handle *ptr;
if (hglrc) { - if (!(ctx = wgl_context_from_handle( hglrc, &funcs ))) return FALSE; - if (ctx->tid && ctx->tid != tid) + if (!(ptr = get_handle_ptr( hglrc ))) return FALSE; + ctx = ptr->u.context; + funcs = ptr->funcs; + + if (ctx->tid && ctx->tid != -1 && ctx->tid != tid) { RtlSetLastWin32Error( ERROR_BUSY ); return FALSE; } + /* update the context now with new shared context if it hasn't been current yet */ + if (!ctx->tid) ctx = wgl_handle_update_context( ptr, tid );
if (!funcs->p_wglMakeContextCurrentARB) return FALSE; if (!funcs->p_wglMakeContextCurrentARB( draw_hdc, read_hdc, ctx )) return FALSE; - if (prev) prev->tid = 0; + if (prev) prev->tid = -1; /* has been current */ ctx->tid = tid; teb->glReserved1[0] = draw_hdc; teb->glReserved1[1] = read_hdc; @@ -941,7 +976,7 @@ static BOOL wrap_wglMakeContextCurrentARB( TEB *teb, HDC draw_hdc, HDC read_hdc, if (prev) { if (!funcs->p_wglMakeCurrent( 0, NULL )) return FALSE; - prev->tid = 0; + prev->tid = -1; /* has been current */ teb->glCurrentRC = 0; teb->glTable = &null_opengl_funcs; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 35 +------ dlls/wineandroid.drv/opengl.c | 7 -- dlls/winemac.drv/opengl.c | 55 ----------- dlls/winewayland.drv/opengl.c | 169 +++++++++++----------------------- dlls/winex11.drv/opengl.c | 75 +-------------- include/wine/opengl_driver.h | 1 - 6 files changed, 59 insertions(+), 283 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 986178ceb8f..06f64a11c47 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -429,12 +429,6 @@ static BOOL egldrv_context_copy( void *src_private, void *dst_private, UINT mask return FALSE; }
-static BOOL egldrv_context_share( void *src_private, void *dst_private ) -{ - FIXME( "stub!\n" ); - return FALSE; -} - static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { FIXME( "stub!\n" ); @@ -462,7 +456,6 @@ static const struct opengl_driver_funcs egldrv_funcs = .p_context_create = egldrv_context_create, .p_context_destroy = egldrv_context_destroy, .p_context_copy = egldrv_context_copy, - .p_context_share = egldrv_context_share, .p_context_flush = egldrv_context_flush, .p_context_make_current = egldrv_context_make_current, }; @@ -737,12 +730,6 @@ static BOOL osmesa_context_copy( void *src_private, void *dst_private, UINT mask return FALSE; }
-static BOOL osmesa_context_share( void *src_private, void *dst_private ) -{ - FIXME( "not supported yet\n" ); - return FALSE; -} - static BOOL osmesa_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) { struct osmesa_context *context = private; @@ -808,7 +795,6 @@ static const struct opengl_driver_funcs osmesa_driver_funcs = .p_context_create = osmesa_context_create, .p_context_destroy = osmesa_context_destroy, .p_context_copy = osmesa_context_copy, - .p_context_share = osmesa_context_share, .p_context_flush = osmesa_context_flush, .p_context_make_current = osmesa_context_make_current, }; @@ -891,11 +877,6 @@ static BOOL nulldrv_context_copy( void *src_private, void *dst_private, UINT mas return FALSE; }
-static BOOL nulldrv_context_share( void *src_private, void *dst_private ) -{ - return FALSE; -} - static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { return FALSE; @@ -921,7 +902,6 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_context_create = nulldrv_context_create, .p_context_destroy = nulldrv_context_destroy, .p_context_copy = nulldrv_context_copy, - .p_context_share = nulldrv_context_share, .p_context_flush = nulldrv_context_flush, .p_context_make_current = nulldrv_context_make_current, }; @@ -1136,17 +1116,6 @@ static BOOL win32u_wglCopyContext( struct wgl_context *src_base, struct wgl_cont return funcs->p_context_copy( src->driver_private, dst->driver_private, mask ); }
-static BOOL win32u_wglShareLists( struct wgl_context *src_base, struct wgl_context *dst_base ) -{ - struct context *src = context_from_wgl_context( src_base ), *dst = context_from_wgl_context( dst_base ); - const struct opengl_driver_funcs *funcs = src->driver_funcs; - - TRACE( "src %p, dst %p\n", src, dst ); - - if (funcs != dst->driver_funcs) return FALSE; - return funcs->p_context_share( src->driver_private, dst->driver_private ); -} - static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *base ) { struct context *context = context_from_wgl_context( base ); @@ -1723,7 +1692,7 @@ static void memory_funcs_init(void) memory_funcs.p_wglCreateContext = win32u_wglCreateContext; memory_funcs.p_wglDeleteContext = win32u_wglDeleteContext; memory_funcs.p_wglCopyContext = win32u_wglCopyContext; - memory_funcs.p_wglShareLists = win32u_wglShareLists; + memory_funcs.p_wglShareLists = (void *)1; /* never called */ memory_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
memory_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; @@ -1753,7 +1722,7 @@ static void display_funcs_init(void) display_funcs.p_wglCreateContext = win32u_wglCreateContext; display_funcs.p_wglDeleteContext = win32u_wglDeleteContext; display_funcs.p_wglCopyContext = win32u_wglCopyContext; - display_funcs.p_wglShareLists = win32u_wglShareLists; + display_funcs.p_wglShareLists = (void *)1; /* never called */ display_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent;
display_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 79204b5e277..ea426b5be86 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -335,12 +335,6 @@ static void *android_get_proc_address( const char *name ) return funcs->p_eglGetProcAddress( name ); }
-static BOOL android_context_share( void *org, void *dest ) -{ - FIXME( "%p %p\n", org, dest ); - return FALSE; -} - static void set_swap_interval( struct gl_drawable *gl, int interval ) { if (interval < 0) interval = -interval; @@ -401,7 +395,6 @@ static struct opengl_driver_funcs android_driver_funcs = .p_context_create = android_context_create, .p_context_destroy = android_context_destroy, .p_context_copy = android_context_copy, - .p_context_share = android_context_share, .p_context_flush = android_context_flush, .p_context_make_current = android_context_make_current, }; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 6eb9120fb59..f78f2318779 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -74,8 +74,6 @@ struct macdrv_context macdrv_view read_view; RECT read_rect; CGLPBufferObj read_pbuffer; - BOOL has_been_current; - BOOL sharing; int swap_interval; LONG view_moved; unsigned int last_flush_time; @@ -2483,7 +2481,6 @@ static BOOL macdrv_context_make_current(HDC draw_hdc, HDC read_hdc, void *privat context->read_view, wine_dbgstr_rect(&context->read_rect), context->read_pbuffer, context->format);
make_context_current(context, FALSE); - context->has_been_current = TRUE; NtCurrentTeb()->glReserved2 = context;
return TRUE; @@ -2973,57 +2970,6 @@ static BOOL macdrv_context_destroy(void *private) return TRUE; }
-static BOOL macdrv_context_share(void *src_private, void *dst_private) -{ - struct macdrv_context *org = src_private, *dest = dst_private; - macdrv_opengl_context saved_context; - CGLContextObj saved_cglcontext; - - TRACE("org %p dest %p\n", org, dest); - - /* Sharing of display lists works differently in Mac OpenGL and WGL. In Mac OpenGL it is done - * at context creation time but in case of WGL it is done using wglShareLists. - * - * The approach is to create a Mac OpenGL context in wglCreateContext / wglCreateContextAttribsARB - * and when a program requests sharing we recreate the destination context if it hasn't been made - * current or when it hasn't shared display lists before. - */ - - if (dest->has_been_current) - { - WARN("could not share display lists, the destination context has been current already\n"); - return FALSE; - } - else if (dest->sharing) - { - WARN("could not share display lists because dest has already shared lists before\n"); - return FALSE; - } - - /* Re-create the Mac context and share display lists */ - saved_context = dest->context; - saved_cglcontext = dest->cglcontext; - dest->context = NULL; - dest->cglcontext = NULL; - if (!create_context(dest, org->cglcontext, dest->major)) - { - dest->context = saved_context; - dest->cglcontext = saved_cglcontext; - return FALSE; - } - - /* Implicitly disposes of saved_cglcontext. */ - macdrv_dispose_opengl_context(saved_context); - - TRACE("re-created OpenGL context %p/%p/%p sharing lists with context %p/%p/%p\n", - dest, dest->context, dest->cglcontext, org, org->context, org->cglcontext); - - org->sharing = TRUE; - dest->sharing = TRUE; - - return TRUE; -} - static void *macdrv_get_proc_address(const char *name) { /* redirect some standard OpenGL functions */ @@ -3105,7 +3051,6 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_context_create = macdrv_context_create, .p_context_destroy = macdrv_context_destroy, .p_context_copy = macdrv_context_copy, - .p_context_share = macdrv_context_share, .p_context_flush = macdrv_context_flush, .p_context_make_current = macdrv_context_make_current, .p_pbuffer_create = macdrv_pbuffer_create, diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index dfda1972dcf..3cc510eecf9 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -73,9 +73,6 @@ struct wayland_context EGLConfig config; EGLContext context; struct wayland_gl_drawable *draw, *read, *new_draw, *new_read; - EGLint attribs[16]; - BOOL has_been_current; - BOOL sharing; };
struct wgl_pbuffer @@ -294,7 +291,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva ctx->draw = draw; ctx->read = read; ctx->new_draw = ctx->new_read = NULL; - ctx->has_been_current = TRUE; NtCurrentTeb()->glReserved2 = ctx; } else @@ -311,68 +307,6 @@ static BOOL wayland_context_make_current(HDC draw_hdc, HDC read_hdc, void *priva return ret; }
-static BOOL wayland_context_populate_attribs(struct wayland_context *ctx, const int *wgl_attribs) -{ - EGLint *attribs_end = ctx->attribs; - - if (!wgl_attribs) goto out; - - for (; wgl_attribs[0] != 0; wgl_attribs += 2) - { - EGLint name; - - TRACE("%#x %#x\n", wgl_attribs[0], wgl_attribs[1]); - - /* Find the EGL attribute names corresponding to the WGL names. - * For all of the attributes below, the values match between the two - * systems, so we can use them directly. */ - switch (wgl_attribs[0]) - { - case WGL_CONTEXT_MAJOR_VERSION_ARB: - name = EGL_CONTEXT_MAJOR_VERSION_KHR; - break; - case WGL_CONTEXT_MINOR_VERSION_ARB: - name = EGL_CONTEXT_MINOR_VERSION_KHR; - break; - case WGL_CONTEXT_FLAGS_ARB: - name = EGL_CONTEXT_FLAGS_KHR; - break; - case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: - name = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; - break; - case WGL_CONTEXT_PROFILE_MASK_ARB: - if (wgl_attribs[1] & WGL_CONTEXT_ES2_PROFILE_BIT_EXT) - { - ERR("OpenGL ES contexts are not supported\n"); - return FALSE; - } - name = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; - break; - default: - name = EGL_NONE; - FIXME("Unhandled attributes: %#x %#x\n", wgl_attribs[0], wgl_attribs[1]); - } - - if (name != EGL_NONE) - { - EGLint *dst = ctx->attribs; - /* Check if we have already set the same attribute and replace it. */ - for (; dst != attribs_end && *dst != name; dst += 2) continue; - /* Our context attribute array should have enough space for all the - * attributes we support (we merge repetitions), plus EGL_NONE. */ - assert(dst - ctx->attribs <= ARRAY_SIZE(ctx->attribs) - 3); - dst[0] = name; - dst[1] = wgl_attribs[1]; - if (dst == attribs_end) attribs_end += 2; - } - } - -out: - *attribs_end = EGL_NONE; - return TRUE; -} - - static void wayland_context_refresh(struct wayland_context *ctx) { BOOL refresh = FALSE; @@ -425,18 +359,64 @@ static BOOL wayland_set_pixel_format(HWND hwnd, int old_format, int new_format, static BOOL wayland_context_create(HDC hdc, 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);
- if (!(ctx = calloc(1, sizeof(*ctx)))) + for (; attribs && attribs[0] != 0; attribs += 2) { - ERR("Failed to allocate memory for GL context\n"); - return FALSE; + EGLint name; + + TRACE("%#x %#x\n", attribs[0], attribs[1]); + + /* Find the EGL attribute names corresponding to the WGL names. + * For all of the attributes below, the values match between the two + * systems, so we can use them directly. */ + switch (attribs[0]) + { + case WGL_CONTEXT_MAJOR_VERSION_ARB: + name = EGL_CONTEXT_MAJOR_VERSION_KHR; + break; + case WGL_CONTEXT_MINOR_VERSION_ARB: + name = EGL_CONTEXT_MINOR_VERSION_KHR; + break; + case WGL_CONTEXT_FLAGS_ARB: + name = EGL_CONTEXT_FLAGS_KHR; + break; + case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: + name = EGL_CONTEXT_OPENGL_NO_ERROR_KHR; + break; + case WGL_CONTEXT_PROFILE_MASK_ARB: + if (attribs[1] & WGL_CONTEXT_ES2_PROFILE_BIT_EXT) + { + ERR("OpenGL ES contexts are not supported\n"); + return FALSE; + } + name = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR; + break; + default: + name = EGL_NONE; + FIXME("Unhandled attributes: %#x %#x\n", attribs[0], attribs[1]); + } + + if (name != EGL_NONE) + { + EGLint *dst = egl_attribs; + /* Check if we have already set the same attribute and replace it. */ + for (; dst != attribs_end && *dst != name; dst += 2) continue; + /* Our context attribute array should have enough space for all the + * attributes we support (we merge repetitions), plus EGL_NONE. */ + assert(dst - egl_attribs <= ARRAY_SIZE(egl_attribs) - 3); + dst[0] = name; + dst[1] = attribs[1]; + if (dst == attribs_end) attribs_end += 2; + } } + *attribs_end = EGL_NONE;
- if (!wayland_context_populate_attribs(ctx, attribs)) + if (!(ctx = calloc(1, sizeof(*ctx)))) { - ctx->attribs[0] = EGL_NONE; + ERR("Failed to allocate memory for GL context\n"); return FALSE; }
@@ -450,7 +430,7 @@ static BOOL wayland_context_create(HDC hdc, int format, void *share_private, con funcs->p_eglBindAPI(EGL_OPENGL_API); ctx->context = funcs->p_eglCreateContext(egl->display, EGL_NO_CONFIG_KHR, share ? share->context : EGL_NO_CONTEXT, - ctx->attribs); + attribs ? egl_attribs : NULL);
pthread_mutex_lock(&gl_object_mutex); list_add_head(&gl_contexts, &ctx->entry); @@ -505,50 +485,6 @@ static void *wayland_get_proc_address(const char *name) return funcs->p_eglGetProcAddress(name); }
-static BOOL wayland_context_share(void *src_private, void *dst_private) -{ - struct wayland_context *orig = src_private, *dest = dst_private; - struct wayland_context *keep, *clobber; - - TRACE("(%p, %p)\n", orig, dest); - - /* Sharing of display lists works differently in EGL and WGL. In case of EGL - * it is done at context creation time but in case of WGL it is done using - * wglShareLists. We create an EGL context in wglCreateContext / - * wglCreateContextAttribsARB and when a program requests sharing we - * recreate the destination or source context if it hasn't been made current - * and it hasn't shared display lists before. */ - - if (!dest->has_been_current && !dest->sharing) - { - keep = orig; - clobber = dest; - } - else if (!orig->has_been_current && !orig->sharing) - { - keep = dest; - clobber = orig; - } - else - { - ERR("Could not share display lists because both of the contexts have " - "already been current or shared\n"); - return FALSE; - } - - funcs->p_eglDestroyContext(egl->display, clobber->context); - clobber->context = funcs->p_eglCreateContext(egl->display, EGL_NO_CONFIG_KHR, - keep->context, clobber->attribs); - TRACE("re-created context (%p) for Wine context %p (%p) " - "sharing lists with ctx %p (%p)\n", - clobber->context, clobber, clobber->config, - keep->context, keep->config); - - orig->sharing = TRUE; - dest->sharing = TRUE; - return TRUE; -} - static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) { return FALSE; @@ -642,7 +578,6 @@ static struct opengl_driver_funcs wayland_driver_funcs = .p_context_create = wayland_context_create, .p_context_destroy = wayland_context_destroy, .p_context_copy = wayland_context_copy, - .p_context_share = wayland_context_share, .p_context_flush = wayland_context_flush, .p_context_make_current = wayland_context_make_current, .p_pbuffer_create = wayland_pbuffer_create, diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 6e1b914b55f..d0a399c0a6e 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,12 +197,8 @@ struct glx_pixel_format struct x11drv_context { HDC hdc; - BOOL has_been_current; - BOOL sharing; BOOL gl3_context; const struct glx_pixel_format *fmt; - int numAttribs; /* This is needed for delaying wglCreateContextAttribsARB */ - int attribList[16]; /* This is needed for delaying wglCreateContextAttribsARB */ GLXContext ctx; struct gl_drawable *drawables[2]; struct gl_drawable *new_drawables[2]; @@ -1025,17 +1021,12 @@ 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) +static GLXContext create_glxcontext(Display *display, struct x11drv_context *context, GLXContext shareList, const int *attribs) { GLXContext ctx;
if(context->gl3_context) - { - if(context->numAttribs) - ctx = pglXCreateContextAttribsARB(gdi_display, context->fmt->fbconfig, shareList, GL_TRUE, context->attribList); - else - ctx = pglXCreateContextAttribsARB(gdi_display, context->fmt->fbconfig, shareList, GL_TRUE, NULL); - } + 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 */ @@ -1589,7 +1580,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->has_been_current = TRUE; ctx->hdc = draw_hdc; set_context_drawables( ctx, draw_gl, read_gl ); NtCurrentTeb()->glReserved2 = ctx; @@ -1606,55 +1596,6 @@ done: return ret; }
-/*********************************************************************** - * glxdrv_wglShareLists - */ -static BOOL x11drv_context_share(void *src_private, void *dst_private) -{ - struct x11drv_context *org = src_private, *dest = dst_private; - struct x11drv_context *keep, *clobber; - - TRACE("(%p, %p)\n", org, dest); - - /* Sharing of display lists works differently in GLX and WGL. In case of GLX it is done - * at context creation time but in case of WGL it is done using wglShareLists. - * In the past we tried to emulate wglShareLists by delaying GLX context creation until - * either a wglMakeCurrent or wglShareLists. This worked fine for most apps but it causes - * issues for OpenGL 3 because there wglCreateContextAttribsARB can fail in a lot of cases, - * so there delaying context creation doesn't work. - * - * The new approach is to create a GLX context in wglCreateContext / wglCreateContextAttribsARB - * and when a program requests sharing we recreate the destination or source context if it - * hasn't been made current and it hasn't shared display lists before. - */ - - if (!dest->has_been_current && !dest->sharing) - { - keep = org; - clobber = dest; - } - else if (!org->has_been_current && !org->sharing) - { - keep = dest; - clobber = org; - } - else - { - ERR("Could not share display lists because both of the contexts have already been current or shared\n"); - return FALSE; - } - - pglXDestroyContext(gdi_display, clobber->ctx); - clobber->ctx = create_glxcontext(gdi_display, clobber, keep->ctx); - TRACE("re-created context (%p) for Wine context %p (%s) sharing lists with ctx %p (%s)\n", - clobber->ctx, clobber, debugstr_fbconfig(clobber->fmt->fbconfig), - keep->ctx, debugstr_fbconfig(keep->fmt->fbconfig)); - - org->sharing = TRUE; - dest->sharing = TRUE; - return TRUE; -} - static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) { HWND toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); @@ -1723,6 +1664,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva static BOOL x11drv_context_create( HDC hdc, 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); @@ -1733,7 +1675,6 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con ret->fmt = &pixel_formats[format - 1]; if (attribList) { - int *pContextAttribList = &ret->attribList[0]; ret->gl3_context = TRUE; /* attribList consists of pairs {token, value] terminated with 0 */ while(attribList[0] != 0) @@ -1745,13 +1686,11 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con pContextAttribList[0] = GLX_CONTEXT_MAJOR_VERSION_ARB; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; case WGL_CONTEXT_MINOR_VERSION_ARB: pContextAttribList[0] = GLX_CONTEXT_MINOR_VERSION_ARB; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; case WGL_CONTEXT_LAYER_PLANE_ARB: break; @@ -1759,25 +1698,21 @@ static BOOL x11drv_context_create( HDC hdc, int format, void *share_private, con pContextAttribList[0] = GLX_CONTEXT_FLAGS_ARB; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; case WGL_CONTEXT_OPENGL_NO_ERROR_ARB: pContextAttribList[0] = GLX_CONTEXT_OPENGL_NO_ERROR_ARB; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; case WGL_CONTEXT_PROFILE_MASK_ARB: pContextAttribList[0] = GLX_CONTEXT_PROFILE_MASK_ARB; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; case WGL_RENDERER_ID_WINE: pContextAttribList[0] = GLX_RENDERER_ID_MESA; pContextAttribList[1] = attribList[1]; pContextAttribList += 2; - ret->numAttribs++; break; default: ERR("Unhandled attribList pair: %#x %#x\n", attribList[0], attribList[1]); @@ -1787,7 +1722,8 @@ 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( gdi_display, ret, hShareContext ? hShareContext->ctx : NULL, + attribList ? glx_attribs : NULL ); XSync(gdi_display, False); if ((err = X11DRV_check_error()) || !ret->ctx) { @@ -2082,7 +2018,6 @@ static const struct opengl_driver_funcs x11drv_driver_funcs = .p_context_create = x11drv_context_create, .p_context_destroy = x11drv_context_destroy, .p_context_copy = x11drv_context_copy, - .p_context_share = x11drv_context_share, .p_context_flush = x11drv_context_flush, .p_context_make_current = x11drv_context_make_current, .p_pbuffer_create = x11drv_pbuffer_create, diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 656caa1754b..ffd60393f90 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -148,7 +148,6 @@ struct opengl_driver_funcs BOOL (*p_context_create)(HDC,int,void*,const int*,void**); BOOL (*p_context_destroy)(void*); BOOL (*p_context_copy)(void*,void*,UINT); - BOOL (*p_context_share)(void*,void*); BOOL (*p_context_flush)(void*,HWND,HDC,int,BOOL); BOOL (*p_context_make_current)(HDC,HDC,void*); BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLenum,GLenum,GLint,GLsizei*,GLsizei*,void **);