From: Zowie van Dillen zowie+wine@vandillen.io
This commit does not yet actually implement the fake pixel format: wglSetPixelFormat will still fail. --- dlls/opengl32/tests/opengl.c | 12 ++++++------ dlls/opengl32/wgl.c | 33 +++++++++++++++++++++++++++++++++ include/wine/opengl_driver.h | 6 ++++++ 3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/dlls/opengl32/tests/opengl.c b/dlls/opengl32/tests/opengl.c index 8c3077d7e8e..82e8c1cfd9f 100644 --- a/dlls/opengl32/tests/opengl.c +++ b/dlls/opengl32/tests/opengl.c @@ -1911,7 +1911,7 @@ static void test_16bit_bitmap_rendering(void)
/* Choose a pixel format. */ pixel_format = ChoosePixelFormat(hdc, &pixel_format_args); - todo_wine ok(pixel_format != 0, "Failed to get a 16 bit pixel format with the DRAW_TO_BITMAP flag.\n"); + ok(pixel_format != 0, "Failed to get a 16 bit pixel format with the DRAW_TO_BITMAP flag.\n");
if (pixel_format == 0) { @@ -1932,11 +1932,11 @@ static void test_16bit_bitmap_rendering(void) success = DescribePixelFormat(hdc, pixel_format, sizeof(pfd), &pfd); ok(success != 0, "Failed to DescribePixelFormat (error: %lu)\n", GetLastError()); ok(pfd.cColorBits == 16, "Wrong amount of color bits (got %d, expected 16)\n", pfd.cColorBits); - todo_wine ok(pfd.cRedBits == 5, "Wrong amount of red bits (got %d, expected 5)\n", pfd.cRedBits); - todo_wine ok(pfd.cGreenBits == 5, "Wrong amount of green bits (got %d, expected 5)\n", pfd.cGreenBits); - todo_wine ok(pfd.cBlueBits == 5, "Wrong amount of blue bits (got %d, expected 5)\n", pfd.cBlueBits); - todo_wine ok(pfd.cRedShift == 10, "Wrong red shift (got %d, expected 10)\n", pfd.cRedShift); - todo_wine ok(pfd.cGreenShift == 5, "Wrong green shift (got %d, expected 5)\n", pfd.cGreenShift); + ok(pfd.cRedBits == 5, "Wrong amount of red bits (got %d, expected 5)\n", pfd.cRedBits); + ok(pfd.cGreenBits == 5, "Wrong amount of green bits (got %d, expected 5)\n", pfd.cGreenBits); + ok(pfd.cBlueBits == 5, "Wrong amount of blue bits (got %d, expected 5)\n", pfd.cBlueBits); + ok(pfd.cRedShift == 10, "Wrong red shift (got %d, expected 10)\n", pfd.cRedShift); + ok(pfd.cGreenShift == 5, "Wrong green shift (got %d, expected 5)\n", pfd.cGreenShift); ok(pfd.cBlueShift == 0, "Wrong blue shift (got %d, expected 0)\n", pfd.cBlueShift);
success = SetPixelFormat(hdc, pixel_format, &pixel_format_args); diff --git a/dlls/opengl32/wgl.c b/dlls/opengl32/wgl.c index 6125d9a4574..54a9ea5f1c4 100644 --- a/dlls/opengl32/wgl.c +++ b/dlls/opengl32/wgl.c @@ -138,6 +138,16 @@ INT WINAPI wglChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR* ppfd)
if (!NtGdiGetDCDword( hdc, NtGdiIsMemDC, &is_memdc )) is_memdc = 0;
+ if (is_memdc && ppfd->cColorBits == 16) + { + /* 16-bit-per-pixel memory DCs are a special case. Windows uses a software renderer with a + * quirky pixel format for this. That pixel format is only rarely supported on actual GPUs. + * We return a special value, which we'll later check for in SelectPixelFormat. + * Check `test_16bit_bitmap_rendering` for more info. */ + TRACE( "Returning special 16-bit pixel format %d\n", FAKE_16BIT_MEMDC_PIXEL_FORMAT ); + return FAKE_16BIT_MEMDC_PIXEL_FORMAT; + } + best_format = 0; best.dwFlags = 0; best.cAlphaBits = -1; @@ -820,6 +830,29 @@ INT WINAPI wglDescribePixelFormat( HDC hdc, int index, UINT size, PIXELFORMATDES
if (!(formats = get_pixel_formats( hdc, &num_formats, &num_onscreen_formats ))) return 0; if (!ppfd) return num_onscreen_formats; + + if (index == FAKE_16BIT_MEMDC_PIXEL_FORMAT) + { + /* 16-bit memory DCs are a special case where we need to fake the pixel format. + * Check `test_16bit_bitmap_rendering` for more info. */ + *ppfd = (PIXELFORMATDESCRIPTOR) { + .nSize = sizeof(PIXELFORMATDESCRIPTOR), + .nVersion = 1, + .dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL, + .iPixelType = PFD_TYPE_RGBA, + .iLayerType = PFD_MAIN_PLANE, + .cColorBits = 16, + .cRedBits = 5, + .cGreenBits = 5, + .cBlueBits = 5, + .cAlphaBits = 0, + .cRedShift = 10, + .cGreenShift = 5, + .cBlueShift = 0, + }; + return num_onscreen_formats; + } + if (size < sizeof(*ppfd)) return 0; if (index <= 0 || index > num_onscreen_formats) return 0;
diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 296b030021d..bdc87fdd83c 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -59,6 +59,12 @@ struct wgl_pixel_format int float_components; };
+ +/* A special pixel format number, which is given by wglChoosePixelFormat when + * you ask for a 16 bpp format with PFD_DRAW_TO_BITMAP. */ +#define FAKE_16BIT_MEMDC_PIXEL_FORMAT 65000 + + #ifdef WINE_UNIX_LIB
#include "wine/gdi_driver.h"