OSmesa is deprecated and has been removed from latest mesa releases, this replaces it with pbuffer rendering and flushing of the surface onto the bitmap at some specific sync points. The tests show that this is roughly how Windows seem to behave anyway, instead of rendering directly to the memory as OSmesa does.
-- v4: win32u: Remove now unnecessary context and pbuffer funcs. win32u: Drop now unnecessary OSMesa dependency. win32u: Use a pbuffer to implement GL on memory DCs. opengl32/tests: Relax memory DC pixel format selection. opengl32: Expose every pixel format on memory DCs. winex11: Check XVisualInfo vs GLXFBConfig depth to avoid BadMatch. winex11: Flag offscreen formats as bitmap compatible if possible. winemac: Use opengl_funcs for glFlush. winex11: Use opengl_funcs for glFlush / glFinish. opengl32: Move glFlush / glFinish hooking from win32u.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 3 ++ dlls/opengl32/unix_private.h | 3 ++ dlls/opengl32/unix_thunks.c | 8 ++--- dlls/opengl32/unix_wgl.c | 38 +++++++++++++++++++++ dlls/win32u/opengl.c | 62 +++++++---------------------------- dlls/wineandroid.drv/opengl.c | 2 +- dlls/winemac.drv/opengl.c | 2 +- dlls/winewayland.drv/opengl.c | 2 +- dlls/winex11.drv/opengl.c | 7 ++-- include/wine/opengl_driver.h | 3 +- 10 files changed, 66 insertions(+), 64 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index 0001ffe28f3..bc8eb05aaa5 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -200,10 +200,13 @@ 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 = ( diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index 62e96dfbe81..30b90545105 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -80,6 +80,9 @@ extern HGLRC wrap_wglCreateContext( TEB *teb, HDC hDc ); extern BOOL wrap_wglDeleteContext( TEB *teb, HGLRC oldContext ); extern PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR lpszProc ); extern BOOL wrap_wglMakeCurrent( TEB *teb, HDC hDc, HGLRC newContext ); +extern void wrap_glFinish( TEB *teb ); +extern void wrap_glFlush( TEB *teb ); +extern BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ); extern BOOL wrap_wglShareLists( TEB *teb, HGLRC hrcSrvShare, HGLRC hrcSrvSource ); extern void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ); extern const GLubyte * wrap_glGetString( TEB *teb, GLenum name ); diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index 4342e809481..ae97dfbec47 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -100,7 +100,7 @@ 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 ); + params->ret = wrap_wglSwapBuffers( params->teb, params->hdc ); return STATUS_SUCCESS; }
@@ -907,8 +907,7 @@ static NTSTATUS gl_glFeedbackBuffer( void *args ) static NTSTATUS gl_glFinish( void *args ) { struct glFinish_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFinish(); + wrap_glFinish( params->teb ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -916,8 +915,7 @@ static NTSTATUS gl_glFinish( void *args ) static NTSTATUS gl_glFlush( void *args ) { struct glFlush_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glFlush(); + wrap_glFlush( params->teb ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index 94220daf4fd..f009c74e209 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -986,6 +986,44 @@ BOOL wrap_wglDeleteContext( TEB *teb, HGLRC hglrc ) return TRUE; }
+static void flush_context( TEB *teb, void (*flush)(void) ) +{ + struct opengl_context *ctx = get_current_context( teb ); + const struct opengl_funcs *funcs = teb->glTable; + + if (!ctx || !funcs->p_wgl_context_flush( ctx->drv_ctx, flush )) + { + /* default implementation: call the functions directly */ + if (flush) flush(); + } +} + +void wrap_glFinish( TEB *teb ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, funcs->p_glFinish ); +} + +void wrap_glFlush( TEB *teb ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, funcs->p_glFlush ); +} + +BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) +{ + const struct opengl_funcs *funcs = get_dc_funcs( hdc ); + BOOL ret; + + if (!(ret = funcs->p_wglSwapBuffers( hdc ))) + { + /* default implementation: implicitly flush the context */ + flush_context( teb, funcs->p_glFlush ); + } + + return ret; +} + BOOL wrap_wglShareLists( TEB *teb, 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 223bae502c2..13c9d230925 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 @@ -424,7 +417,7 @@ static BOOL egldrv_context_destroy( void *private ) return FALSE; }
-static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL egldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { FIXME( "stub!\n" ); return FALSE; @@ -767,7 +760,7 @@ static BOOL osmesa_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva return ret; }
-static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } @@ -859,7 +852,7 @@ static BOOL nulldrv_context_destroy( void *private ) return FALSE; }
-static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL nulldrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } @@ -1044,8 +1037,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 )) { @@ -1552,23 +1543,17 @@ 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( struct wgl_context *context, void (*flush)(void) ) { - HDC hdc = NtCurrentTeb()->glReserved1[0]; + HDC draw_hdc = NtCurrentTeb()->glReserved1[0]; int interval; HWND hwnd;
- if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; + if (!(hwnd = NtUserWindowFromDC( draw_hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- 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(); - } + TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush ); + return context->driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1589,14 +1574,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 ) @@ -1645,18 +1623,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) \ @@ -1689,10 +1655,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) @@ -1722,10 +1685,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/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 0e8da03ab0c..60cdd419f62 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -355,7 +355,7 @@ static BOOL android_swap_buffers( void *private, HWND hwnd, HDC hdc, int interva return TRUE; }
-static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL android_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct android_context *ctx = private; struct gl_drawable *gl; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 474d8f9d4e8..f1d3ef3a265 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -2068,7 +2068,7 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, }
-static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL macdrv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct macdrv_context *context = private;
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index d9b93f44c73..5b995f6b6ab 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -479,7 +479,7 @@ static void *wayland_get_proc_address(const char *name) return funcs->p_eglGetProcAddress(name); }
-static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL wayland_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { return FALSE; } diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3d583a170e7..3c40d864338 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1612,7 +1612,7 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO if (region) NtGdiDeleteObjectApp( region ); }
-static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, BOOL finish ) +static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) { struct gl_drawable *gl; struct x11drv_context *ctx = private; @@ -1624,10 +1624,9 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva set_swap_interval( gl, interval ); pthread_mutex_unlock( &context_mutex );
- if (finish) pglFinish(); - else pglFlush(); + if (flush) flush();
- present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, !finish ); + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != pglFinish ); release_gl_drawable( gl ); return TRUE; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 71e799660b8..ed441fdb932 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -69,6 +69,7 @@ struct wgl_pbuffer; /* interface between opengl32 and win32u */ struct opengl_funcs { + BOOL (*p_wgl_context_flush)( struct wgl_context *context, void (*flush)(void) ); BOOL (*p_wglCopyContext)( struct wgl_context * hglrcSrc, struct wgl_context * hglrcDst, UINT mask ); struct wgl_context * (*p_wglCreateContext)( HDC hDc ); BOOL (*p_wglDeleteContext)( struct wgl_context * oldContext ); @@ -134,7 +135,7 @@ struct opengl_driver_funcs BOOL (*p_swap_buffers)(void*,HWND,HDC,int); BOOL (*p_context_create)(HDC,int,void*,const int*,void**); BOOL (*p_context_destroy)(void*); - BOOL (*p_context_flush)(void*,HWND,HDC,int,BOOL); + BOOL (*p_context_flush)(void*,HWND,HDC,int,void(*)(void)); BOOL (*p_context_make_current)(HDC,HDC,void*); BOOL (*p_pbuffer_create)(HDC,int,BOOL,GLenum,GLenum,GLint,GLsizei*,GLsizei*,void **); BOOL (*p_pbuffer_destroy)(HDC,void*);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 3c40d864338..07e90ef2caa 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -346,10 +346,12 @@ static INT64 (*pglXSwapBuffersMscOML)( Display *dpy, GLXDrawable drawable, INT64 target_msc, INT64 divisor, INT64 remainder );
/* Standard OpenGL */ -static void (*pglFinish)(void); -static void (*pglFlush)(void); static const GLubyte *(*pglGetString)(GLenum name);
+static void *opengl_handle; +static const struct opengl_funcs *funcs; +static const struct opengl_driver_funcs x11drv_driver_funcs; + /* check if the extension is present in the list */ static BOOL has_extension( const char *list, const char *ext ) { @@ -490,9 +492,6 @@ done: return ret; }
-static void *opengl_handle; -static const struct opengl_driver_funcs x11drv_driver_funcs; - /********************************************************************** * X11DRV_OpenglInit */ @@ -505,6 +504,7 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c ERR( "version mismatch, opengl32 wants %u but driver has %u\n", version, WINE_OPENGL_DRIVER_VERSION ); return STATUS_INVALID_PARAMETER; } + funcs = opengl_funcs;
/* No need to load any other libraries as according to the ABI, libGL should be self-sufficient and include all dependencies */ @@ -523,8 +523,6 @@ UINT X11DRV_OpenGLInit( UINT version, const struct opengl_funcs *opengl_funcs, c ERR( "%s not found in libGL, disabling OpenGL.\n", #func ); \ goto failed; \ } - LOAD_FUNCPTR( glFinish ); - LOAD_FUNCPTR( glFlush ); LOAD_FUNCPTR( glGetString ); #undef LOAD_FUNCPTR
@@ -1589,7 +1587,7 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO window = get_dc_drawable( hdc, &rect ); region = get_dc_monitor_region( hwnd, hdc );
- if (gl_finish) pglFinish(); + if (gl_finish) funcs->p_glFinish(); if (flush) XFlush( gdi_display );
NtUserGetClientRect( hwnd, &rect_dst, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); @@ -1626,7 +1624,7 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva
if (flush) flush();
- present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != pglFinish ); + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != funcs->p_glFinish ); release_gl_drawable( gl ); return TRUE; } @@ -1942,14 +1940,14 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval /* (glX)SwapBuffers has an implicit glFlush effect, however * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before * copying */ - pglFlush(); + funcs->p_glFlush(); pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0, gl->rect.right, gl->rect.bottom ); break; } if (ctx && pglXSwapBuffersMscOML) { - pglFlush(); + funcs->p_glFlush(); target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); break; } @@ -1963,7 +1961,7 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval default: if (ctx && drawable && pglXSwapBuffersMscOML) { - pglFlush(); + funcs->p_glFlush(); target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); break; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/opengl.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index f1d3ef3a265..c55ecc0976a 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -86,12 +86,13 @@ static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER; static CFMutableDictionaryRef dc_pbuffers; static pthread_mutex_t dc_pbuffers_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void *opengl_handle; +static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs macdrv_driver_funcs;
static void (*pglCopyColorTable)(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); static void (*pglCopyPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -static void (*pglFlush)(void); static void (*pglFlushRenderAPPLE)(void); static const GLubyte *(*pglGetString)(GLenum name); static PFN_glGetIntegerv pglGetIntegerv; @@ -232,9 +233,6 @@ static pixel_format *pixel_formats; static int nb_formats, nb_displayable_formats;
-static void *opengl_handle; - - static const char* debugstr_attrib(int attrib, int value) { static const struct { @@ -2174,7 +2172,7 @@ static UINT macdrv_pbuffer_bind(HDC hdc, void *private, GLenum source) TRACE("hdc %p pbuffer %p source 0x%x\n", hdc, pbuffer, source);
if (!context->draw_view && context->draw_pbuffer == pbuffer && source != GL_NONE) - pglFlush(); + funcs->p_glFlush();
err = CGLTexImagePBuffer(context->cglcontext, pbuffer, source); if (err != kCGLNoError) @@ -2782,6 +2780,7 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co ERR("version mismatch, opengl32 wants %u but macdrv has %u\n", version, WINE_OPENGL_DRIVER_VERSION); return STATUS_INVALID_PARAMETER; } + funcs = opengl_funcs;
dc_pbuffers = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); if (!dc_pbuffers) @@ -2810,7 +2809,6 @@ UINT macdrv_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, co LOAD_FUNCPTR(glReadPixels); LOAD_FUNCPTR(glViewport); LOAD_FUNCPTR(glCopyColorTable); - LOAD_FUNCPTR(glFlush);
if (!init_gl_info()) goto failed;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 07e90ef2caa..6a28fb8e80f 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -733,7 +733,7 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) { struct glx_pixel_format *list; int size = 0, onscreen_size = 0; - int fmt_id, nCfgs, i, run, bmp_formats; + int fmt_id, nCfgs, i, run; GLXFBConfig* cfgs; XVisualInfo *visinfo;
@@ -744,21 +744,7 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) return 0; }
- /* Bitmap rendering on Windows implies the use of the Microsoft GDI software renderer. - * Further most GLX drivers only offer pixmap rendering using indirect rendering (except for modern drivers which support 'AIGLX' / composite). - * Indirect rendering can indicate software rendering (on Nvidia it is hw accelerated) - * Since bitmap rendering implies the use of software rendering we can safely use indirect rendering for bitmaps. - * - * Below we count the number of formats which are suitable for bitmap rendering. Windows restricts bitmap rendering to single buffered formats. - */ - for(i=0, bmp_formats=0; i<nCfgs; i++) - { - if(check_fbconfig_bitmap_capability(gdi_display, cfgs[i])) - bmp_formats++; - } - TRACE("Found %d bitmap capable fbconfigs\n", bmp_formats); - - list = calloc( 1, (nCfgs + bmp_formats) * sizeof(*list) ); + list = calloc( 1, (nCfgs * 2) * sizeof(*list) );
/* Fill the pixel format list. Put onscreen formats at the top and offscreen ones at the bottom. * Do this as GLX doesn't guarantee that the list is sorted */ @@ -826,7 +812,8 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) list[size].fbconfig = cfgs[i]; list[size].fmt_id = fmt_id; list[size].render_type = get_render_type_from_fbconfig(gdi_display, cfgs[i]); - list[size].dwFlags = 0; + if (!check_fbconfig_bitmap_capability( gdi_display, cfgs[i] )) list[size].dwFlags = 0; + else list[size].dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_GENERIC_FORMAT; size++; } else if (visinfo) XFree(visinfo);
From: Rémi Bernon rbernon@codeweavers.com
Some onscreen llvmpipe formats have inconsistent 32 vs 24 bpp, we should make sure they aren't used for bitmap rendering. --- dlls/winex11.drv/opengl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 6a28fb8e80f..810ba3253e5 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -718,10 +718,14 @@ static int get_render_type_from_fbconfig(Display *display, GLXFBConfig fbconfig) }
/* Check whether a fbconfig is suitable for Windows-style bitmap rendering */ -static BOOL check_fbconfig_bitmap_capability(Display *display, GLXFBConfig fbconfig) +static BOOL check_fbconfig_bitmap_capability( GLXFBConfig fbconfig, const XVisualInfo *vis ) { int dbuf, value; - pglXGetFBConfigAttrib(display, fbconfig, GLX_DOUBLEBUFFER, &dbuf); + + pglXGetFBConfigAttrib( gdi_display, fbconfig, GLX_BUFFER_SIZE, &value ); + if (vis && value != vis->depth) return FALSE; + + pglXGetFBConfigAttrib( gdi_display, fbconfig, GLX_DOUBLEBUFFER, &dbuf ); pglXGetFBConfigAttrib(gdi_display, fbconfig, GLX_DRAWABLE_TYPE, &value);
/* Windows only supports bitmap rendering on single buffered formats, further the fbconfig needs to have @@ -781,7 +785,7 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) onscreen_size++;
/* Clone a format if it is bitmap capable for indirect rendering to bitmaps */ - if(check_fbconfig_bitmap_capability(gdi_display, cfgs[i])) + if (check_fbconfig_bitmap_capability( cfgs[i], visinfo )) { TRACE("Found bitmap capable format FBCONFIG_ID 0x%x corresponding to iPixelFormat %d at GLX index %d\n", fmt_id, size+1, i); list[size].fbconfig = cfgs[i]; @@ -812,7 +816,7 @@ static UINT x11drv_init_pixel_formats( UINT *onscreen_count ) list[size].fbconfig = cfgs[i]; list[size].fmt_id = fmt_id; list[size].render_type = get_render_type_from_fbconfig(gdi_display, cfgs[i]); - if (!check_fbconfig_bitmap_capability( gdi_display, cfgs[i] )) list[size].dwFlags = 0; + if (!check_fbconfig_bitmap_capability( cfgs[i], NULL )) list[size].dwFlags = 0; else list[size].dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI | PFD_GENERIC_FORMAT; size++; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/wgl.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 7de0d1b1dba..e24327af15b 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -29,6 +29,7 @@ #include "winbase.h" #include "winreg.h" #include "ntuser.h" +#include "ntgdi.h" #include "malloc.h"
#include "unixlib.h" @@ -314,6 +315,7 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, struct get_pixel_formats_params args = { .teb = NtCurrentTeb(), .hdc = hdc }; PVOID *glReserved = NtCurrentTeb()->glReserved1; NTSTATUS status; + DWORD is_memdc;
if (glReserved[WINE_GL_RESERVED_FORMATS_HDC] == hdc) { @@ -329,6 +331,9 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, args.max_formats = args.num_formats; if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error;
+ if (NtGdiGetDCDword( hdc, NtGdiIsMemDC, &is_memdc ) && is_memdc) + args.num_onscreen_formats = args.num_formats; + *num_formats = args.num_formats; *num_onscreen_formats = args.num_onscreen_formats;
From: Rémi Bernon rbernon@codeweavers.com
The llvmpipe formats with 8 alpha bits are all "onscreen" and have bogus inconsistent depth between their config and visual which cause BadMatch errors when flushing, including with PBuffers. Offscreen formats have only 2 alpha bits, so relax the tests so they work on the CI. --- dlls/opengl32/tests/opengl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 4443945c8c6..10d4e9a491f 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1539,7 +1539,7 @@ static void test_bitmap_rendering( BOOL use_dib ) ok( ret == count, "got %d\n", ret );
if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) && (pfd.dwFlags & PFD_SUPPORT_OPENGL) && - pfd.cColorBits == bpp && pfd.cAlphaBits == 8) + pfd.cColorBits == bpp && pfd.cAlphaBits > 0) { ret = SetPixelFormat( hdc, i, &pfd ); if (pixel_format) ok( !ret, "SetPixelFormat succeeded\n" ); @@ -1825,7 +1825,7 @@ static void test_d3dkmt_rendering(void) ok( ret == count, "got %d\n", ret );
if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) && (pfd.dwFlags & PFD_SUPPORT_OPENGL) && - pfd.cColorBits == 32 && pfd.cAlphaBits == 8) + pfd.cColorBits == 32 && pfd.cAlphaBits > 0) { ret = SetPixelFormat( desc.hDc, i, &pfd ); if (pixel_format) ok( !ret, "SetPixelFormat succeeded\n" );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/opengl32/make_opengl | 3 + dlls/opengl32/tests/opengl.c | 25 ++++---- dlls/opengl32/unix_private.h | 3 + dlls/opengl32/unix_thunks.c | 9 +-- dlls/opengl32/unix_wgl.c | 21 +++++++ dlls/win32u/opengl.c | 108 ++++++++++++++++++++++++++++++----- 6 files changed, 137 insertions(+), 32 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index bc8eb05aaa5..d43ee4abf3e 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -200,11 +200,14 @@ my %manual_unix_thunks = "glDebugMessageCallback" => 1, "glDebugMessageCallbackAMD" => 1, "glDebugMessageCallbackARB" => 1, + "glDrawPixels" => 1, "glFinish" => 1, "glFlush" => 1, "glGetIntegerv" => 1, "glGetString" => 1, "glGetStringi" => 1, + "glReadPixels" => 1, + "glViewport" => 1, "wglGetProcAddress" => 1, "wglSwapBuffers" => 1, ); diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 10d4e9a491f..901745098f1 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1597,7 +1597,7 @@ static void test_bitmap_rendering( BOOL use_dib ) ok( EqualRect( (RECT *)viewport, &expect_rect ), "got viewport %s\n", wine_dbgstr_rect( (RECT *)viewport ) );
glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( (pixel & 0xffffff) == 0xcdcdcd, "got %#x\n", pixel ); + ok( (pixel & 0xffffff) == 0xcdcdcd, "got %#x\n", pixel );
glClearColor( (float)0x22 / 0xff, (float)0x33 / 0xff, (float)0x44 / 0xff, (float)0x11 / 0xff ); glClear( GL_COLOR_BUFFER_BIT ); @@ -1642,7 +1642,7 @@ static void test_bitmap_rendering( BOOL use_dib ) ok( (pixel & 0xffffff) == 0x443322, "got %#x\n", pixel ); if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); ok( (pixels2[0] & 0xffffff) == 0xdcdcdc, "got %#x\n", pixels2[0] );
@@ -1657,13 +1657,13 @@ static void test_bitmap_rendering( BOOL use_dib ) /* pixels are read from the selected bitmap */
glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( (pixel & 0xffffff) == 0xdcdcdc, "got %#x\n", pixel ); + ok( (pixel & 0xffffff) == 0xdcdcdc, "got %#x\n", pixel );
if (use_dib) { memset( buffer2, 0xa5, sizeof(buffer2) ); glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( (pixel & 0xffffff) == 0xdcdcdc, "got %#x\n", pixel ); + ok( (pixel & 0xffffff) == 0xdcdcdc, "got %#x\n", pixel ); memset( buffer2, 0xdc, sizeof(buffer2) ); }
@@ -1676,7 +1676,7 @@ static void test_bitmap_rendering( BOOL use_dib )
if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); ok( (pixels2[0] & 0xffffff) == 0xdcdcdc, "got %#x\n", pixels2[0] );
glFinish(); @@ -1685,8 +1685,8 @@ static void test_bitmap_rendering( BOOL use_dib ) ok( (pixel & 0xffffff) == 0x223344, "got %#x\n", pixel ); if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); - todo_wine ok( (pixels2[0] & 0xffffff) == 0x443322, "got %#x\n", pixels2[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels2[0] & 0xffffff) == 0x443322, "got %#x\n", pixels2[0] );
ret = wglMakeCurrent( NULL, NULL ); @@ -1704,7 +1704,7 @@ static void test_bitmap_rendering( BOOL use_dib )
if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); ok( (pixels2[0] & 0xffffff) == 0x445566, "got %#x\n", pixels2[0] );
@@ -1726,7 +1726,7 @@ static void test_bitmap_rendering( BOOL use_dib )
if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); if (use_dib) todo_wine ok( (pixels2[0] & 0xffffff) == 0x03148, "got %#x\n", pixels2[0] ); else ok( (pixels2[0] & 0xffffff) == 0x665544, "got %#x\n", pixels2[0] );
@@ -1743,7 +1743,7 @@ static void test_bitmap_rendering( BOOL use_dib )
if (pixels == buffer) read_bitmap_pixels( hdc, bmp, pixels, 4, 4, bpp ); if (pixels2 == buffer2) read_bitmap_pixels( hdc, bmp2, pixels2, 12, 12, bpp ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x223344, "got %#x\n", pixels[0] ); ok( (pixels2[0] & 0xffffff) == 0x667788, "got %#x\n", pixels2[0] );
@@ -1789,6 +1789,7 @@ static void test_d3dkmt_rendering(void) NTSTATUS status; HGLRC hglrc;
+ memset( (void *)pixels, 0xcd, sizeof(*pixels) * 4 * 4 ); create.pMemory = pixels; create.Format = D3DDDIFMT_A8R8G8B8; create.Width = 4; @@ -1858,7 +1859,7 @@ static void test_d3dkmt_rendering(void)
memset( (void *)pixels, 0xcd, sizeof(*pixels) * 4 * 4 ); glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); - todo_wine ok( (pixel & 0xffffff) == 0xcdcdcd, "got %#x\n", pixel ); + ok( (pixel & 0xffffff) == 0xcdcdcd, "got %#x\n", pixel );
glClearColor( (float)0x44 / 0xff, (float)0x33 / 0xff, (float)0x22 / 0xff, (float)0x11 / 0xff ); glClear( GL_COLOR_BUFFER_BIT ); @@ -1881,7 +1882,7 @@ static void test_d3dkmt_rendering(void) ok( (pixels[0] & 0xffffff) == 0x556677, "got %#x\n", pixels[0] ); glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); ok( (pixel & 0xffffff) == 0x223344, "got %#x\n", pixel ); - todo_wine ok( (pixels[0] & 0xffffff) == 0x443322, "got %#x\n", pixels[0] ); + ok( (pixels[0] & 0xffffff) == 0x443322, "got %#x\n", pixels[0] );
glReadPixels( 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel ); ok( (pixel & 0xffffff) == 0x223344, "got %#x\n", pixel ); diff --git a/dlls/opengl32/unix_private.h b/dlls/opengl32/unix_private.h index 30b90545105..c15bda2c99a 100644 --- a/dlls/opengl32/unix_private.h +++ b/dlls/opengl32/unix_private.h @@ -82,6 +82,9 @@ extern PROC wrap_wglGetProcAddress( TEB *teb, LPCSTR lpszProc ); extern BOOL wrap_wglMakeCurrent( TEB *teb, HDC hDc, HGLRC newContext ); extern void wrap_glFinish( TEB *teb ); extern void wrap_glFlush( TEB *teb ); +extern void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ); +extern void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ); +extern void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height ); extern BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ); extern BOOL wrap_wglShareLists( TEB *teb, HGLRC hrcSrvShare, HGLRC hrcSrvSource ); extern void wrap_glGetIntegerv( TEB *teb, GLenum pname, GLint *data ); diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index ae97dfbec47..91aaadbe9c0 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -718,8 +718,7 @@ static NTSTATUS gl_glDrawElements( void *args ) static NTSTATUS gl_glDrawPixels( void *args ) { struct glDrawPixels_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glDrawPixels( params->width, params->height, params->format, params->type, params->pixels ); + wrap_glDrawPixels( params->teb, params->width, params->height, params->format, params->type, params->pixels ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -2203,8 +2202,7 @@ static NTSTATUS gl_glReadBuffer( void *args ) static NTSTATUS gl_glReadPixels( void *args ) { struct glReadPixels_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glReadPixels( params->x, params->y, params->width, params->height, params->format, params->type, params->pixels ); + wrap_glReadPixels( params->teb, params->x, params->y, params->width, params->height, params->format, params->type, params->pixels ); set_context_attribute( params->teb, -1 /* unsupported */, NULL, 0 ); return STATUS_SUCCESS; } @@ -3085,8 +3083,7 @@ static NTSTATUS gl_glVertexPointer( void *args ) static NTSTATUS gl_glViewport( void *args ) { struct glViewport_params *params = args; - const struct opengl_funcs *funcs = params->teb->glTable; - funcs->p_glViewport( params->x, params->y, params->width, params->height ); + wrap_glViewport( params->teb, params->x, params->y, params->width, params->height ); set_context_attribute( params->teb, GL_VIEWPORT, ¶ms->x, 2 * sizeof(GLint) + 2 * sizeof(GLsizei) ); return STATUS_SUCCESS; } diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index f009c74e209..d203f4781a7 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1010,6 +1010,27 @@ void wrap_glFlush( TEB *teb ) flush_context( teb, funcs->p_glFlush ); }
+void wrap_glDrawPixels( TEB *teb, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, NULL ); + funcs->p_glDrawPixels( width, height, format, type, pixels ); +} + +void wrap_glReadPixels( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, NULL ); + funcs->p_glReadPixels( x, y, width, height, format, type, pixels ); +} + +void wrap_glViewport( TEB *teb, GLint x, GLint y, GLsizei width, GLsizei height ) +{ + const struct opengl_funcs *funcs = teb->glTable; + flush_context( teb, NULL ); + funcs->p_glViewport( x, y, width, height ); +} + BOOL wrap_wglSwapBuffers( TEB *teb, HDC hdc ) { const struct opengl_funcs *funcs = get_dc_funcs( hdc ); diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 13c9d230925..310beaa8922 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -45,6 +45,9 @@ struct wgl_context const struct opengl_funcs *funcs; void *driver_private; int pixel_format; + + HBITMAP memory_bitmap; + struct wgl_pbuffer *memory_pbuffer; };
struct wgl_pbuffer @@ -935,6 +938,76 @@ static int win32u_wglGetPixelFormat( HDC hdc ) return format > 0 ? format : 0; }
+static struct wgl_pbuffer *create_memory_pbuffer( HDC hdc, int format ) +{ + const struct opengl_funcs *funcs = &display_funcs; + struct wgl_pbuffer *pbuffer = NULL; + BITMAPOBJ *bmp; + dib_info dib; + BOOL ret; + DC *dc; + + if (!(dc = get_dc_ptr( hdc ))) return NULL; + if (get_gdi_object_type( hdc ) != NTGDI_OBJ_MEMDC) ret = FALSE; + else if (!(bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) ret = FALSE; + else + { + ret = init_dib_info_from_bitmapobj( &dib, bmp ); + GDI_ReleaseObj( dc->hBitmap ); + } + release_dc_ptr( dc ); + + if (ret) + { + int width = dib.rect.right - dib.rect.left, height = dib.rect.bottom - dib.rect.top; + pbuffer = funcs->p_wglCreatePbufferARB( hdc, format, width, height, NULL ); + } + + if (pbuffer) TRACE( "Created pbuffer %p for memory DC %p\n", pbuffer, hdc ); + else WARN( "Failed to create pbuffer for memory DC %p\n", hdc ); + return pbuffer; +} + +static BOOL flush_memory_pbuffer( struct wgl_context *context, HDC hdc, BOOL write, void (*flush)(void) ) +{ + const struct opengl_funcs *funcs = &display_funcs; + BITMAPOBJ *bmp; + DC *dc; + + if (flush) flush(); + + if (!(dc = get_dc_ptr( hdc ))) return TRUE; + if ((bmp = GDI_GetObjPtr( dc->hBitmap, NTGDI_OBJ_BITMAP ))) + { + char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; + BITMAPINFO *info = (BITMAPINFO *)buffer; + struct bitblt_coords src = {0}; + struct gdi_image_bits bits; + + if (dc->hBitmap != context->memory_bitmap) write = TRUE; + context->memory_bitmap = dc->hBitmap; + + if (!get_image_from_bitmap( bmp, info, &bits, &src )) + { + int width = info->bmiHeader.biWidth, height = abs( info->bmiHeader.biHeight ); + if (write) funcs->p_glDrawPixels( width, height, GL_BGRA, GL_UNSIGNED_BYTE, bits.ptr ); + else funcs->p_glReadPixels( 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, bits.ptr ); + } + GDI_ReleaseObj( dc->hBitmap ); + } + release_dc_ptr( dc ); + + return TRUE; +} + +static void destroy_memory_pbuffer( struct wgl_context *context, HDC hdc ) +{ + const struct opengl_funcs *funcs = context->funcs; + flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFinish ); + funcs->p_wglDestroyPbufferARB( context->memory_pbuffer ); + context->memory_pbuffer = NULL; +} + static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) { const struct opengl_funcs *funcs; @@ -1038,7 +1111,7 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, context->funcs = funcs; context->pixel_format = format;
- if (!driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) + if (!context->driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) { free( context ); return NULL; @@ -1079,14 +1152,18 @@ static BOOL win32u_wglDeleteContext( struct wgl_context *context )
static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *context ) { + HDC hdc = draw_hdc, prev_draw = NtCurrentTeb()->glReserved1[0]; + struct wgl_context *prev_context = NtCurrentTeb()->glContext; const struct opengl_driver_funcs *funcs; int format;
TRACE( "draw_hdc %p, read_hdc %p, context %p\n", draw_hdc, read_hdc, context );
+ if (prev_context && prev_context->memory_pbuffer) destroy_memory_pbuffer( prev_context, prev_draw ); + if (!context) { - if (!(context = NtCurrentTeb()->glContext)) return TRUE; + if (!(context = prev_context)) return TRUE; funcs = context->driver_funcs; if (!funcs->p_context_make_current( NULL, NULL, NULL )) return FALSE; NtCurrentTeb()->glContext = NULL; @@ -1106,9 +1183,16 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return FALSE; }
+ if ((context->memory_pbuffer = create_memory_pbuffer( draw_hdc, context->pixel_format ))) + { + if (read_hdc != draw_hdc) ERR( "read != draw not supported\n" ); + draw_hdc = read_hdc = context->memory_pbuffer->hdc; + } + funcs = context->driver_funcs; if (!funcs->p_context_make_current( draw_hdc, read_hdc, context->driver_private )) return FALSE; NtCurrentTeb()->glContext = context; + if (context->memory_pbuffer) flush_memory_pbuffer( context, hdc, TRUE, NULL ); return TRUE; }
@@ -1147,7 +1231,7 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int return NULL; } NtGdiSetPixelFormat( pbuffer->hdc, format ); - pbuffer->driver_funcs = funcs == &display_funcs ? display_driver_funcs : memory_driver_funcs; + pbuffer->driver_funcs = display_driver_funcs; pbuffer->funcs = funcs; pbuffer->width = width; pbuffer->height = height; @@ -1553,13 +1637,14 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) else interval = get_window_swap_interval( hwnd );
TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush ); + + if (context->memory_pbuffer) return flush_memory_pbuffer( context, draw_hdc, FALSE, flush ); return context->driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); }
static BOOL win32u_wglSwapBuffers( HDC hdc ) { struct wgl_context *context = NtCurrentTeb()->glContext; - const struct opengl_driver_funcs *driver_funcs; const struct opengl_funcs *funcs; int interval; HWND hwnd; @@ -1569,12 +1654,13 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); return FALSE; } - driver_funcs = funcs == &display_funcs ? display_driver_funcs : memory_driver_funcs; + context->driver_funcs = funcs == &display_funcs ? display_driver_funcs : memory_driver_funcs;
if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
- return driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); + if (context->memory_pbuffer) return flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFlush ); + return context->driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); }
static BOOL win32u_wglSwapIntervalEXT( int interval ) @@ -1635,7 +1721,7 @@ static void init_opengl_funcs( struct opengl_funcs *funcs, const struct opengl_d #undef USE_GL_FUNC }
-static void memory_funcs_init(void) +static inline void memory_funcs_init(void) { if (!osmesa_get_wgl_driver( &memory_driver_funcs )) WARN( "Failed to initialize OSMesa functions\n" );
@@ -1749,18 +1835,12 @@ static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_fun release_dc_ptr( dc );
if (is_disabled) return NULL; - if (is_display) + if (is_display || is_memdc) { static pthread_once_t display_init_once = PTHREAD_ONCE_INIT; pthread_once( &display_init_once, display_funcs_init ); return &display_funcs; } - if (is_memdc) - { - static pthread_once_t memory_init_once = PTHREAD_ONCE_INIT; - pthread_once( &memory_init_once, memory_funcs_init ); - return &memory_funcs; - } return NULL; }
From: Rémi Bernon rbernon@codeweavers.com
--- configure.ac | 7 - dlls/win32u/opengl.c | 399 +++++--------------------------------- tools/gitlab/image.docker | 1 - 3 files changed, 49 insertions(+), 358 deletions(-)
diff --git a/configure.ac b/configure.ac index b373c47cfbb..17e9c559405 100644 --- a/configure.ac +++ b/configure.ac @@ -47,7 +47,6 @@ AC_ARG_WITH(netapi, AS_HELP_STRING([--without-netapi],[do not use the Samba N AC_ARG_WITH(opencl, AS_HELP_STRING([--without-opencl],[do not use OpenCL]), [if test "x$withval" = "xno"; then ac_cv_header_CL_cl_h=no; ac_cv_header_OpenCL_opencl_h=no; fi]) AC_ARG_WITH(opengl, AS_HELP_STRING([--without-opengl],[do not use OpenGL])) -AC_ARG_WITH(osmesa, AS_HELP_STRING([--without-osmesa],[do not use the OSMesa library])) AC_ARG_WITH(oss, AS_HELP_STRING([--without-oss],[do not use the OSS sound support])) AC_ARG_WITH(pcap, AS_HELP_STRING([--without-pcap],[do not use the Packet Capture library]), [if test "x$withval" = "xno"; then ac_cv_header_pcap_pcap_h=no; fi]) @@ -1391,12 +1390,6 @@ This probably prevents linking to OpenGL. Try deleting the file and restarting c fi], $X_LIBS -lm -dylib_file /System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib)], $X_LIBS -lm) - if test "x$with_osmesa" != "xno" - then - WINE_CHECK_SONAME(OSMesa,OSMesaGetProcAddress,,,[$X_LIBS -lm]) - WINE_NOTICE_WITH(osmesa,[test "x$ac_cv_lib_soname_OSMesa" = "x"], - [libOSMesa ${notice_platform}development files not found (or too old), OpenGL rendering in bitmaps won't be supported.]) - fi fi WINE_WARNING_WITH(opengl,[test -n "$opengl_msg"],[$opengl_msg OpenGL and Direct3D won't be supported.]) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 310beaa8922..6b0fa5bd481 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -71,9 +71,6 @@ struct wgl_pbuffer static const struct opengl_funcs *default_funcs; /* default GL function table from opengl32 */ static struct egl_platform display_egl; static struct opengl_funcs display_funcs; -static struct opengl_funcs memory_funcs; - -static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs );
static const struct { @@ -564,233 +561,6 @@ static void init_egl_platform( struct egl_platform *egl, struct opengl_funcs *fu
#endif /* SONAME_LIBEGL */
-#ifdef SONAME_LIBOSMESA - -#define OSMESA_COLOR_INDEX GL_COLOR_INDEX -#define OSMESA_RGBA GL_RGBA -#define OSMESA_BGRA 0x1 -#define OSMESA_ARGB 0x2 -#define OSMESA_RGB GL_RGB -#define OSMESA_BGR 0x4 -#define OSMESA_RGB_565 0x5 -#define OSMESA_ROW_LENGTH 0x10 -#define OSMESA_Y_UP 0x11 - -typedef struct osmesa_context *OSMesaContext; - -struct osmesa_context -{ - OSMesaContext context; - UINT format; -}; - -static const struct opengl_driver_funcs osmesa_driver_funcs; - -static OSMesaContext (*pOSMesaCreateContextExt)( GLenum format, GLint depthBits, GLint stencilBits, - GLint accumBits, OSMesaContext sharelist ); -static void (*pOSMesaDestroyContext)( OSMesaContext ctx ); -static void * (*pOSMesaGetProcAddress)( const char *funcName ); -static GLboolean (*pOSMesaMakeCurrent)( OSMesaContext ctx, void *buffer, GLenum type, - GLsizei width, GLsizei height ); -static void (*pOSMesaPixelStore)( GLint pname, GLint value ); -static void describe_pixel_format( int fmt, PIXELFORMATDESCRIPTOR *descr ); - -static BOOL osmesa_get_wgl_driver( const struct opengl_driver_funcs **driver_funcs ) -{ - static void *osmesa_handle; - - osmesa_handle = dlopen( SONAME_LIBOSMESA, RTLD_NOW ); - if (osmesa_handle == NULL) - { - ERR( "Failed to load OSMesa: %s\n", dlerror() ); - return FALSE; - } - -#define LOAD_FUNCPTR(f) do if (!(p##f = dlsym( osmesa_handle, #f ))) \ - { \ - ERR( "%s not found in %s (%s), disabling.\n", #f, SONAME_LIBOSMESA, dlerror() ); \ - goto failed; \ - } while(0) - - LOAD_FUNCPTR(OSMesaCreateContextExt); - LOAD_FUNCPTR(OSMesaDestroyContext); - LOAD_FUNCPTR(OSMesaGetProcAddress); - LOAD_FUNCPTR(OSMesaMakeCurrent); - LOAD_FUNCPTR(OSMesaPixelStore); -#undef LOAD_FUNCPTR - - *driver_funcs = &osmesa_driver_funcs; - return TRUE; - -failed: - dlclose( osmesa_handle ); - osmesa_handle = NULL; - return FALSE; -} - -static const char *osmesa_init_wgl_extensions( struct opengl_funcs *funcs ) -{ - return ""; -} - -static UINT osmesa_init_pixel_formats( UINT *onscreen_count ) -{ - *onscreen_count = ARRAY_SIZE(pixel_formats); - return ARRAY_SIZE(pixel_formats); -} - -static BOOL osmesa_describe_pixel_format( int format, struct wgl_pixel_format *desc ) -{ - if (format <= 0 || format > ARRAY_SIZE(pixel_formats)) return FALSE; - describe_pixel_format( format, &desc->pfd ); - return TRUE; -} - -static BOOL osmesa_set_pixel_format( HWND hwnd, int old_format, int new_format, BOOL internal ) -{ - return TRUE; -} - -static BOOL osmesa_context_create( HDC hdc, int format, void *shared, const int *attribs, void **private ) -{ - struct osmesa_context *context; - PIXELFORMATDESCRIPTOR descr; - UINT gl_format; - - if (attribs) - { - ERR( "attribs not supported\n" ); - return FALSE; - } - - describe_pixel_format( format, &descr ); - - switch (descr.cColorBits) - { - case 32: - if (descr.cRedShift == 8) gl_format = OSMESA_ARGB; - else if (descr.cRedShift == 16) gl_format = OSMESA_BGRA; - else gl_format = OSMESA_RGBA; - break; - case 24: - gl_format = descr.cRedShift == 16 ? OSMESA_BGR : OSMESA_RGB; - break; - case 16: - gl_format = OSMESA_RGB_565; - break; - default: - return FALSE; - } - - if (!(context = malloc( sizeof(*context) ))) return FALSE; - context->format = gl_format; - if (!(context->context = pOSMesaCreateContextExt( gl_format, descr.cDepthBits, descr.cStencilBits, - descr.cAccumBits, 0 ))) - { - free( context ); - return FALSE; - } - - *private = context; - return TRUE; -} - -static BOOL osmesa_context_destroy( void *private ) -{ - struct osmesa_context *context = private; - pOSMesaDestroyContext( context->context ); - free( context ); - return TRUE; -} - -static void *osmesa_get_proc_address( const char *proc ) -{ - if (!strncmp( proc, "wgl", 3 )) return NULL; - return (PROC)pOSMesaGetProcAddress( proc ); -} - -static BOOL osmesa_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval ) -{ - return TRUE; -} - -static BOOL osmesa_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) -{ - struct osmesa_context *context = private; - HBITMAP bitmap; - BITMAPOBJ *bmp; - dib_info dib; - BOOL ret = FALSE; - - if (!private) - { - pOSMesaMakeCurrent( NULL, NULL, GL_UNSIGNED_BYTE, 0, 0 ); - return TRUE; - } - - if (draw_hdc != read_hdc) - { - ERR( "read != draw not supported\n" ); - return FALSE; - } - - bitmap = NtGdiGetDCObject( draw_hdc, NTGDI_OBJ_SURF ); - bmp = GDI_GetObjPtr( bitmap, NTGDI_OBJ_BITMAP ); - if (!bmp) return FALSE; - - if (init_dib_info_from_bitmapobj( &dib, bmp )) - { - char *bits; - int width = dib.rect.right - dib.rect.left; - int height = dib.rect.bottom - dib.rect.top; - GLenum type; - - if (dib.stride < 0) bits = (char *)dib.bits.ptr + (dib.rect.bottom - 1) * dib.stride; - else bits = (char *)dib.bits.ptr + dib.rect.top * dib.stride; - bits += dib.rect.left * dib.bit_count / 8; - - TRACE( "context %p bits %p size %ux%u\n", context, bits, width, height ); - - type = context->format == OSMESA_RGB_565 ? GL_UNSIGNED_SHORT_5_6_5 : GL_UNSIGNED_BYTE; - ret = pOSMesaMakeCurrent( context->context, bits, type, width, height ); - if (ret) - { - pOSMesaPixelStore( OSMESA_ROW_LENGTH, abs( dib.stride ) * 8 / dib.bit_count ); - pOSMesaPixelStore( OSMESA_Y_UP, 1 ); /* Windows seems to assume bottom-up */ - } - } - GDI_ReleaseObj( bitmap ); - return ret; -} - -static BOOL osmesa_context_flush( void *private, HWND hwnd, HDC hdc, int interval, void (*flush)(void) ) -{ - return FALSE; -} - -static const struct opengl_driver_funcs osmesa_driver_funcs = -{ - .p_get_proc_address = osmesa_get_proc_address, - .p_init_pixel_formats = osmesa_init_pixel_formats, - .p_describe_pixel_format = osmesa_describe_pixel_format, - .p_init_wgl_extensions = osmesa_init_wgl_extensions, - .p_set_pixel_format = osmesa_set_pixel_format, - .p_swap_buffers = osmesa_swap_buffers, - .p_context_create = osmesa_context_create, - .p_context_destroy = osmesa_context_destroy, - .p_context_flush = osmesa_context_flush, - .p_context_make_current = osmesa_context_make_current, -}; - -#else /* SONAME_LIBOSMESA */ - -static BOOL osmesa_get_wgl_driver( const struct opengl_driver_funcs **driver_funcs ) -{ - return FALSE; -} - -#endif /* SONAME_LIBOSMESA */ - static void *nulldrv_get_proc_address( const char *name ) { return NULL; @@ -883,10 +653,8 @@ static const struct opengl_driver_funcs nulldrv_funcs = .p_context_make_current = nulldrv_context_make_current, };
-static const struct opengl_driver_funcs *memory_driver_funcs = &nulldrv_funcs; -static const struct opengl_driver_funcs *display_driver_funcs = &nulldrv_funcs; -static UINT display_formats_count, display_onscreen_count; -static UINT memory_formats_count, memory_onscreen_count; +static const struct opengl_driver_funcs *driver_funcs = &nulldrv_funcs; +static UINT formats_count, onscreen_count;
static char wgl_extensions[4096];
@@ -919,7 +687,7 @@ static int get_dc_pixel_format( HDC hdc, BOOL internal ) /* Offscreen formats can't be used with traditional WGL calls. As has been * verified on Windows GetPixelFormat doesn't fail but returns 1. */ - if (is_display && ret >= 0 && ret > display_onscreen_count) ret = 1; + if (is_display && ret >= 0 && ret > onscreen_count) ret = 1; } else { @@ -1010,11 +778,10 @@ static void destroy_memory_pbuffer( struct wgl_context *context, HDC hdc )
static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) { - const struct opengl_funcs *funcs; + const struct opengl_funcs *funcs = &display_funcs; UINT total, onscreen; HWND hwnd;
- if (!(funcs = get_dc_funcs( hdc, NULL ))) return FALSE; funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); if (new_format <= 0 || new_format > total) return FALSE;
@@ -1031,7 +798,7 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal );
if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format; - if (!display_driver_funcs->p_set_pixel_format( hwnd, old_format, new_format, internal )) return FALSE; + if (!driver_funcs->p_set_pixel_format( hwnd, old_format, new_format, internal )) return FALSE; return set_window_pixel_format( hwnd, new_format, internal ); }
@@ -1049,49 +816,29 @@ static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) return set_dc_pixel_format( hdc, format, TRUE ); }
-static PROC win32u_memory_wglGetProcAddress( const char *name ) -{ - PROC ret; - if (!strncmp( name, "wgl", 3 )) return NULL; - ret = memory_driver_funcs->p_get_proc_address( name ); - TRACE( "%s -> %p\n", debugstr_a(name), ret ); - return ret; -} - -static PROC win32u_display_wglGetProcAddress( const char *name ) +static PROC win32u_wglGetProcAddress( const char *name ) { PROC ret; if (!strncmp( name, "wgl", 3 )) return NULL; - ret = display_driver_funcs->p_get_proc_address( name ); + ret = driver_funcs->p_get_proc_address( name ); TRACE( "%s -> %p\n", debugstr_a(name), ret ); return ret; }
-static void win32u_display_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, - UINT *num_formats, UINT *num_onscreen_formats ) -{ - UINT i = 0; - - if (formats) while (i < max_formats && display_driver_funcs->p_describe_pixel_format( i + 1, &formats[i] )) i++; - *num_formats = display_formats_count; - *num_onscreen_formats = display_onscreen_count; -} - -static void win32u_memory_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, - UINT *num_formats, UINT *num_onscreen_formats ) +static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max_formats, + UINT *num_formats, UINT *num_onscreen_formats ) { UINT i = 0;
- if (formats) while (i < max_formats && memory_driver_funcs->p_describe_pixel_format( i + 1, &formats[i] )) i++; - *num_formats = memory_formats_count; - *num_onscreen_formats = memory_onscreen_count; + if (formats) while (i < max_formats && driver_funcs->p_describe_pixel_format( i + 1, &formats[i] )) i++; + *num_formats = formats_count; + *num_onscreen_formats = onscreen_count; }
static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, const int *attribs ) { void *shared_private = shared ? shared->driver_private : NULL; - const struct opengl_driver_funcs *driver_funcs; - const struct opengl_funcs *funcs; + const struct opengl_funcs *funcs = &display_funcs; struct wgl_context *context; int format;
@@ -1103,9 +850,6 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, return NULL; }
- if (!(funcs = get_dc_funcs( hdc, NULL ))) return NULL; - driver_funcs = funcs == &display_funcs ? display_driver_funcs : memory_driver_funcs; - if (!(context = calloc( 1, sizeof(*context) ))) return NULL; context->driver_funcs = driver_funcs; context->funcs = funcs; @@ -1154,7 +898,6 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct { HDC hdc = draw_hdc, prev_draw = NtCurrentTeb()->glReserved1[0]; struct wgl_context *prev_context = NtCurrentTeb()->glContext; - const struct opengl_driver_funcs *funcs; int format;
TRACE( "draw_hdc %p, read_hdc %p, context %p\n", draw_hdc, read_hdc, context ); @@ -1164,8 +907,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!context) { if (!(context = prev_context)) return TRUE; - funcs = context->driver_funcs; - if (!funcs->p_context_make_current( NULL, NULL, NULL )) return FALSE; + if (!driver_funcs->p_context_make_current( NULL, NULL, NULL )) return FALSE; NtCurrentTeb()->glContext = NULL; return TRUE; } @@ -1189,8 +931,7 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct draw_hdc = read_hdc = context->memory_pbuffer->hdc; }
- funcs = context->driver_funcs; - if (!funcs->p_context_make_current( draw_hdc, read_hdc, context->driver_private )) return FALSE; + if (!driver_funcs->p_context_make_current( draw_hdc, read_hdc, context->driver_private )) return FALSE; NtCurrentTeb()->glContext = context; if (context->memory_pbuffer) flush_memory_pbuffer( context, hdc, TRUE, NULL ); return TRUE; @@ -1204,14 +945,13 @@ static BOOL win32u_wglMakeCurrent( HDC hdc, struct wgl_context *context ) static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int width, int height, const int *attribs ) { + const struct opengl_funcs *funcs = &display_funcs; UINT total, onscreen, size, max_level = 0; - const struct opengl_funcs *funcs; struct wgl_pbuffer *pbuffer; BOOL largest = FALSE;
TRACE( "(%p, %d, %d, %d, %p)\n", hdc, format, width, height, attribs );
- if (!(funcs = get_dc_funcs( hdc, NULL ))) return FALSE; funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); if (format <= 0 || format > total) { @@ -1231,7 +971,7 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int return NULL; } NtGdiSetPixelFormat( pbuffer->hdc, format ); - pbuffer->driver_funcs = display_driver_funcs; + pbuffer->driver_funcs = driver_funcs; pbuffer->funcs = funcs; pbuffer->width = width; pbuffer->height = height; @@ -1645,17 +1385,10 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) static BOOL win32u_wglSwapBuffers( HDC hdc ) { struct wgl_context *context = NtCurrentTeb()->glContext; - const struct opengl_funcs *funcs; + const struct opengl_funcs *funcs = &display_funcs; int interval; HWND hwnd;
- if (!(funcs = get_dc_funcs( hdc, NULL ))) - { - RtlSetLastWin32Error( ERROR_DC_NOT_FOUND ); - return FALSE; - } - context->driver_funcs = funcs == &display_funcs ? display_driver_funcs : memory_driver_funcs; - if (!(hwnd = NtUserWindowFromDC( hdc ))) interval = 0; else interval = get_window_swap_interval( hwnd );
@@ -1709,58 +1442,31 @@ static int win32u_wglGetSwapIntervalEXT(void) return interval; }
-static void init_opengl_funcs( struct opengl_funcs *funcs, const struct opengl_driver_funcs *driver_funcs ) -{ -#define USE_GL_FUNC(func) \ - if (!funcs->p_##func && !(funcs->p_##func = driver_funcs->p_get_proc_address( #func ))) \ - { \ - WARN( "%s not found for memory DCs.\n", #func ); \ - funcs->p_##func = default_funcs->p_##func; \ - } - ALL_GL_FUNCS -#undef USE_GL_FUNC -} - -static inline void memory_funcs_init(void) -{ - if (!osmesa_get_wgl_driver( &memory_driver_funcs )) WARN( "Failed to initialize OSMesa functions\n" ); - - memory_formats_count = memory_driver_funcs->p_init_pixel_formats( &memory_onscreen_count ); - init_opengl_funcs( &memory_funcs, memory_driver_funcs ); - - memory_funcs.p_wglGetProcAddress = win32u_memory_wglGetProcAddress; - memory_funcs.p_get_pixel_formats = win32u_memory_get_pixel_formats; - - memory_funcs.p_wglGetPixelFormat = win32u_wglGetPixelFormat; - memory_funcs.p_wglSetPixelFormat = win32u_wglSetPixelFormat; - - memory_funcs.p_wglCreateContext = win32u_wglCreateContext; - memory_funcs.p_wglDeleteContext = win32u_wglDeleteContext; - memory_funcs.p_wglCopyContext = (void *)1; /* never called */ - memory_funcs.p_wglShareLists = (void *)1; /* never called */ - memory_funcs.p_wglMakeCurrent = win32u_wglMakeCurrent; - - memory_funcs.p_wglSwapBuffers = win32u_wglSwapBuffers; - memory_funcs.p_wgl_context_flush = win32u_wgl_context_flush; -} - static void display_funcs_init(void) { UINT status;
- if (egl_init( &display_driver_funcs )) TRACE( "Initialized EGL library\n" ); + if (egl_init( &driver_funcs )) TRACE( "Initialized EGL library\n" );
- if ((status = user_driver->pOpenGLInit( WINE_OPENGL_DRIVER_VERSION, &display_funcs, &display_driver_funcs ))) + if ((status = user_driver->pOpenGLInit( WINE_OPENGL_DRIVER_VERSION, &display_funcs, &driver_funcs ))) WARN( "Failed to initialize the driver OpenGL functions, status %#x\n", status ); - init_egl_platform( &display_egl, &display_funcs, display_driver_funcs ); + init_egl_platform( &display_egl, &display_funcs, driver_funcs ); + + formats_count = driver_funcs->p_init_pixel_formats( &onscreen_count );
- display_formats_count = display_driver_funcs->p_init_pixel_formats( &display_onscreen_count ); - init_opengl_funcs( &display_funcs, display_driver_funcs ); +#define USE_GL_FUNC(func) \ + if (!display_funcs.p_##func && !(display_funcs.p_##func = driver_funcs->p_get_proc_address( #func ))) \ + { \ + WARN( "%s not found for memory DCs.\n", #func ); \ + display_funcs.p_##func = default_funcs->p_##func; \ + } + ALL_GL_FUNCS +#undef USE_GL_FUNC
- display_funcs.p_wglGetProcAddress = win32u_display_wglGetProcAddress; - display_funcs.p_get_pixel_formats = win32u_display_get_pixel_formats; + display_funcs.p_wglGetProcAddress = win32u_wglGetProcAddress; + display_funcs.p_get_pixel_formats = win32u_get_pixel_formats;
- strcpy( wgl_extensions, display_driver_funcs->p_init_wgl_extensions( &display_funcs ) ); + strcpy( wgl_extensions, driver_funcs->p_init_wgl_extensions( &display_funcs ) ); display_funcs.p_wglGetPixelFormat = win32u_wglGetPixelFormat; display_funcs.p_wglSetPixelFormat = win32u_wglSetPixelFormat;
@@ -1823,32 +1529,15 @@ static void display_funcs_init(void) display_funcs.p_wglGetSwapIntervalEXT = win32u_wglGetSwapIntervalEXT; }
-static const struct opengl_funcs *get_dc_funcs( HDC hdc, const struct opengl_funcs *null_funcs ) -{ - DWORD is_disabled, is_display, is_memdc; - DC *dc; - - if (!(dc = get_dc_ptr( hdc ))) return NULL; - is_memdc = get_gdi_object_type( hdc ) == NTGDI_OBJ_MEMDC; - is_display = dc->is_display; - is_disabled = dc->attr->disabled; - release_dc_ptr( dc ); - - if (is_disabled) return NULL; - if (is_display || is_memdc) - { - static pthread_once_t display_init_once = PTHREAD_ONCE_INIT; - pthread_once( &display_init_once, display_funcs_init ); - return &display_funcs; - } - return NULL; -} - /*********************************************************************** * __wine_get_wgl_driver (win32u.@) */ const struct opengl_funcs *__wine_get_wgl_driver( HDC hdc, UINT version, const struct opengl_funcs *null_funcs ) { + static pthread_once_t init_once = PTHREAD_ONCE_INIT; + DWORD is_disabled, is_display, is_memdc; + DC *dc; + if (version != WINE_OPENGL_DRIVER_VERSION) { ERR( "version mismatch, opengl32 wants %u but dibdrv has %u\n", @@ -1857,5 +1546,15 @@ const struct opengl_funcs *__wine_get_wgl_driver( HDC hdc, UINT version, const s }
InterlockedExchangePointer( (void *)&default_funcs, (void *)null_funcs ); - return get_dc_funcs( hdc, null_funcs ); + + if (!(dc = get_dc_ptr( hdc ))) return NULL; + is_memdc = get_gdi_object_type( hdc ) == NTGDI_OBJ_MEMDC; + is_display = dc->is_display; + is_disabled = dc->attr->disabled; + release_dc_ptr( dc ); + + if (is_disabled) return NULL; + if (!is_display && !is_memdc) return NULL; + pthread_once( &init_once, display_funcs_init ); + return &display_funcs; } diff --git a/tools/gitlab/image.docker b/tools/gitlab/image.docker index ac59ee8937b..0a1d9f788b7 100644 --- a/tools/gitlab/image.docker +++ b/tools/gitlab/image.docker @@ -29,7 +29,6 @@ RUN export DEBIAN_FRONTEND=noninteractive; \ libgphoto2-dev:amd64 libgphoto2-dev:i386 \ libice-dev:amd64 libice-dev:i386 \ libkrb5-dev:amd64 libkrb5-dev:i386 \ - libosmesa6-dev:amd64 libosmesa6-dev:i386 \ libpcap-dev:amd64 libpcap-dev:i386 \ libpcsclite-dev:amd64 \ libpulse-dev:amd64 libpulse-dev:i386 \
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/opengl.c | 57 +++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 6b0fa5bd481..b997ea4a8a8 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -41,8 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wgl);
struct wgl_context { - const struct opengl_driver_funcs *driver_funcs; - const struct opengl_funcs *funcs; void *driver_private; int pixel_format;
@@ -52,8 +50,6 @@ struct wgl_context
struct wgl_pbuffer { - const struct opengl_driver_funcs *driver_funcs; - const struct opengl_funcs *funcs; void *driver_private;
HDC hdc; @@ -770,7 +766,7 @@ static BOOL flush_memory_pbuffer( struct wgl_context *context, HDC hdc, BOOL wri
static void destroy_memory_pbuffer( struct wgl_context *context, HDC hdc ) { - const struct opengl_funcs *funcs = context->funcs; + const struct opengl_funcs *funcs = &display_funcs; flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFinish ); funcs->p_wglDestroyPbufferARB( context->memory_pbuffer ); context->memory_pbuffer = NULL; @@ -838,7 +834,6 @@ static void win32u_get_pixel_formats( struct wgl_pixel_format *formats, UINT max static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, const int *attribs ) { void *shared_private = shared ? shared->driver_private : NULL; - const struct opengl_funcs *funcs = &display_funcs; struct wgl_context *context; int format;
@@ -851,11 +846,9 @@ static struct wgl_context *context_create( HDC hdc, struct wgl_context *shared, }
if (!(context = calloc( 1, sizeof(*context) ))) return NULL; - context->driver_funcs = driver_funcs; - context->funcs = funcs; context->pixel_format = format;
- if (!context->driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) + if (!driver_funcs->p_context_create( hdc, format, shared_private, attribs, &context->driver_private )) { free( context ); return NULL; @@ -883,12 +876,11 @@ static struct wgl_context *win32u_wglCreateContext( HDC hdc )
static BOOL win32u_wglDeleteContext( struct wgl_context *context ) { - const struct opengl_driver_funcs *funcs = context->driver_funcs; BOOL ret;
TRACE( "context %p\n", context );
- ret = funcs->p_context_destroy( context->driver_private ); + ret = driver_funcs->p_context_destroy( context->driver_private ); free( context );
return ret; @@ -971,8 +963,6 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int return NULL; } NtGdiSetPixelFormat( pbuffer->hdc, format ); - pbuffer->driver_funcs = driver_funcs; - pbuffer->funcs = funcs; pbuffer->width = width; pbuffer->height = height; pbuffer->mipmap_level = -1; @@ -1060,9 +1050,9 @@ static struct wgl_pbuffer *win32u_wglCreatePbufferARB( HDC hdc, int format, int } }
- if (pbuffer->driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, - pbuffer->texture_target, max_level, &pbuffer->width, - &pbuffer->height, &pbuffer->driver_private )) + if (driver_funcs->p_pbuffer_create( pbuffer->hdc, format, largest, pbuffer->texture_format, + pbuffer->texture_target, max_level, &pbuffer->width, + &pbuffer->height, &pbuffer->driver_private )) return pbuffer;
failed: @@ -1074,10 +1064,12 @@ failed:
static BOOL win32u_wglDestroyPbufferARB( struct wgl_pbuffer *pbuffer ) { + const struct opengl_funcs *funcs = &display_funcs; + TRACE( "pbuffer %p\n", pbuffer );
- pbuffer->driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->driver_private ); - if (pbuffer->tmp_context) pbuffer->funcs->p_wglDeleteContext( pbuffer->tmp_context ); + driver_funcs->p_pbuffer_destroy( pbuffer->hdc, pbuffer->driver_private ); + if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); NtGdiDeleteObjectApp( pbuffer->hdc ); free( pbuffer );
@@ -1199,6 +1191,7 @@ static GLenum binding_from_target( GLenum target )
static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) { + const struct opengl_funcs *funcs = &display_funcs; HDC prev_draw = NtCurrentTeb()->glReserved1[0], prev_read = NtCurrentTeb()->glReserved1[1]; int prev_texture = 0, format = win32u_wglGetPixelFormat( pbuffer->hdc ); struct wgl_context *prev_context = NtCurrentTeb()->glContext; @@ -1214,7 +1207,7 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) return GL_FALSE; }
- if (!pbuffer->driver_funcs->p_describe_pixel_format( format, &desc )) + if (!driver_funcs->p_describe_pixel_format( format, &desc )) { RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); return FALSE; @@ -1257,29 +1250,29 @@ static BOOL win32u_wglBindTexImageARB( struct wgl_pbuffer *pbuffer, int buffer ) return GL_FALSE; }
- if ((ret = pbuffer->driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, source )) != -1) + if ((ret = driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, source )) != -1) return ret;
if (!pbuffer->tmp_context || pbuffer->prev_context != prev_context) { - if (pbuffer->tmp_context) pbuffer->funcs->p_wglDeleteContext( pbuffer->tmp_context ); - pbuffer->tmp_context = pbuffer->funcs->p_wglCreateContextAttribsARB( pbuffer->hdc, prev_context, NULL ); + if (pbuffer->tmp_context) funcs->p_wglDeleteContext( pbuffer->tmp_context ); + pbuffer->tmp_context = funcs->p_wglCreateContextAttribsARB( pbuffer->hdc, prev_context, NULL ); pbuffer->prev_context = prev_context; }
- pbuffer->funcs->p_glGetIntegerv( binding_from_target( pbuffer->texture_target ), &prev_texture ); + funcs->p_glGetIntegerv( binding_from_target( pbuffer->texture_target ), &prev_texture );
/* Switch to our pbuffer */ - pbuffer->funcs->p_wglMakeCurrent( pbuffer->hdc, pbuffer->tmp_context ); + funcs->p_wglMakeCurrent( pbuffer->hdc, pbuffer->tmp_context );
/* Make sure that the prev_texture is set as the current texture state isn't shared * between contexts. After that copy the pbuffer texture data. */ - pbuffer->funcs->p_glBindTexture( pbuffer->texture_target, prev_texture ); - pbuffer->funcs->p_glCopyTexImage2D( pbuffer->texture_target, 0, pbuffer->texture_format, 0, 0, + funcs->p_glBindTexture( pbuffer->texture_target, prev_texture ); + funcs->p_glCopyTexImage2D( pbuffer->texture_target, 0, pbuffer->texture_format, 0, 0, pbuffer->width, pbuffer->height, 0 );
/* Switch back to the original drawable and context */ - pbuffer->funcs->p_wglMakeContextCurrentARB( prev_draw, prev_read, prev_context ); + funcs->p_wglMakeContextCurrentARB( prev_draw, prev_read, prev_context ); return GL_TRUE; }
@@ -1293,7 +1286,7 @@ static BOOL win32u_wglReleaseTexImageARB( struct wgl_pbuffer *pbuffer, int buffe return GL_FALSE; }
- return !!pbuffer->driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, GL_NONE ); + return !!driver_funcs->p_pbuffer_bind( pbuffer->hdc, pbuffer->driver_private, GL_NONE ); }
static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const int *attribs ) @@ -1351,8 +1344,8 @@ static BOOL win32u_wglSetPbufferAttribARB( struct wgl_pbuffer *pbuffer, const in } }
- return pbuffer->driver_funcs->p_pbuffer_updated( pbuffer->hdc, pbuffer->driver_private, - pbuffer->cube_face, max( pbuffer->mipmap_level, 0 ) ); + return driver_funcs->p_pbuffer_updated( pbuffer->hdc, pbuffer->driver_private, + pbuffer->cube_face, max( pbuffer->mipmap_level, 0 ) ); }
static int get_window_swap_interval( HWND hwnd ) @@ -1379,7 +1372,7 @@ static BOOL win32u_wgl_context_flush( struct wgl_context *context, void (*flush) TRACE( "context %p, hwnd %p, draw_hdc %p, interval %d, flush %p\n", context, hwnd, draw_hdc, interval, flush );
if (context->memory_pbuffer) return flush_memory_pbuffer( context, draw_hdc, FALSE, flush ); - return context->driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); + return driver_funcs->p_context_flush( context->driver_private, hwnd, draw_hdc, interval, flush ); }
static BOOL win32u_wglSwapBuffers( HDC hdc ) @@ -1393,7 +1386,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc ) else interval = get_window_swap_interval( hwnd );
if (context->memory_pbuffer) return flush_memory_pbuffer( context, hdc, FALSE, funcs->p_glFlush ); - return context->driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); + return driver_funcs->p_swap_buffers( context ? context->driver_private : NULL, hwnd, hdc, interval ); }
static BOOL win32u_wglSwapIntervalEXT( int interval )
v4: Remove unnecessary !8202 commit which was already merged.
So, is there something wrong about this?
That's a lot of changes for a single MR...