As an intermediate step on the way to !5388, I wanted to focus on the infrastructure that will allow us to pass pixel format information from the driver to the PE side. This MR introduces the mechanism to perform this information exchange and uses it to implement `wglDescribePixelFormat` on the PE side. In the current RFC state this MR:
1. Introduces `p_get_pixel_format` driver API to allow drivers to provide pixel format information. 2. Implements `wglDescribePixelFormat` on the PE side using the pixel format information. If the driver doesn't implement `p_get_pixel_format` we fall back to the `wglDescribePixelFormat` driver implementation (temporary measure until all drivers are updated). 3. Caches pixel format information in `NtCurrentTeb()->glReserved1[]`. 4. Implements `p_get_pixel_format` API and removes the custom `wglDescribePixelFormat` for winewayland.
At this point would like to get some more feedback about this approach and the technical details. If the direction seems promising, here are the next steps to get to a final MR:
1. Implement `p_get_pixel_format` for winex11, winemac and dibdrv and remove their custom `wglDescribePixelFormat` implementations. 2. Remove the `wglDescribePixelFormat` driver API.
Thanks!
-- v3: winex11.drv: Remove unnecessary parameter from describe_pixel_format. winex11.drv: Enable wglDescribePixelFormat through p_get_pixel_formats.
From: Alexandros Frantzis alexandros.frantzis@collabora.com
We want to use wgl_pixel_format in the wgl driver API. --- dlls/winex11.drv/opengl.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 68c8214b835..2482a07212a 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -184,7 +184,7 @@ static char wglExtensions[4096]; static int glxVersion[2]; static int glx_opcode;
-struct wgl_pixel_format +struct glx_pixel_format { GLXFBConfig fbconfig; XVisualInfo *visual; @@ -199,7 +199,7 @@ struct wgl_context BOOL has_been_current; BOOL sharing; BOOL gl3_context; - const struct wgl_pixel_format *fmt; + 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; @@ -226,7 +226,7 @@ struct gl_drawable Window window; /* window if drawable is a GLXWindow */ Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ - const struct wgl_pixel_format *format; /* pixel format for the drawable */ + const struct glx_pixel_format *format; /* pixel format for the drawable */ SIZE pixmap_size; /* pixmap size for GLXPixmap drawables */ int swap_interval; BOOL refresh_swap_interval; @@ -236,7 +236,7 @@ struct gl_drawable struct wgl_pbuffer { struct gl_drawable *gl; - const struct wgl_pixel_format* fmt; + const struct glx_pixel_format* fmt; int width; int height; int* attribList; @@ -268,7 +268,7 @@ static XContext gl_pbuffer_context;
static struct list context_list = LIST_INIT( context_list ); static struct list pbuffer_list = LIST_INIT( pbuffer_list ); -static struct wgl_pixel_format *pixel_formats; +static struct glx_pixel_format *pixel_formats; static int nb_pixel_formats, nb_onscreen_formats; static BOOL use_render_texture_emulation = TRUE;
@@ -1000,7 +1000,7 @@ static BOOL check_fbconfig_bitmap_capability(Display *display, GLXFBConfig fbcon
static void init_pixel_formats( Display *display ) { - struct wgl_pixel_format *list; + struct glx_pixel_format *list; int size = 0, onscreen_size = 0; int fmt_id, nCfgs, i, run, bmp_formats; GLXFBConfig* cfgs; @@ -1119,7 +1119,7 @@ static inline BOOL is_onscreen_pixel_format( int format ) return format > 0 && format <= nb_onscreen_formats; }
-static inline int pixel_format_index( const struct wgl_pixel_format *format ) +static inline int pixel_format_index( const struct glx_pixel_format *format ) { return format - pixel_formats + 1; } @@ -1129,7 +1129,7 @@ static inline int pixel_format_index( const struct wgl_pixel_format *format ) * Wine's main visual and offscreen formats (if they are available). * This function converts a WGL format to its corresponding GLX one. */ -static const struct wgl_pixel_format *get_pixel_format(Display *display, int iPixelFormat, BOOL AllowOffscreen) +static const struct glx_pixel_format *get_pixel_format(Display *display, int iPixelFormat, BOOL AllowOffscreen) { /* Check if the pixelformat is valid. Note that it is legal to pass an invalid * iPixelFormat in case of probing the number of pixelformats. @@ -1308,7 +1308,7 @@ static GLXContext create_glxcontext(Display *display, struct wgl_context *contex /*********************************************************************** * create_gl_drawable */ -static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel_format *format, BOOL known_child, +static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel_format *format, BOOL known_child, BOOL mutable_pf ) { struct gl_drawable *gl, *prev; @@ -1400,7 +1400,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel /*********************************************************************** * set_win_format */ -static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format, BOOL internal ) +static BOOL set_win_format( HWND hwnd, const struct glx_pixel_format *format, BOOL internal ) { struct gl_drawable *old, *gl;
@@ -1431,7 +1431,7 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format, BO
static BOOL set_pixel_format( HDC hdc, int format, BOOL internal ) { - const struct wgl_pixel_format *fmt; + const struct glx_pixel_format *fmt; int value; HWND hwnd = NtUserWindowFromDC( hdc ); int prev; @@ -1562,7 +1562,7 @@ static int describe_pixel_format( int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd, /*XVisualInfo *vis;*/ int value; int rb,gb,bb,ab; - const struct wgl_pixel_format *fmt; + const struct glx_pixel_format *fmt;
if (!has_opengl()) return 0;
@@ -2165,7 +2165,7 @@ static struct wgl_pbuffer *X11DRV_wglCreatePbufferARB( HDC hdc, int iPixelFormat const int *piAttribList ) { struct wgl_pbuffer* object; - const struct wgl_pixel_format *fmt; + const struct glx_pixel_format *fmt; int attribs[256]; int nAttribs = 0;
@@ -2708,7 +2708,7 @@ static BOOL X11DRV_wglGetPixelFormatAttribivARB( HDC hdc, int iPixelFormat, int UINT nAttributes, const int *piAttributes, int *piValues ) { UINT i; - const struct wgl_pixel_format *fmt; + const struct glx_pixel_format *fmt; int hTest; int tmp; int curGLXAttr = 0;
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Introduce a new wgl driver callback function to allow the driver to provide a complete list of all pixel formats and their attributes. If the driver provides the information use it to implement wglDescribePixelFormat. --- dlls/opengl32/make_opengl | 24 ++++++++++++++++++- dlls/opengl32/thunks.c | 9 ------- dlls/opengl32/unix_thunks.c | 4 ++++ dlls/opengl32/unix_wgl.c | 35 +++++++++++++++++++++++++++ dlls/opengl32/unixlib.h | 11 +++++++++ dlls/opengl32/wgl.c | 47 +++++++++++++++++++++++++++++++++++++ include/wine/wgl_driver.h | 8 ++++++- 7 files changed, 127 insertions(+), 11 deletions(-)
diff --git a/dlls/opengl32/make_opengl b/dlls/opengl32/make_opengl index ec6c7cbe4df..215caad4639 100755 --- a/dlls/opengl32/make_opengl +++ b/dlls/opengl32/make_opengl @@ -176,6 +176,7 @@ my %manual_win_thunks = "glUnmapBufferARB" => 1, "glUnmapNamedBuffer" => 1, "glUnmapNamedBufferEXT" => 1, + "wglDescribePixelFormat" => 1, "wglGetCurrentReadDCARB" => 1, "wglGetExtensionsStringARB" => 1, "wglGetExtensionsStringEXT" => 1, @@ -880,6 +881,11 @@ printf HEADER "#define WINE_WGL_DRIVER_VERSION %u\n\n", $wgl_version + 1; print HEADER "struct wgl_context;\n"; print HEADER "struct wgl_pbuffer;\n\n";
+print HEADER "struct wgl_pixel_format\n"; +print HEADER "{\n"; +print HEADER " PIXELFORMATDESCRIPTOR pfd;\n"; +print HEADER "};\n\n"; + print HEADER "struct opengl_funcs\n{\n"; print HEADER " struct\n {\n"; foreach (sort keys %wgl_functions) @@ -889,6 +895,7 @@ foreach (sort keys %wgl_functions) my $func_ret = get_func_ret( $wgl_functions{$_}, 1 ); printf HEADER " %-10s (WINE_GLAPI *p_$_)($decl_args);\n", $func_ret; } +printf HEADER " %-10s (WINE_GLAPI *p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats );\n", "void"; print HEADER " } wgl;\n\n";
print HEADER " struct\n {\n"; @@ -1012,10 +1019,21 @@ foreach (sort keys %ext_functions) print OUT generate_func_params($_, $ext_functions{$_}); }
+print OUT "struct get_pixel_formats_params\n"; +print OUT "{\n"; +print OUT " TEB *teb;\n"; +print OUT " HDC hdc;\n"; +print OUT " struct wgl_pixel_format *formats;\n"; +print OUT " unsigned int max_formats;\n"; +print OUT " unsigned int num_formats;\n"; +print OUT " unsigned int num_onscreen_formats;\n"; +print OUT "};\n\n"; + print OUT "enum unix_funcs\n"; print OUT "{\n"; print OUT " unix_thread_attach,\n"; print OUT " unix_process_detach,\n"; +print OUT " unix_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1139,6 +1157,7 @@ print OUT "#endif\n\n";
print OUT "extern NTSTATUS thread_attach( void *args );\n"; print OUT "extern NTSTATUS process_detach( void *args );\n"; +print OUT "extern NTSTATUS get_pixel_formats( void *args );\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1185,6 +1204,7 @@ print OUT "const unixlib_entry_t __wine_unix_call_funcs[] =\n"; print OUT "{\n"; print OUT " &thread_attach,\n"; print OUT " &process_detach,\n"; +print OUT " &get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; @@ -1206,7 +1226,8 @@ print OUT "\n"; print OUT "#ifdef _WIN64\n\n"; print OUT "typedef ULONG PTR32;\n\n"; print OUT "extern NTSTATUS wow64_thread_attach( void *args );\n"; -print OUT "extern NTSTATUS wow64_process_detach( void *args );\n\n"; +print OUT "extern NTSTATUS wow64_process_detach( void *args );\n"; +print OUT "extern NTSTATUS wow64_get_pixel_formats( void *args );\n\n";
foreach (sort keys %wgl_functions) { @@ -1250,6 +1271,7 @@ print OUT "\nconst unixlib_entry_t __wine_unix_call_wow64_funcs[] =\n"; print OUT "{\n"; print OUT " wow64_thread_attach,\n"; print OUT " wow64_process_detach,\n"; +print OUT " wow64_get_pixel_formats,\n"; foreach (sort keys %wgl_functions) { next if defined $manual_win_functions{$_}; diff --git a/dlls/opengl32/thunks.c b/dlls/opengl32/thunks.c index c20abdf5488..49f32461de5 100644 --- a/dlls/opengl32/thunks.c +++ b/dlls/opengl32/thunks.c @@ -43,15 +43,6 @@ BOOL WINAPI wglDeleteContext( HGLRC oldContext ) return args.ret; }
-int WINAPI wglDescribePixelFormat( HDC hdc, int ipfd, UINT cjpfd, PIXELFORMATDESCRIPTOR *ppfd ) -{ - struct wglDescribePixelFormat_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .ipfd = ipfd, .cjpfd = cjpfd, .ppfd = ppfd }; - NTSTATUS status; - TRACE( "hdc %p, ipfd %d, cjpfd %u, ppfd %p\n", hdc, ipfd, cjpfd, ppfd ); - if ((status = UNIX_CALL( wglDescribePixelFormat, &args ))) WARN( "wglDescribePixelFormat returned %#lx\n", status ); - return args.ret; -} - BOOL WINAPI wglMakeCurrent( HDC hDc, HGLRC newContext ) { struct wglMakeCurrent_params args = { .teb = NtCurrentTeb(), .hDc = hDc, .newContext = newContext }; diff --git a/dlls/opengl32/unix_thunks.c b/dlls/opengl32/unix_thunks.c index a2889e7cd32..abb436bdc05 100644 --- a/dlls/opengl32/unix_thunks.c +++ b/dlls/opengl32/unix_thunks.c @@ -24,6 +24,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(opengl);
extern NTSTATUS thread_attach( void *args ); extern NTSTATUS process_detach( void *args ); +extern NTSTATUS get_pixel_formats( void *args ); extern NTSTATUS wgl_wglCopyContext( void *args ); extern NTSTATUS wgl_wglCreateContext( void *args ); extern NTSTATUS wgl_wglDeleteContext( void *args ); @@ -24206,6 +24207,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { &thread_attach, &process_detach, + &get_pixel_formats, &wgl_wglCopyContext, &wgl_wglCreateContext, &wgl_wglDeleteContext, @@ -27254,6 +27256,7 @@ typedef ULONG PTR32;
extern NTSTATUS wow64_thread_attach( void *args ); extern NTSTATUS wow64_process_detach( void *args ); +extern NTSTATUS wow64_get_pixel_formats( void *args );
static NTSTATUS wow64_wgl_wglCopyContext( void *args ) { @@ -92326,6 +92329,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { wow64_thread_attach, wow64_process_detach, + wow64_get_pixel_formats, wow64_wgl_wglCopyContext, wow64_wgl_wglCreateContext, wow64_wgl_wglDeleteContext, diff --git a/dlls/opengl32/unix_wgl.c b/dlls/opengl32/unix_wgl.c index b75a940d1d6..093dab4efb8 100644 --- a/dlls/opengl32/unix_wgl.c +++ b/dlls/opengl32/unix_wgl.c @@ -1157,6 +1157,16 @@ NTSTATUS process_detach( void *args ) return STATUS_SUCCESS; }
+NTSTATUS get_pixel_formats( void *args ) +{ + struct get_pixel_formats_params *params = args; + const struct opengl_funcs *funcs = get_dc_funcs( params->hdc ); + if (!funcs || !funcs->wgl.p_get_pixel_formats) return STATUS_NOT_IMPLEMENTED; + funcs->wgl.p_get_pixel_formats( params->formats, params->max_formats, + ¶ms->num_formats, ¶ms->num_onscreen_formats ); + return STATUS_SUCCESS; +} + #ifdef _WIN64
typedef ULONG PTR32; @@ -2239,4 +2249,29 @@ NTSTATUS wow64_process_detach( void *args ) return STATUS_SUCCESS; }
+NTSTATUS wow64_get_pixel_formats( void *args ) +{ + struct + { + PTR32 teb; + PTR32 hdc; + PTR32 formats; + UINT max_formats; + UINT num_formats; + UINT num_onscreen_formats; + } *params32 = args; + struct get_pixel_formats_params params = + { + .teb = get_teb64(params32->teb), + .hdc = ULongToPtr(params32->hdc), + .formats = ULongToPtr(params32->formats), + .max_formats = params32->max_formats, + }; + NTSTATUS status; + status = get_pixel_formats( ¶ms ); + params32->num_formats = params.num_formats; + params32->num_onscreen_formats = params.num_onscreen_formats; + return status; +} + #endif diff --git a/dlls/opengl32/unixlib.h b/dlls/opengl32/unixlib.h index 96e42a39b17..3e1e6206478 100644 --- a/dlls/opengl32/unixlib.h +++ b/dlls/opengl32/unixlib.h @@ -25331,10 +25331,21 @@ struct wglSwapIntervalEXT_params BOOL ret; };
+struct get_pixel_formats_params +{ + TEB *teb; + HDC hdc; + struct wgl_pixel_format *formats; + unsigned int max_formats; + unsigned int num_formats; + unsigned int num_onscreen_formats; +}; + enum unix_funcs { unix_thread_attach, unix_process_detach, + unix_get_pixel_formats, unix_wglCopyContext, unix_wglCreateContext, unix_wglDeleteContext, diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index c02436f1675..c7b0bbfdf34 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -35,6 +35,7 @@
#include "wine/glu.h" #include "wine/debug.h" +#include "wine/wgl_driver.h"
WINE_DEFAULT_DEBUG_CHANNEL(opengl); WINE_DECLARE_DEBUG_CHANNEL(fps); @@ -294,6 +295,52 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd) return best_format; }
+static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, + UINT *num_onscreen_formats ) +{ + struct get_pixel_formats_params args = { .teb = NtCurrentTeb(), .hdc = hdc }; + NTSTATUS status; + + if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; + if (!(args.formats = malloc( sizeof(*args.formats) * args.num_formats ))) goto error; + args.max_formats = args.num_formats; + if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; + + *num_formats = args.num_formats; + *num_onscreen_formats = args.num_onscreen_formats; + return args.formats; + +error: + *num_formats = *num_onscreen_formats = 0; + free( args.formats ); + return NULL; +} + +INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDESCRIPTOR *ppfd ) +{ + struct wglDescribePixelFormat_params args = { .teb = NtCurrentTeb(), .hdc = hdc, .ipfd = index, .cjpfd = size, .ppfd = ppfd }; + NTSTATUS status; + struct wgl_pixel_format *formats; + UINT num_formats, num_onscreen_formats; + + TRACE( "hdc %p, index %d, size %u, ppfd %p\n", hdc, index, index, ppfd ); + + if ((formats = get_pixel_formats( hdc, &num_formats, &num_onscreen_formats ))) + { + if (!ppfd) return num_onscreen_formats; + if (size < sizeof(*ppfd)) return 0; + if (index <= 0 || index > num_onscreen_formats) return 0; + + *ppfd = formats[index - 1].pfd; + + free( formats ); + return num_onscreen_formats; + } + + if ((status = UNIX_CALL( wglDescribePixelFormat, &args ))) WARN( "wglDescribePixelFormat returned %#lx\n", status ); + return args.ret; +} + /*********************************************************************** * wglGetPixelFormat (OPENGL32.@) */ diff --git a/include/wine/wgl_driver.h b/include/wine/wgl_driver.h index 93ebe7d7f46..5bf72a7f269 100644 --- a/include/wine/wgl_driver.h +++ b/include/wine/wgl_driver.h @@ -7,11 +7,16 @@ #define WINE_GLAPI #endif
-#define WINE_WGL_DRIVER_VERSION 23 +#define WINE_WGL_DRIVER_VERSION 24
struct wgl_context; struct wgl_pbuffer;
+struct wgl_pixel_format +{ + PIXELFORMATDESCRIPTOR pfd; +}; + struct opengl_funcs { struct @@ -26,6 +31,7 @@ struct opengl_funcs BOOL (WINE_GLAPI *p_wglSetPixelFormat)( HDC hdc, int ipfd, const PIXELFORMATDESCRIPTOR *ppfd ); BOOL (WINE_GLAPI *p_wglShareLists)( struct wgl_context * hrcSrvShare, struct wgl_context * hrcSrvSource ); BOOL (WINE_GLAPI *p_wglSwapBuffers)( HDC hdc ); + void (WINE_GLAPI *p_get_pixel_formats)( struct wgl_pixel_format *formats, UINT max_formats, UINT *num_formats, UINT *num_onscreen_formats ); } wgl;
struct
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Use the glReserved1 area in the Teb to cache the latest pixel format information requested from the driver. --- dlls/opengl32/wgl.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index c7b0bbfdf34..87f91aef473 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -42,6 +42,11 @@ WINE_DECLARE_DEBUG_CHANNEL(fps);
static const MAT2 identity = { {0,1},{0,0},{0,0},{0,1} };
+#define WINE_GL_RESERVED_FORMATS_HDC 2 +#define WINE_GL_RESERVED_FORMATS_PTR 3 +#define WINE_GL_RESERVED_FORMATS_NUM 4 +#define WINE_GL_RESERVED_FORMATS_ONSCREEN 5 + #ifndef _WIN64
static char **wow64_strings; @@ -299,8 +304,16 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats, UINT *num_onscreen_formats ) { struct get_pixel_formats_params args = { .teb = NtCurrentTeb(), .hdc = hdc }; + PVOID *glReserved = NtCurrentTeb()->glReserved1; NTSTATUS status;
+ if (glReserved[WINE_GL_RESERVED_FORMATS_HDC] == hdc) + { + *num_formats = PtrToUlong( glReserved[WINE_GL_RESERVED_FORMATS_NUM] ); + *num_onscreen_formats = PtrToUlong( glReserved[WINE_GL_RESERVED_FORMATS_ONSCREEN] ); + return glReserved[WINE_GL_RESERVED_FORMATS_PTR]; + } + if ((status = UNIX_CALL( get_pixel_formats, &args ))) goto error; if (!(args.formats = malloc( sizeof(*args.formats) * args.num_formats ))) goto error; args.max_formats = args.num_formats; @@ -308,6 +321,13 @@ static struct wgl_pixel_format *get_pixel_formats( HDC hdc, UINT *num_formats,
*num_formats = args.num_formats; *num_onscreen_formats = args.num_onscreen_formats; + + free( glReserved[WINE_GL_RESERVED_FORMATS_PTR] ); + glReserved[WINE_GL_RESERVED_FORMATS_HDC] = hdc; + glReserved[WINE_GL_RESERVED_FORMATS_PTR] = args.formats; + glReserved[WINE_GL_RESERVED_FORMATS_NUM] = ULongToPtr( args.num_formats ); + glReserved[WINE_GL_RESERVED_FORMATS_ONSCREEN] = ULongToPtr( args.num_onscreen_formats ); + return args.formats;
error: @@ -333,7 +353,6 @@ INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDES
*ppfd = formats[index - 1].pfd;
- free( formats ); return num_onscreen_formats; }
@@ -1374,6 +1393,9 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) #ifndef _WIN64 cleanup_wow64_strings(); #endif + /* fallthrough */ + case DLL_THREAD_DETACH: + free( NtCurrentTeb()->glReserved1[WINE_GL_RESERVED_FORMATS_PTR] ); return TRUE; } return TRUE;
From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winewayland.drv/opengl.c | 121 ++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 58 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index f072b8063a1..3cb8b1e8a0d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -544,63 +544,6 @@ static BOOL wayland_wglDeleteContext(struct wgl_context *ctx) return TRUE; }
-static BOOL has_opengl(void); - -static int wayland_wglDescribePixelFormat(HDC hdc, int fmt, UINT size, - PIXELFORMATDESCRIPTOR *pfd) -{ - EGLint val; - EGLConfig config; - - if (!has_opengl()) return 0; - if (!pfd) return num_egl_configs; - if (size < sizeof(*pfd)) return 0; - if (fmt <= 0 || fmt > num_egl_configs) return 0; - - config = egl_configs[fmt - 1]; - - memset(pfd, 0, sizeof(*pfd)); - pfd->nSize = sizeof(*pfd); - pfd->nVersion = 1; - pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | - PFD_SUPPORT_COMPOSITION; - pfd->iPixelType = PFD_TYPE_RGBA; - pfd->iLayerType = PFD_MAIN_PLANE; - - /* Although the documentation describes cColorBits as excluding alpha, real - * drivers tend to return the full pixel size, so do the same. */ - p_eglGetConfigAttrib(egl_display, config, EGL_BUFFER_SIZE, &val); - pfd->cColorBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_RED_SIZE, &val); - pfd->cRedBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_GREEN_SIZE, &val); - pfd->cGreenBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_BLUE_SIZE, &val); - pfd->cBlueBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_ALPHA_SIZE, &val); - pfd->cAlphaBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_DEPTH_SIZE, &val); - pfd->cDepthBits = val; - p_eglGetConfigAttrib(egl_display, config, EGL_STENCIL_SIZE, &val); - pfd->cStencilBits = val; - - /* Although we don't get information from EGL about the component shifts - * or the native format, the 0xARGB order is the most common. */ - pfd->cBlueShift = 0; - pfd->cGreenShift = pfd->cBlueBits; - pfd->cRedShift = pfd->cGreenBits + pfd->cBlueBits; - if (pfd->cAlphaBits) - pfd->cAlphaShift = pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits; - else - pfd->cAlphaShift = 0; - - TRACE("fmt %u color %u %u/%u/%u/%u depth %u stencil %u\n", - fmt, pfd->cColorBits, pfd->cRedBits, pfd->cGreenBits, pfd->cBlueBits, - pfd->cAlphaBits, pfd->cDepthBits, pfd->cStencilBits); - - return num_egl_configs; -} - static const char *wayland_wglGetExtensionsStringARB(HDC hdc) { TRACE("() returning "%s"\n", wgl_extensions); @@ -762,6 +705,68 @@ static BOOL wayland_wglSwapIntervalEXT(int interval) return ret; }
+static void describe_pixel_format(EGLConfig config, struct wgl_pixel_format *fmt) +{ + EGLint value; + PIXELFORMATDESCRIPTOR *pfd = &fmt->pfd; + + memset(pfd, 0, sizeof(*pfd)); + pfd->nSize = sizeof(*pfd); + pfd->nVersion = 1; + pfd->dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | + PFD_SUPPORT_COMPOSITION; + pfd->iPixelType = PFD_TYPE_RGBA; + pfd->iLayerType = PFD_MAIN_PLANE; + +#define SET_ATTRIB(field, attrib) \ + value = 0; \ + p_eglGetConfigAttrib(egl_display, config, attrib, &value); \ + pfd->field = value; + + /* Although the documentation describes cColorBits as excluding alpha, real + * drivers tend to return the full pixel size, so do the same. */ + SET_ATTRIB(cColorBits, EGL_BUFFER_SIZE); + SET_ATTRIB(cRedBits, EGL_RED_SIZE); + SET_ATTRIB(cGreenBits, EGL_GREEN_SIZE); + SET_ATTRIB(cBlueBits, EGL_BLUE_SIZE); + SET_ATTRIB(cAlphaBits, EGL_ALPHA_SIZE); + /* Although we don't get information from EGL about the component shifts + * or the native format, the 0xARGB order is the most common. */ + pfd->cBlueShift = 0; + pfd->cGreenShift = pfd->cBlueBits; + pfd->cRedShift = pfd->cGreenBits + pfd->cBlueBits; + if (pfd->cAlphaBits) + pfd->cAlphaShift = pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits; + else + pfd->cAlphaShift = 0; + + SET_ATTRIB(cDepthBits, EGL_DEPTH_SIZE); + SET_ATTRIB(cStencilBits, EGL_STENCIL_SIZE); + +#undef SET_ATTRIB +} + +static BOOL has_opengl(void); + +static void wayland_get_pixel_formats(struct wgl_pixel_format *formats, + UINT max_formats, UINT *num_formats, + UINT *num_onscreen_formats) +{ + UINT i; + + if (!has_opengl()) + { + *num_formats = *num_onscreen_formats = 0; + return; + } + if (formats) + { + for (i = 0; i < min(max_formats, num_egl_configs); ++i) + describe_pixel_format(egl_configs[i], &formats[i]); + } + *num_formats = *num_onscreen_formats = num_egl_configs; +} + static BOOL has_extension(const char *list, const char *ext) { size_t len = strlen(ext); @@ -980,12 +985,12 @@ static struct opengl_funcs opengl_funcs = .p_wglCopyContext = wayland_wglCopyContext, .p_wglCreateContext = wayland_wglCreateContext, .p_wglDeleteContext = wayland_wglDeleteContext, - .p_wglDescribePixelFormat = wayland_wglDescribePixelFormat, .p_wglGetProcAddress = wayland_wglGetProcAddress, .p_wglMakeCurrent = wayland_wglMakeCurrent, .p_wglSetPixelFormat = wayland_wglSetPixelFormat, .p_wglShareLists = wayland_wglShareLists, .p_wglSwapBuffers = wayland_wglSwapBuffers, + .p_get_pixel_formats = wayland_get_pixel_formats, } };
From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winex11.drv/opengl.c | 44 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 2482a07212a..feb6a70019e 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1681,27 +1681,6 @@ static int describe_pixel_format( int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd, return nb_onscreen_formats; }
-/** - * glxdrv_DescribePixelFormat - * - * Get the pixel-format descriptor associated to the given id - */ -static int glxdrv_wglDescribePixelFormat( HDC hdc, int iPixelFormat, - UINT nBytes, PIXELFORMATDESCRIPTOR *ppfd) -{ - TRACE("(%p,%d,%d,%p)\n", hdc, iPixelFormat, nBytes, ppfd); - - if (!ppfd) return nb_onscreen_formats; - - if (nBytes < sizeof(PIXELFORMATDESCRIPTOR)) - { - ERR("Wrong structure size !\n"); - /* Should set error */ - return 0; - } - - return describe_pixel_format(iPixelFormat, ppfd, FALSE); -}
/*********************************************************************** * glxdrv_wglGetPixelFormat @@ -3428,19 +3407,40 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc ) return TRUE; }
+static void glxdrv_get_pixel_formats( struct wgl_pixel_format *formats, + UINT max_formats, UINT *num_formats, + UINT *num_onscreen_formats ) +{ + UINT i; + + if (!has_opengl()) + { + *num_formats = *num_onscreen_formats = 0; + return; + } + if (formats) + { + for (i = 0; i < min( max_formats, nb_pixel_formats ); ++i) + describe_pixel_format( i + 1, &formats[i].pfd, TRUE ); + } + *num_formats = nb_pixel_formats; + *num_onscreen_formats = nb_onscreen_formats; +} + static struct opengl_funcs opengl_funcs = { { glxdrv_wglCopyContext, /* p_wglCopyContext */ glxdrv_wglCreateContext, /* p_wglCreateContext */ glxdrv_wglDeleteContext, /* p_wglDeleteContext */ - glxdrv_wglDescribePixelFormat, /* p_wglDescribePixelFormat */ + NULL, /* p_wglDescribePixelFormat */ glxdrv_wglGetPixelFormat, /* p_wglGetPixelFormat */ glxdrv_wglGetProcAddress, /* p_wglGetProcAddress */ glxdrv_wglMakeCurrent, /* p_wglMakeCurrent */ glxdrv_wglSetPixelFormat, /* p_wglSetPixelFormat */ glxdrv_wglShareLists, /* p_wglShareLists */ glxdrv_wglSwapBuffers, /* p_wglSwapBuffers */ + glxdrv_get_pixel_formats, /* p_get_pixel_formats */ } };
From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winex11.drv/opengl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index feb6a70019e..cd132f059df 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1557,7 +1557,7 @@ void destroy_gl_drawable( HWND hwnd ) * * Get the pixel-format descriptor associated to the given id */ -static int describe_pixel_format( int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd, BOOL allow_offscreen ) +static int describe_pixel_format( int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd ) { /*XVisualInfo *vis;*/ int value; @@ -1567,7 +1567,7 @@ static int describe_pixel_format( int iPixelFormat, PIXELFORMATDESCRIPTOR *ppfd, if (!has_opengl()) return 0;
/* Look for the iPixelFormat in our list of supported formats. If it is supported we get the index in the FBConfig table and the number of supported formats back */ - fmt = get_pixel_format(gdi_display, iPixelFormat, allow_offscreen); + fmt = get_pixel_format(gdi_display, iPixelFormat, TRUE /* Offscreen */); if (!fmt) { WARN("unexpected format %d\n", iPixelFormat); return 0; @@ -2653,7 +2653,7 @@ static BOOL X11DRV_wglChoosePixelFormatARB( HDC hdc, const int *piAttribIList, c format->original_index = it;
memset(&format->pfd, 0, sizeof(format->pfd)); - if (!describe_pixel_format(format->format, &format->pfd, TRUE)) + if (!describe_pixel_format(format->format, &format->pfd)) ERR("describe_pixel_format failed, format %d.\n", format->format);
format->depth = format->pfd.cDepthBits; @@ -3421,7 +3421,7 @@ static void glxdrv_get_pixel_formats( struct wgl_pixel_format *formats, if (formats) { for (i = 0; i < min( max_formats, nb_pixel_formats ); ++i) - describe_pixel_format( i + 1, &formats[i].pfd, TRUE ); + describe_pixel_format( i + 1, &formats[i].pfd ); } *num_formats = nb_pixel_formats; *num_onscreen_formats = nb_onscreen_formats;
On Wed Apr 24 06:43:41 2024 +0000, Alexandros Frantzis wrote:
It looks like the winex11.drv changes broke something. Looking...
v3: Fix error in winex11.drv `get_pixel_formats`
This merge request was approved by Rémi Bernon.
On Wed Apr 24 06:43:34 2024 +0000, Alexandros Frantzis wrote:
Done in v2. For now I removed all other members, since they were currently unused (I initially copied the struct from the other MR just to show how it would look like). The idea is to introduce additional members when needed, i.e., for the `WGL_ARB_pixel_format` implementation in the other MR. But let me know if you would like to have the full struct earlier.
Sounds good.
@rbernon Thanks for the review. The current MR still doesn't implement `get_pixel_formats` for a few drivers (hence still draft). Does your approval imply that it's fine to merge this now and gradually transition the other drivers, or should we have everything in place before we merge? Although I am not set up to work/test on mac and android, I think the changes are mechanical enough that I can give it a go if preferred.
I think it's fine merging it like this, as it's used by winewayland and winex11.
You could then probably safely change wineandroid too, in a separate MR if you like.
This leaves winemac, which can probably keep using the old interface for now. Or, if you want to convert it as well, I can run some tests to make sure it still reports reasonable formats.
On Wed Apr 24 06:45:33 2024 +0000, Rémi Bernon wrote:
I think it's fine merging it like this, as it's used by winewayland and winex11. You could then probably safely change wineandroid too, in a separate MR if you like. This leaves winemac, which can probably keep using the old interface for now. Or, if you want to convert it as well, I can run some tests to make sure it still reports reasonable formats.
Sounds good. I have removed 'draft/rfc' from this MR, and will propose updates for the other drivers in a different MR.