From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58846 --- dlls/win32u/opengl.c | 103 ++++++++++++++++++++++++++++++------------- dlls/win32u/window.c | 2 +- 2 files changed, 73 insertions(+), 32 deletions(-)
diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index fc0be5795d4..714318d26fb 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1269,24 +1269,32 @@ static const char *win32u_wglGetExtensionsStringEXT(void) return wgl_extensions; }
-static int get_dc_pixel_format( HDC hdc, BOOL internal ) +static int get_dc_pixel_format( HDC hdc, BOOL *is_display ) { - int ret = 0; - HWND hwnd; + int ret; DC *dc;
- if ((hwnd = NtUserWindowFromDC( hdc ))) - ret = get_window_pixel_format( hwnd, internal ); - else if ((dc = get_dc_ptr( hdc ))) - { - BOOL is_display = dc->is_display; - ret = dc->pixel_format; - release_dc_ptr( dc ); + if (!(dc = get_dc_ptr( hdc ))) return -1; + if (is_display) *is_display = dc->is_display; + ret = dc->pixel_format; + release_dc_ptr( dc ); + + return ret; +}
+static int win32u_wglGetPixelFormat( HDC hdc ) +{ + BOOL is_display = FALSE; + int format; + HWND hwnd; + + if ((hwnd = NtUserWindowFromDC( hdc ))) format = get_window_pixel_format( hwnd, FALSE ); + else if ((format = get_dc_pixel_format( hdc, &is_display )) >= 0) + { /* 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 > onscreen_count) ret = 1; + if (is_display && format > onscreen_count) format = 1; } else { @@ -1295,13 +1303,7 @@ static int get_dc_pixel_format( HDC hdc, BOOL internal ) return -1; }
- TRACE( "%p/%p -> %d\n", hdc, hwnd, ret ); - return ret; -} - -static int win32u_wglGetPixelFormat( HDC hdc ) -{ - int format = get_dc_pixel_format( hdc, FALSE ); + TRACE( "%p/%p -> %d\n", hdc, hwnd, format ); return format > 0 ? format : 0; }
@@ -1466,7 +1468,7 @@ static BOOL flush_memory_dc( struct wgl_context *context, HDC hdc, BOOL write, v return ret; }
-static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) +static BOOL win32u_wglSetPixelFormat( HDC hdc, int new_format, const PIXELFORMATDESCRIPTOR *pfd ) { const struct opengl_funcs *funcs = &display_funcs; UINT total, onscreen; @@ -1486,9 +1488,9 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) return FALSE; }
- TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal ); + TRACE( "%p/%p format %d\n", hdc, hwnd, new_format );
- if ((old_format = get_window_pixel_format( hwnd, FALSE )) && !internal) return old_format == new_format; + if ((old_format = get_window_pixel_format( hwnd, FALSE ))) return old_format == new_format;
if ((drawable = get_window_unused_drawable( hwnd, new_format ))) { @@ -1497,21 +1499,52 @@ static BOOL set_dc_pixel_format( HDC hdc, int new_format, BOOL internal ) opengl_drawable_release( drawable ); }
- return set_window_pixel_format( hwnd, new_format, internal ); + return set_window_pixel_format( hwnd, new_format, FALSE ); }
- TRACE( "%p/%p format %d, internal %u\n", hdc, hwnd, new_format, internal ); + TRACE( "%p/%p format %d\n", hdc, hwnd, new_format ); return NtGdiSetPixelFormat( hdc, new_format ); }
-static BOOL win32u_wglSetPixelFormat( HDC hdc, int format, const PIXELFORMATDESCRIPTOR *pfd ) +static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int new_format ) { - return set_dc_pixel_format( hdc, format, FALSE ); -} + const struct opengl_funcs *funcs = &display_funcs; + struct opengl_drawable *drawable; + UINT total, onscreen; + HWND hwnd; + DC *dc;
-static BOOL win32u_wglSetPixelFormatWINE( HDC hdc, int format ) -{ - return set_dc_pixel_format( hdc, format, TRUE ); + if (!(hwnd = NtUserWindowFromDC( hdc ))) return FALSE; + + TRACE( "%p/%p format %d\n", hdc, hwnd, new_format ); + + funcs->p_get_pixel_formats( NULL, 0, &total, &onscreen ); + if (new_format < 0 || new_format > total) return FALSE; + if (new_format > onscreen) + { + WARN( "Invalid format %d for %p/%p\n", new_format, hdc, hwnd ); + return FALSE; + } + + if (!(dc = get_dc_ptr( hdc ))) return FALSE; + dc->pixel_format = new_format; + drawable = dc->opengl_drawable; + dc->opengl_drawable = NULL; + release_dc_ptr( dc ); + + if (drawable && drawable->format != new_format) + { + opengl_drawable_release( drawable ); + drawable = NULL; + } + if (new_format && (drawable || (drawable = get_window_unused_drawable( hwnd, new_format )))) + { + set_window_opengl_drawable( hwnd, drawable, TRUE ); + set_dc_opengl_drawable( hdc, drawable ); + opengl_drawable_release( drawable ); + } + + return TRUE; }
static PROC win32u_wglGetProcAddress( const char *name ) @@ -1581,6 +1614,10 @@ static BOOL context_sync_drawables( struct wgl_context *context, HDC draw_hdc, H struct wgl_context *previous = NtCurrentTeb()->glContext; BOOL ret = FALSE;
+ /* retrieve the D3D internal drawables from the DCs if they have any */ + if (draw_hdc && !context->draw) context->draw = get_dc_opengl_drawable( draw_hdc ); + if (read_hdc && !context->read) context->read = get_dc_opengl_drawable( read_hdc ); + new_draw = get_updated_drawable( draw_hdc, context->format, context->draw ); if (!draw_hdc && context->draw == context->read) opengl_drawable_add_ref( (new_read = new_draw) ); else if (draw_hdc && draw_hdc == read_hdc) opengl_drawable_add_ref( (new_read = new_draw) ); @@ -1684,10 +1721,12 @@ static BOOL win32u_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct return TRUE; }
- if ((format = get_dc_pixel_format( draw_hdc, TRUE )) <= 0) + if ((format = get_dc_pixel_format( draw_hdc, NULL )) <= 0 && + (format = get_window_pixel_format( NtUserWindowFromDC( draw_hdc ), FALSE )) <= 0) { WARN( "Invalid draw_hdc %p format %u\n", draw_hdc, format ); if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + else RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } if (context->format != format) @@ -2144,9 +2183,11 @@ static BOOL win32u_wgl_context_reset( struct wgl_context *context, HDC hdc, stru context->driver_private = NULL; if (!hdc) return TRUE;
- if ((format = get_dc_pixel_format( hdc, TRUE )) <= 0) + if ((format = get_dc_pixel_format( hdc, NULL )) <= 0 && + (format = get_window_pixel_format( NtUserWindowFromDC( hdc ), FALSE )) <= 0) { if (!format) RtlSetLastWin32Error( ERROR_INVALID_PIXEL_FORMAT ); + else RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } if (!driver_funcs->p_context_create( format, share_private, attribs, &context->driver_private )) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index c5c5d0522c8..8a026a3c189 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1568,7 +1568,7 @@ int get_window_pixel_format( HWND hwnd, BOOL internal ) if (!win || win == WND_DESKTOP || win == WND_OTHER_PROCESS) { WARN( "getting format on win %p not supported\n", hwnd ); - return 0; + return -1; }
ret = internal && win->internal_pixel_format ? win->internal_pixel_format : win->pixel_format;