-- v2: dxgi/tests: Test window states tracking and restoration in fullscreen mode. dxgi/tests: Use test contexts in test_resize_target(). wined3d: Conditionally update saved window state in fullscreen mode.
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/swapchain.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 1a010958a21..14c34b57c89 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -2101,6 +2101,25 @@ HRESULT CDECL wined3d_swapchain_state_resize_target(struct wined3d_swapchain_sta } else { + if (FAILED(hr = wined3d_output_get_desc(state->desc.output, &output_desc))) + { + ERR("Failed to get output description, hr %#lx.\n", hr); + wined3d_mutex_unlock(); + return hr; + } + width = output_desc.desktop_rect.right - output_desc.desktop_rect.left; + height = output_desc.desktop_rect.bottom - output_desc.desktop_rect.top; + + GetWindowRect(window, &window_rect); + if (width != window_rect.right - window_rect.left || height != window_rect.bottom - window_rect.top) + { + TRACE("Update saved window state.\n"); + /* Undo changes made by fullscreen_style(). */ + state->style = GetWindowLongW(window, GWL_STYLE) & ~(WS_POPUP | WS_SYSMENU); + state->exstyle = GetWindowLongW(window, GWL_EXSTYLE); + state->original_window_rect = window_rect; + } + if (state->desc.flags & WINED3D_SWAPCHAIN_ALLOW_MODE_SWITCH) { actual_mode = *mode; @@ -2111,19 +2130,18 @@ HRESULT CDECL wined3d_swapchain_state_resize_target(struct wined3d_swapchain_sta wined3d_mutex_unlock(); return hr; } - } + if (FAILED(hr = wined3d_output_get_desc(state->desc.output, &output_desc))) + { + ERR("Failed to get output description, hr %#lx.\n", hr); + wined3d_mutex_unlock(); + return hr; + }
- if (FAILED(hr = wined3d_output_get_desc(state->desc.output, &output_desc))) - { - ERR("Failed to get output description, hr %#lx.\n", hr); - wined3d_mutex_unlock(); - return hr; + width = output_desc.desktop_rect.right - output_desc.desktop_rect.left; + height = output_desc.desktop_rect.bottom - output_desc.desktop_rect.top; } - x = output_desc.desktop_rect.left; y = output_desc.desktop_rect.top; - width = output_desc.desktop_rect.right - output_desc.desktop_rect.left; - height = output_desc.desktop_rect.bottom - output_desc.desktop_rect.top; }
wined3d_mutex_unlock();
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index 03bccc50a37..f223ab96c2d 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3257,14 +3257,18 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) for (adapter_idx = 0; SUCCEEDED(IDXGIFactory_EnumAdapters(factory, adapter_idx, &adapter)); ++adapter_idx) { + winetest_push_context("Adapter %u", adapter_idx); for (output_idx = 0; SUCCEEDED(IDXGIAdapter_EnumOutputs(adapter, output_idx, &output)); ++output_idx) { + winetest_push_context("output %u", adapter_idx); hr = IDXGIOutput_GetDesc(output, &output_desc); - ok(hr == S_OK, "Adapter %u output %u: Got unexpected hr %#lx.\n", adapter_idx, output_idx, hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx) { + winetest_push_context("test %u", test_idx); + swapchain_desc.Flags = tests[test_idx].flags; swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, output_desc.DesktopCoordinates.left + tests[test_idx].origin.x, @@ -3282,8 +3286,7 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow);
hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); - ok(hr == S_OK, "Adapter %u output %u test %u: Got unexpected hr %#lx.\n", - adapter_idx, output_idx, test_idx, hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); check_swapchain_fullscreen_state(swapchain, &initial_state);
expected_state = initial_state; @@ -3294,36 +3297,33 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) &swapchain_desc, &initial_state.fullscreen_state.monitor_rect, 800, 600, NULL); hr = IDXGISwapChain_GetContainingOutput(swapchain, &expected_state.target); ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED) /* Win 7 testbot */, - "Adapter %u output %u test %u: Got unexpected hr %#lx.\n", - adapter_idx, output_idx, test_idx, hr); + "Unexpected hr %#lx.\n", hr); if (hr == DXGI_ERROR_UNSUPPORTED) { - win_skip("Adapter %u output %u test %u: GetContainingOutput() not supported.\n", - adapter_idx, output_idx, test_idx); + win_skip("GetContainingOutput() not supported.\n"); IDXGISwapChain_Release(swapchain); DestroyWindow(swapchain_desc.OutputWindow); + winetest_pop_context(); continue; }
hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); ok(hr == S_OK || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE, - "Adapter %u output %u test %u: Got unexpected hr %#lx.\n", - adapter_idx, output_idx, test_idx, hr); + "Unexpected hr %#lx.\n", hr); if (hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE) { - skip("Adapter %u output %u test %u: Could not change fullscreen state.\n", - adapter_idx, output_idx, test_idx); + skip("Could not change fullscreen state.\n"); IDXGIOutput_Release(expected_state.target); IDXGISwapChain_Release(swapchain); DestroyWindow(swapchain_desc.OutputWindow); + winetest_pop_context(); continue; } } check_swapchain_fullscreen_state(swapchain, &expected_state);
hr = IDXGISwapChain_ResizeTarget(swapchain, NULL); - ok(hr == DXGI_ERROR_INVALID_CALL, "Adapter %u output %u test %u: Got unexpected hr %#lx.\n", - adapter_idx, output_idx, test_idx, hr); + ok(hr == DXGI_ERROR_INVALID_CALL, "Unexpected hr %#lx.\n", hr); check_swapchain_fullscreen_state(swapchain, &expected_state);
if (tests[test_idx].fullscreen) @@ -3331,8 +3331,7 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) test_fullscreen_resize_target(swapchain, &expected_state);
hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); - ok(hr == S_OK, "Adapter %u output %u test %u: Got unexpected hr %#lx.\n", - adapter_idx, output_idx, test_idx, hr); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); check_swapchain_fullscreen_state(swapchain, &initial_state); IDXGIOutput_Release(expected_state.target); check_swapchain_fullscreen_state(swapchain, &initial_state); @@ -3346,14 +3345,16 @@ static void test_resize_target(IUnknown *device, BOOL is_d3d12) }
refcount = IDXGISwapChain_Release(swapchain); - ok(!refcount, "Adapter %u output %u test %u: IDXGISwapChain has %lu references left.\n", - adapter_idx, output_idx, test_idx, refcount); + ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount); check_window_fullscreen_state(swapchain_desc.OutputWindow, &expected_state.fullscreen_state); DestroyWindow(swapchain_desc.OutputWindow); + winetest_pop_context(); } IDXGIOutput_Release(output); + winetest_pop_context(); } IDXGIAdapter_Release(adapter); + winetest_pop_context(); } refcount = IDXGIFactory_Release(factory); ok(refcount == !is_d3d12, "Got unexpected refcount %lu.\n", refcount);
From: Matteo Bruni mbruni@codeweavers.com
--- dlls/dxgi/tests/dxgi.c | 181 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c index f223ab96c2d..06f0147c0a3 100644 --- a/dlls/dxgi/tests/dxgi.c +++ b/dlls/dxgi/tests/dxgi.c @@ -3056,6 +3056,185 @@ static void test_default_fullscreen_target_output(IUnknown *device, BOOL is_d3d1 ok(refcount == !is_d3d12, "IDXGIFactory has %lu references left.\n", refcount); }
+static void test_resize_fullscreen_window(IUnknown *device, BOOL is_d3d12, BOOL change_style) +{ + struct swapchain_fullscreen_state initial_state, expected_state; + unsigned int desktop_width, desktop_height; + DXGI_SWAP_CHAIN_DESC swapchain_desc; + IDXGIAdapter *adapter = NULL; + DXGI_OUTPUT_DESC output_desc; + IDXGIOutput *output = NULL; + IDXGISwapChain *swapchain; + IDXGIFactory *factory; + BOOL fullscreen, ret; + DXGI_MODE_DESC mode; + ULONG refcount; + HRESULT hr; + RECT r; + + winetest_push_context(change_style ? "Style change" : "No style change"); + + get_factory(device, is_d3d12, &factory); + + swapchain_desc.BufferDesc.Width = 800; + swapchain_desc.BufferDesc.Height = 600; + swapchain_desc.BufferDesc.RefreshRate.Numerator = 60; + swapchain_desc.BufferDesc.RefreshRate.Denominator = 60; + swapchain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapchain_desc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapchain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapchain_desc.SampleDesc.Count = 1; + swapchain_desc.SampleDesc.Quality = 0; + swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapchain_desc.BufferCount = is_d3d12 ? 2 : 1; + swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); + swapchain_desc.Windowed = TRUE; + swapchain_desc.SwapEffect = is_d3d12 ? DXGI_SWAP_EFFECT_FLIP_DISCARD : DXGI_SWAP_EFFECT_DISCARD; + swapchain_desc.Flags = 0; + + memset(&initial_state, 0, sizeof(initial_state)); + capture_fullscreen_state(&initial_state.fullscreen_state, swapchain_desc.OutputWindow); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_GetContainingOutput(swapchain, &output); + ok(hr == S_OK || broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */ + "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + skip("Could not get output.\n"); + goto done; + } + hr = IDXGIOutput_GetParent(output, &IID_IDXGIAdapter, (void **)&adapter); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + check_swapchain_fullscreen_state(swapchain, &initial_state); + hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); + ok(hr == S_OK || hr == DXGI_ERROR_NOT_CURRENTLY_AVAILABLE + || broken(hr == DXGI_ERROR_UNSUPPORTED), /* Win 7 testbot */ + "Unexpected hr %#lx.\n", hr); + if (FAILED(hr)) + { + skip("Could not change fullscreen state.\n"); + goto done; + } + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + refcount = IDXGISwapChain_Release(swapchain); + ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount); + + DestroyWindow(swapchain_desc.OutputWindow); + swapchain_desc.OutputWindow = CreateWindowA("static", "dxgi_test", 0, 0, 0, 400, 200, 0, 0, 0, 0); + ShowWindow(swapchain_desc.OutputWindow, SW_NORMAL); + flush_events(); + check_window_fullscreen_state(swapchain_desc.OutputWindow, &initial_state.fullscreen_state); + hr = IDXGIFactory_CreateSwapChain(factory, device, &swapchain_desc, &swapchain); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_SetFullscreenState(swapchain, TRUE, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!fullscreen, "Unexpected fullscreen %#x.\n", fullscreen); + + hr = IDXGIOutput_GetDesc(output, &output_desc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + if (change_style) + SetWindowLongPtrA(swapchain_desc.OutputWindow, GWL_STYLE, 0x10ca0000); + + expected_state = initial_state; + SetRect(&expected_state.fullscreen_state.client_rect, 0, 0, 640, 480); + r = expected_state.fullscreen_state.client_rect; + ret = AdjustWindowRectEx(&r, GetWindowLongW(swapchain_desc.OutputWindow, GWL_STYLE), + FALSE, GetWindowLongW(swapchain_desc.OutputWindow, GWL_EXSTYLE)); + ok(ret, "Unexpected ret %#x.\n", ret); + desktop_width = output_desc.DesktopCoordinates.right - output_desc.DesktopCoordinates.left; + desktop_height = output_desc.DesktopCoordinates.bottom - output_desc.DesktopCoordinates.top; + OffsetRect(&r, (desktop_width - 640) / 2, (desktop_height - 480) / 2); + expected_state.fullscreen_state.window_rect = r; + + /* Center the window on the screen. */ + ret = SetWindowPos(swapchain_desc.OutputWindow, HWND_NOTOPMOST, r.left, + r.top, r.right - r.left, r.bottom - r.top, SWP_FRAMECHANGED); + ok(ret, "Unexpected ret %#x.\n", ret); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!fullscreen, "Unexpected fullscreen %#x.\n", fullscreen); + expected_state.fullscreen = TRUE; + expected_state.target = output; + if (change_style) + { + expected_state.fullscreen_state.style = 0x4ca0000; + } + else + { + expected_state.fullscreen_state.style = 0x4000000; + expected_state.fullscreen_state.exstyle = 0; + } + check_swapchain_fullscreen_state(swapchain, &expected_state); + + /* Update DXGI swapchain. */ + memset(&mode, 0, sizeof(mode)); + mode.Width = 640; + mode.Height = 480; + hr = IDXGISwapChain_ResizeTarget(swapchain, &mode); + ok(!hr, "Unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!fullscreen, "Unexpected fullscreen %#x.\n", fullscreen); + SetRect(&expected_state.fullscreen_state.window_rect, 0, 0, desktop_width, desktop_height); + expected_state.fullscreen_state.client_rect = expected_state.fullscreen_state.window_rect; + if (change_style) + { + expected_state.fullscreen_state.style = 0x4000000; + expected_state.fullscreen_state.exstyle = 0; + } + check_swapchain_fullscreen_state(swapchain, &expected_state); + hr = IDXGISwapChain_GetDesc(swapchain, &swapchain_desc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(swapchain_desc.BufferDesc.Width == 800, "Unexpected width %u.\n", swapchain_desc.BufferDesc.Width); + ok(swapchain_desc.BufferDesc.Height == 600, "Unexpected height %u.\n", swapchain_desc.BufferDesc.Height); + + /* Now actually leave fullscreen mode. */ + hr = IDXGISwapChain_SetFullscreenState(swapchain, FALSE, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!fullscreen, "Unexpected fullscreen %#x.\n", fullscreen); + expected_state.fullscreen_state.window_rect = r; + SetRect(&expected_state.fullscreen_state.client_rect, 0, 0, 640, 480); + expected_state.fullscreen = FALSE; + expected_state.target = NULL; + if (change_style) + { + expected_state.fullscreen_state.style = 0x4ca0000; + expected_state.fullscreen_state.exstyle = 0x100; + } + check_swapchain_fullscreen_state(swapchain, &expected_state); + +done: + if (output) + IDXGIOutput_Release(output); + if (adapter) + IDXGIAdapter_Release(adapter); + refcount = IDXGISwapChain_Release(swapchain); + ok(!refcount, "IDXGISwapChain has %lu references left.\n", refcount); + check_window_fullscreen_state(swapchain_desc.OutputWindow, &expected_state.fullscreen_state); + DestroyWindow(swapchain_desc.OutputWindow); + + refcount = IDXGIFactory_Release(factory); + ok(refcount == !is_d3d12, "Unexpected refcount %lu.\n", refcount); + + winetest_pop_context(); +} + +static void test_resize_fullscreen(IUnknown *device, BOOL is_d3d12) +{ + test_resize_fullscreen_window(device, is_d3d12, FALSE); + /* Skip the test on Wine, it's very tricky to make it pass. */ + if (!winetest_platform_is_wine) + test_resize_fullscreen_window(device, is_d3d12, TRUE); +} + static void test_windowed_resize_target(IDXGISwapChain *swapchain, HWND window, struct swapchain_fullscreen_state *state) { @@ -8336,6 +8515,7 @@ START_TEST(dxgi) test_swapchain_window_styles(); run_on_d3d10(test_set_fullscreen); run_on_d3d10(test_resize_target); + run_on_d3d10(test_resize_fullscreen); run_on_d3d10(test_swapchain_resize); run_on_d3d10(test_swapchain_present); run_on_d3d10(test_swapchain_backbuffer_index); @@ -8368,6 +8548,7 @@ START_TEST(dxgi)
run_on_d3d12(test_set_fullscreen); run_on_d3d12(test_resize_target); + run_on_d3d10(test_resize_fullscreen); run_on_d3d12(test_swapchain_resize); run_on_d3d12(test_swapchain_present); run_on_d3d12(test_swapchain_backbuffer_index);