[PATCH 07/11] dxgi: Do not store IDXGIOutputs in IDXGIAdapter.

Józef Kucia jkucia at codeweavers.com
Tue Apr 12 05:29:42 CDT 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/dxgi/adapter.c      | 28 +++++++++++-----------------
 dlls/dxgi/dxgi_private.h |  5 ++---
 dlls/dxgi/factory.c      | 15 +--------------
 dlls/dxgi/output.c       | 30 ++++++++++++++++++++++--------
 dlls/dxgi/tests/device.c | 18 +++++++++---------
 5 files changed, 45 insertions(+), 51 deletions(-)

diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index 387156c..529d4f4 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -68,7 +68,6 @@ static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IDXGIAdapter1 *iface)
 
     if (!refcount)
     {
-        IDXGIOutput_Release(adapter->output);
         wined3d_private_store_cleanup(&adapter->private_store);
         HeapFree(GetProcessHeap(), 0, adapter);
     }
@@ -119,6 +118,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IDXGIAdapter1 *iface,
         UINT output_idx, IDXGIOutput **output)
 {
     struct dxgi_adapter *adapter = impl_from_IDXGIAdapter1(iface);
+    struct dxgi_output *output_object;
+    HRESULT hr;
 
     TRACE("iface %p, output_idx %u, output %p.\n", iface, output_idx, output);
 
@@ -128,10 +129,15 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IDXGIAdapter1 *iface,
         return DXGI_ERROR_NOT_FOUND;
     }
 
-    *output = adapter->output;
-    IDXGIOutput_AddRef(*output);
+    if (FAILED(hr = dxgi_output_create(adapter, &output_object)))
+    {
+        *output = NULL;
+        return hr;
+    }
+
+    *output = &output_object->IDXGIOutput_iface;
 
-    TRACE("Returning output %p.\n", output);
+    TRACE("Returning output %p.\n", *output);
 
     return S_OK;
 }
@@ -259,23 +265,11 @@ struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface)
     return CONTAINING_RECORD(iface, struct dxgi_adapter, IDXGIAdapter1_iface);
 }
 
-HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal)
+void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal)
 {
-    struct dxgi_output *output;
-
     adapter->IDXGIAdapter1_iface.lpVtbl = &dxgi_adapter_vtbl;
     adapter->parent = parent;
     adapter->refcount = 1;
     wined3d_private_store_init(&adapter->private_store);
     adapter->ordinal = ordinal;
-
-    if (!(output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*output))))
-    {
-        wined3d_private_store_cleanup(&adapter->private_store);
-        return E_OUTOFMEMORY;
-    }
-    dxgi_output_init(output, adapter);
-    adapter->output = &output->IDXGIOutput_iface;
-
-    return S_OK;
 }
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index fb49b21..a4ed850 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -134,7 +134,7 @@ struct dxgi_output
     struct dxgi_adapter *adapter;
 };
 
-void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter) DECLSPEC_HIDDEN;
+HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output) DECLSPEC_HIDDEN;
 
 /* IDXGIAdapter */
 struct dxgi_adapter
@@ -144,10 +144,9 @@ struct dxgi_adapter
     LONG refcount;
     struct wined3d_private_store private_store;
     UINT ordinal;
-    IDXGIOutput *output;
 };
 
-HRESULT dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal) DECLSPEC_HIDDEN;
+void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal) DECLSPEC_HIDDEN;
 struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface) DECLSPEC_HIDDEN;
 
 /* IDXGISwapChain */
diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c
index 8e16311..8dd6ead 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -347,20 +347,7 @@ static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended)
             goto fail;
         }
 
-        if (FAILED(hr = dxgi_adapter_init(adapter, factory, i)))
-        {
-            UINT j;
-
-            ERR("Failed to initialize adapter, hr %#x.\n", hr);
-
-            HeapFree(GetProcessHeap(), 0, adapter);
-            for (j = 0; j < i; ++j)
-            {
-                IDXGIAdapter1_Release(factory->adapters[j]);
-            }
-            goto fail;
-        }
-
+        dxgi_adapter_init(adapter, factory, i);
         factory->adapters[i] = &adapter->IDXGIAdapter1_iface;
     }
 
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index 65e60aa..a668b50 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -61,15 +61,16 @@ static ULONG STDMETHODCALLTYPE dxgi_output_AddRef(IDXGIOutput *iface)
 
 static ULONG STDMETHODCALLTYPE dxgi_output_Release(IDXGIOutput *iface)
 {
-    struct dxgi_output *This = impl_from_IDXGIOutput(iface);
-    ULONG refcount = InterlockedDecrement(&This->refcount);
+    struct dxgi_output *output = impl_from_IDXGIOutput(iface);
+    ULONG refcount = InterlockedDecrement(&output->refcount);
 
-    TRACE("%p decreasing refcount to %u.\n", This, refcount);
+    TRACE("%p decreasing refcount to %u.\n", output, refcount);
 
     if (!refcount)
     {
-        wined3d_private_store_cleanup(&This->private_store);
-        HeapFree(GetProcessHeap(), 0, This);
+        wined3d_private_store_cleanup(&output->private_store);
+        IDXGIAdapter1_Release(&output->adapter->IDXGIAdapter1_iface);
+        HeapFree(GetProcessHeap(), 0, output);
     }
 
     return refcount;
@@ -110,11 +111,11 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetPrivateData(IDXGIOutput *iface,
 static HRESULT STDMETHODCALLTYPE dxgi_output_GetParent(IDXGIOutput *iface,
         REFIID riid, void **parent)
 {
-    struct dxgi_output *This = impl_from_IDXGIOutput(iface);
+    struct dxgi_output *output = impl_from_IDXGIOutput(iface);
 
     TRACE("iface %p, riid %s, parent %p.\n", iface, debugstr_guid(riid), parent);
 
-    return IDXGIAdapter_QueryInterface((IDXGIAdapter *)This->adapter, riid, parent);
+    return IDXGIAdapter1_QueryInterface(&output->adapter->IDXGIAdapter1_iface, riid, parent);
 }
 
 /* IDXGIOutput methods */
@@ -316,10 +317,23 @@ static const struct IDXGIOutputVtbl dxgi_output_vtbl =
     dxgi_output_GetFrameStatistics,
 };
 
-void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter)
+static void dxgi_output_init(struct dxgi_output *output, struct dxgi_adapter *adapter)
 {
     output->IDXGIOutput_iface.lpVtbl = &dxgi_output_vtbl;
     output->refcount = 1;
     wined3d_private_store_init(&output->private_store);
     output->adapter = adapter;
+    IDXGIAdapter1_AddRef(&output->adapter->IDXGIAdapter1_iface);
+}
+
+HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **output)
+{
+    if (!(*output = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(**output))))
+    {
+        *output = NULL;
+        return E_OUTOFMEMORY;
+    }
+
+    dxgi_output_init(*output, adapter);
+    return S_OK;
 }
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index d8b1dd6..9cb66d7 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -619,7 +619,7 @@ static void test_get_containing_output(void)
     ok(SUCCEEDED(hr), "EnumOutputs failed, hr %#x.\n", hr);
 
     refcount = get_refcount((IUnknown *)output);
-    todo_wine ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+    ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
 
     hr = IDXGIFactory_CreateSwapChain(factory, (IUnknown *)device, &swapchain_desc, &swapchain);
     ok(SUCCEEDED(hr), "CreateSwapChain failed, hr %#x.\n", hr);
@@ -635,9 +635,9 @@ static void test_get_containing_output(void)
     }
 
     refcount = get_refcount((IUnknown *)output);
-    todo_wine ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+    ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
     refcount = get_refcount((IUnknown *)output2);
-    todo_wine ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
+    ok(refcount == 1, "Got unexpected refcount %u.\n", refcount);
 
     hr = IDXGIOutput_GetDesc(output, &output_desc);
     ok(SUCCEEDED(hr), "GetDesc failed, hr %#x.\n", hr);
@@ -656,13 +656,13 @@ static void test_get_containing_output(void)
             output_desc2.DesktopCoordinates.right, output_desc2.DesktopCoordinates.bottom);
 
     refcount = IDXGIOutput_Release(output2);
-    todo_wine ok(!refcount, "IDXGIOuput has %u references left.\n", refcount);
+    ok(!refcount, "IDXGIOuput has %u references left.\n", refcount);
 
     refcount = IDXGISwapChain_Release(swapchain);
     ok(!refcount, "IDXGISwapChain has %u references left.\n", refcount);
 
     refcount = IDXGIOutput_Release(output);
-    todo_wine ok(!refcount, "IDXGIOuput has %u references left.\n", refcount);
+    ok(!refcount, "IDXGIOuput has %u references left.\n", refcount);
 
 done:
     refcount = IDXGIDevice_Release(device);
@@ -1470,17 +1470,17 @@ static void test_output_desc(void)
 
             hr = IDXGIAdapter_EnumOutputs(adapter, j, &output2);
             ok(SUCCEEDED(hr), "Failed to enumerate output %u on adapter %u, hr %#x.\n", j, i, hr);
-            todo_wine ok(output != output2, "Expected to get new instance of IDXGIOuput, %p == %p.\n", output, output2);
+            ok(output != output2, "Expected to get new instance of IDXGIOuput, %p == %p.\n", output, output2);
             refcount = get_refcount((IUnknown *)output);
-            todo_wine ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
+            ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
             IDXGIOutput_Release(output2);
 
             refcount = get_refcount((IUnknown *)factory);
             todo_wine ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
             refcount = get_refcount((IUnknown *)adapter);
-            ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
+            todo_wine ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
             refcount = get_refcount((IUnknown *)output);
-            todo_wine ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
+            ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
 
             hr = IDXGIOutput_GetDesc(output, NULL);
             ok(hr == E_INVALIDARG, "Got unexpected hr %#x for output %u on adapter %u.\n", hr, j, i);
-- 
2.4.10




More information about the wine-patches mailing list