From: Zhiyi Zhang zzhang@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56825 --- dlls/user32/tests/monitor.c | 51 +++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index e4fe79d6882..f2eb70e3eb3 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -2529,13 +2529,13 @@ static void test_display_dc(void) { static const INT bpps[] = {1, 4, 8, 16, 24, 32}; unsigned char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)]; + HBITMAP hbitmap, hbitmap2, old_hbitmap; BITMAPINFO *bmi = (BITMAPINFO *)buffer; INT count, old_count, i, bpp, value; - HBITMAP hbitmap, old_hbitmap; DWORD device_idx, mode_idx; DEVMODEA dm, dm2, dm3; + HDC hdc, hdc2, mem_dc; DISPLAY_DEVICEA dd; - HDC hdc, mem_dc; DIBSECTION dib; BITMAP bitmap; BOOL ret; @@ -2684,6 +2684,53 @@ static void test_display_dc(void) SelectObject(mem_dc, old_hbitmap); DeleteDC(mem_dc);
+ /* Test that the same bitmap handle is used for different display DCs */ + old_hbitmap = GetCurrentObject(hdc, OBJ_BITMAP); + + hdc2 = CreateDCA("DISPLAY", NULL, NULL, NULL); + ok(!!hdc2, "CreateDCA failed.\n"); + hbitmap2 = GetCurrentObject(hdc2, OBJ_BITMAP); + todo_wine + ok(hbitmap2 == old_hbitmap, "Expected the same bitmap handle.\n"); + + /* Tests after mode changes to a mode with different resolution */ + memset(&dm2, 0, sizeof(dm2)); + dm2.dmSize = sizeof(dm2); + for (mode_idx = 0; EnumDisplaySettingsA(NULL, mode_idx, &dm2); ++mode_idx) + { + if (dm2.dmPelsWidth != dm.dmPelsWidth || dm2.dmPelsHeight != dm.dmPelsHeight) + break; + } + if (dm2.dmPelsWidth != dm.dmPelsWidth || dm2.dmPelsHeight != dm.dmPelsHeight) + { + res = ChangeDisplaySettingsExA(NULL, &dm2, NULL, CDS_RESET, NULL); + /* Win8 TestBots */ + ok(res == DISP_CHANGE_SUCCESSFUL || broken(res == DISP_CHANGE_FAILED), + "ChangeDisplaySettingsExA returned unexpected %ld.\n", res); + if (res == DISP_CHANGE_SUCCESSFUL) + { + check_display_dc(hdc, &dm2, FALSE); + + /* Test that a different bitmap handle is used for the display DC after resolution changes */ + hbitmap2 = GetCurrentObject(hdc, OBJ_BITMAP); + todo_wine + ok(hbitmap2 != old_hbitmap, "Expected a different bitmap handle.\n"); + + /* Test that the old display bitmap is invalid after waiting for a bit. This suggests + * that the bitmap got released. And note that hdc2 has not been deleted yet and hdc2 + * has the same bitmap handle so the display bitmap is not being reference counted */ + Sleep(500); + count = GetObjectW(old_hbitmap, sizeof(bitmap), &bitmap); + todo_wine + ok(!count, "GetObject failed, count %d.\n", count); + } + } + else + { + win_skip("Failed to find a different resolution.\n"); + } + DeleteDC(hdc2); + /* Tests after mode changes to a mode with different resolution and color depth */ memset(&dm2, 0, sizeof(dm2)); dm2.dmSize = sizeof(dm2);
From: Zhiyi Zhang zzhang@codeweavers.com
Create a bitmap of the virtual screen size for all display device contexts. Previously, the concern was that allocating a full size bitmap may use too much memory. But now that there is a real world application that needs this, it is now necessary. Fortunately, tests show that all display device contexts use the same bitmap.
Fix a regression from 19229020.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56825 --- dlls/user32/tests/monitor.c | 5 ----- dlls/win32u/dc.c | 11 ++--------- dlls/win32u/gdiobj.c | 5 ++++- dlls/win32u/sysparams.c | 21 +++++++++++++++++++++ dlls/win32u/win32u_private.h | 1 + 5 files changed, 28 insertions(+), 15 deletions(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c index f2eb70e3eb3..2575d278392 100644 --- a/dlls/user32/tests/monitor.c +++ b/dlls/user32/tests/monitor.c @@ -2509,10 +2509,8 @@ static void _check_display_dc(INT line, HDC hdc, const DEVMODEA *dm, BOOL allow_ if (ret) { ok_(__FILE__, line)(bitmap.bmType == 0, "Expected bmType %d, got %d.\n", 0, bitmap.bmType); - todo_wine ok_(__FILE__, line)(bitmap.bmWidth == GetSystemMetrics(SM_CXVIRTUALSCREEN), "Expected bmWidth %d, got %d.\n", GetSystemMetrics(SM_CXVIRTUALSCREEN), bitmap.bmWidth); - todo_wine ok_(__FILE__, line)(bitmap.bmHeight == GetSystemMetrics(SM_CYVIRTUALSCREEN), "Expected bmHeight %d, got %d.\n", GetSystemMetrics(SM_CYVIRTUALSCREEN), bitmap.bmHeight); ok_(__FILE__, line)(bitmap.bmBitsPixel == 32, "Expected bmBitsPixel %d, got %d.\n", 32, @@ -2690,7 +2688,6 @@ static void test_display_dc(void) hdc2 = CreateDCA("DISPLAY", NULL, NULL, NULL); ok(!!hdc2, "CreateDCA failed.\n"); hbitmap2 = GetCurrentObject(hdc2, OBJ_BITMAP); - todo_wine ok(hbitmap2 == old_hbitmap, "Expected the same bitmap handle.\n");
/* Tests after mode changes to a mode with different resolution */ @@ -2713,7 +2710,6 @@ static void test_display_dc(void)
/* Test that a different bitmap handle is used for the display DC after resolution changes */ hbitmap2 = GetCurrentObject(hdc, OBJ_BITMAP); - todo_wine ok(hbitmap2 != old_hbitmap, "Expected a different bitmap handle.\n");
/* Test that the old display bitmap is invalid after waiting for a bit. This suggests @@ -2721,7 +2717,6 @@ static void test_display_dc(void) * has the same bitmap handle so the display bitmap is not being reference counted */ Sleep(500); count = GetObjectW(old_hbitmap, sizeof(bitmap), &bitmap); - todo_wine ok(!count, "GetObject failed, count %d.\n", count); } } diff --git a/dlls/win32u/dc.c b/dlls/win32u/dc.c index 24a3bca5544..3f6a501041a 100644 --- a/dlls/win32u/dc.c +++ b/dlls/win32u/dc.c @@ -275,13 +275,7 @@ void free_dc_ptr( DC *dc ) GDI_dec_ref_count( dc->hPen ); GDI_dec_ref_count( dc->hBrush ); GDI_dec_ref_count( dc->hFont ); - if (dc->hBitmap) - { - if (dc->is_display) - NtGdiDeleteObjectApp( dc->hBitmap ); - else - GDI_dec_ref_count( dc->hBitmap ); - } + if (dc->hBitmap && !dc->is_display) GDI_dec_ref_count( dc->hBitmap ); free_gdi_handle( dc->hSelf ); free_dc_state( dc ); } @@ -729,9 +723,8 @@ HDC WINAPI NtGdiOpenDCW( UNICODE_STRING *device, const DEVMODEW *devmode, UNICOD
if (!(dc = alloc_dc_ptr( NTGDI_OBJ_DC ))) return 0; hdc = dc->hSelf; - if (is_display) - dc->hBitmap = NtGdiCreateCompatibleBitmap( hdc, 1, 1 ); + dc->hBitmap = get_display_bitmap(); else dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 5cf99e39ff0..fec99243aa2 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -969,7 +969,10 @@ HANDLE WINAPI NtGdiGetDCObject( HDC hdc, UINT type ) case NTGDI_OBJ_BRUSH: ret = dc->hBrush; break; case NTGDI_OBJ_PAL: ret = dc->hPalette; break; case NTGDI_OBJ_FONT: ret = dc->hFont; break; - case NTGDI_OBJ_SURF: ret = dc->hBitmap; break; + case NTGDI_OBJ_SURF: + /* Update bitmap for display device contexts */ + if (dc->is_display) dc->hBitmap = get_display_bitmap(); + ret = dc->hBitmap; break; default: FIXME( "(%p, %d): unknown type.\n", hdc, type ); break; diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index afa75928c94..094a963d305 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2100,6 +2100,27 @@ static HDC get_display_dc(void) return display_dc; }
+HBITMAP get_display_bitmap(void) +{ + static RECT old_virtual_rect; + static HBITMAP hbitmap; + RECT virtual_rect; + HBITMAP ret; + + virtual_rect = get_virtual_screen_rect( 0 ); + pthread_mutex_lock( &display_dc_lock ); + if (!EqualRect( &old_virtual_rect, &virtual_rect )) + { + if (hbitmap) NtGdiDeleteObjectApp( hbitmap ); + hbitmap = NtGdiCreateBitmap( virtual_rect.right - virtual_rect.left, + virtual_rect.bottom - virtual_rect.top, 1, 32, NULL ); + old_virtual_rect = virtual_rect; + } + ret = hbitmap; + pthread_mutex_unlock( &display_dc_lock ); + return ret; +} + static void release_display_dc( HDC hdc ) { pthread_mutex_unlock( &display_dc_lock ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 73933acc14a..c4521899299 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -161,6 +161,7 @@ extern BOOL enable_thunk_lock; extern HBRUSH get_55aa_brush(void); extern DWORD get_dialog_base_units(void); extern LONG get_char_dimensions( HDC hdc, TEXTMETRICW *metric, int *height ); +extern HBITMAP get_display_bitmap(void); extern INT get_display_depth( UNICODE_STRING *name ); extern RECT get_display_rect( const WCHAR *display ); extern UINT get_monitor_dpi( HMONITOR monitor );
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147798
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4305: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000008200E4, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: peek: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: peek: raw_legacy: 0: got F: 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: peek: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: peek: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: peek: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: peek: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: peek: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: peek: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x46, lparam 0x10001 input.c:733: Test failed: receive: raw_legacy: 0: test->expect 2 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x66, lparam 0x10001 input.c:734: Test failed: receive: raw_legacy: 0: got F: 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x46, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0xe7, lparam 0x10001 input.c:734: Test failed: receive: raw_vk_packet_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_legacy: 1: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0xe7, lparam 0xffffffffc0020001 input.c:733: Test failed: receive: raw_unicode_legacy: 0: test->expect 1 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_CHAR, wparam 0x3c0, lparam 0x1 input.c:734: Test failed: receive: raw_unicode_legacy: 0: got 0xe7: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYDOWN, wparam 0x11, lparam 0xc00001 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_CONTROL: 0 input.c:734: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 0: got VK_LCONTROL: 0 input.c:733: Test failed: receive: raw_unicode_vkey_ctrl_legacy: 1: test->expect 0 (missing): MSG_TEST_WIN hwnd 0000000000000000, WM_KEYUP, wparam 0x11, lparam 0xffffffffc0c00001 input.c:733: Test failed: receive: raw_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey F, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey F, message WM_KEYUP, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 0: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x1, flags 0, vkey 0xe7, message WM_KEYDOWN, extra 0 input.c:733: Test failed: receive: raw_vk_packet_nolegacy: 1: test->expect 0 (missing): got WM_INPUT key hwnd 0000000000000000, code 0, make_code 0x2, flags 0x1, vkey 0xe7, message WM_KEYUP, extra 0
This merge request was approved by Huw Davies.