[PATCH 2/3] dxgi: Update swapchain containing output after Alt+Enter was used to exit fullscreen.

Zhiyi Zhang zzhang at codeweavers.com
Tue Oct 6 08:30:51 CDT 2020


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/dxgi/swapchain.c          | 21 ++++++++++++++++++++-
 dlls/dxgi/tests/dxgi.c         |  4 ++--
 dlls/wined3d/swapchain.c       |  4 ++++
 dlls/wined3d/wined3d.spec      |  2 +-
 dlls/wined3d/wined3d_main.c    |  6 +++++-
 dlls/wined3d/wined3d_private.h |  3 +++
 include/wine/wined3d.h         |  8 +++++++-
 7 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 9d6ec0246ce..aa889bbe236 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -807,6 +807,24 @@ static const struct wined3d_parent_ops d3d11_swapchain_wined3d_parent_ops =
     d3d11_swapchain_wined3d_object_released,
 };
 
+static void STDMETHODCALLTYPE d3d11_swapchain_windowed_state_changed(void *parent, BOOL windowed)
+{
+    struct d3d11_swapchain *swapchain = parent;
+
+    TRACE("parent %p, windowed %d.\n", parent, windowed);
+
+    if (windowed && swapchain->target)
+    {
+        IDXGIOutput_Release(swapchain->target);
+        swapchain->target = NULL;
+    }
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d11_swapchain_state_parent_ops =
+{
+    d3d11_swapchain_windowed_state_changed,
+};
+
 HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device,
         struct wined3d_swapchain_desc *desc)
 {
@@ -855,7 +873,8 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi
 
     swapchain->state = wined3d_swapchain_get_state(swapchain->wined3d_swapchain);
     wined3d = wined3d_device_get_wined3d(device->wined3d_device);
-    wined3d_swapchain_state_register(swapchain->state, wined3d);
+    wined3d_swapchain_state_register(swapchain->state, wined3d, swapchain,
+            &d3d11_swapchain_state_parent_ops);
 
     swapchain->target = NULL;
     if (fullscreen)
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index f747e236f31..5830426f756 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -2453,7 +2453,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
         ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
         hr = IDXGIOutput_GetDesc(output2, &output_desc2);
         ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
-        todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+        todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
                 "Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
                 wine_dbgstr_w(output_desc.DeviceName));
         IDXGIOutput_Release(output);
@@ -2465,7 +2465,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
         ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
         hr = IDXGIOutput_GetDesc(output2, &output_desc2);
         ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
-        todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+        todo_wine_if(is_d3d12) ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
                 "Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
                 wine_dbgstr_w(output_desc.DeviceName));
 
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 2cf36d189cb..a36946cc620 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -2171,6 +2171,7 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st
 {
     struct wined3d_display_mode actual_mode;
     struct wined3d_output_desc output_desc;
+    BOOL windowed = state->desc.windowed;
     HRESULT hr;
 
     TRACE("state %p, swapchain_desc %p, mode %p.\n", state, swapchain_desc, mode);
@@ -2259,6 +2260,9 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st
     state->desc.output = swapchain_desc->output;
     state->desc.windowed = swapchain_desc->windowed;
 
+    if (state->parent_ops && windowed != state->desc.windowed)
+        state->parent_ops->windowed_state_changed(state->parent, state->desc.windowed);
+
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 816108e8b3b..4c42b0854e1 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -292,7 +292,7 @@
 @ cdecl wined3d_swapchain_state_create(ptr ptr ptr)
 @ cdecl wined3d_swapchain_state_destroy(ptr)
 @ cdecl wined3d_swapchain_state_is_windowed(ptr)
-@ cdecl wined3d_swapchain_state_register(ptr ptr)
+@ cdecl wined3d_swapchain_state_register(ptr ptr ptr ptr)
 @ cdecl wined3d_swapchain_state_resize_target(ptr ptr)
 @ cdecl wined3d_swapchain_state_set_fullscreen(ptr ptr ptr)
 @ cdecl wined3d_swapchain_state_unregister(ptr)
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index bb3ad7ffa51..09d741ac87f 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -775,7 +775,8 @@ static struct wined3d_window_hook *wined3d_find_hook(DWORD thread_id)
 }
 
 void CDECL wined3d_swapchain_state_register(struct wined3d_swapchain_state *state,
-        struct wined3d *wined3d)
+        struct wined3d *wined3d, void *parent,
+        const struct wined3d_swapchain_state_parent_ops *parent_ops)
 {
     struct wined3d_registered_swapchain_state *state_entry;
     struct wined3d_window_hook *hook;
@@ -789,6 +790,9 @@ void CDECL wined3d_swapchain_state_register(struct wined3d_swapchain_state *stat
         return;
     }
 
+    state->parent = parent;
+    state->parent_ops = parent_ops;
+
     state_entry = &swapchain_state_table.states[swapchain_state_table.state_count++];
     state_entry->state = state;
     state_entry->wined3d = wined3d;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7c88e04f5e7..0d14f1e2860 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -5062,6 +5062,9 @@ struct wined3d_swapchain_state
     LONG style;
     LONG exstyle;
     HWND device_window;
+
+    void *parent;
+    const struct wined3d_swapchain_state_parent_ops *parent_ops;
 };
 
 void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state,
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 3f2361e55a5..9d2d37c4856 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2208,6 +2208,11 @@ struct wined3d_parent_ops
     void (__stdcall *wined3d_object_destroyed)(void *parent);
 };
 
+struct wined3d_swapchain_state_parent_ops
+{
+    void (__stdcall *windowed_state_changed)(void *parent, BOOL windowed);
+};
+
 struct wined3d;
 struct wined3d_adapter;
 struct wined3d_blend_state;
@@ -2807,7 +2812,8 @@ HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_de
 void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state);
 BOOL __cdecl wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_state *state);
 void __cdecl wined3d_swapchain_state_register(struct wined3d_swapchain_state *state,
-        struct wined3d *wined3d);
+        struct wined3d *wined3d, void *context,
+        const struct wined3d_swapchain_state_parent_ops *parent_ops);
 HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state,
         const struct wined3d_display_mode *mode);
 HRESULT __cdecl wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_state *state,
-- 
2.25.1




More information about the wine-devel mailing list