[PATCH 09/11] dxgi: Do not store IDXGIAdapters in IDXGIFactory.

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


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/dxgi/adapter.c      | 28 +++++++++++++++-----
 dlls/dxgi/dxgi_private.h |  7 +++--
 dlls/dxgi/factory.c      | 66 ++++++++++--------------------------------------
 dlls/dxgi/output.c       |  4 +--
 dlls/dxgi/tests/device.c | 22 ++++++++--------
 5 files changed, 50 insertions(+), 77 deletions(-)

diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c
index 529d4f4..f9b8591 100644
--- a/dlls/dxgi/adapter.c
+++ b/dlls/dxgi/adapter.c
@@ -69,6 +69,7 @@ static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IDXGIAdapter1 *iface)
     if (!refcount)
     {
         wined3d_private_store_cleanup(&adapter->private_store);
+        IDXGIFactory1_Release(&adapter->factory->IDXGIFactory1_iface);
         HeapFree(GetProcessHeap(), 0, adapter);
     }
 
@@ -109,9 +110,9 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IDXGIAdapter1 *iface, RE
 {
     struct dxgi_adapter *adapter = impl_from_IDXGIAdapter1(iface);
 
-    TRACE("iface %p, iid %s, parent %p\n", iface, debugstr_guid(iid), parent);
+    TRACE("iface %p, iid %s, parent %p.\n", iface, debugstr_guid(iid), parent);
 
-    return IDXGIFactory1_QueryInterface(&adapter->parent->IDXGIFactory1_iface, iid, parent);
+    return IDXGIFactory1_QueryInterface(&adapter->factory->IDXGIFactory1_iface, iid, parent);
 }
 
 static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IDXGIAdapter1 *iface,
@@ -160,7 +161,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc1(IDXGIAdapter1 *iface, DXG
     adapter_id.device_name_size = 0;
 
     wined3d_mutex_lock();
-    hr = wined3d_get_adapter_identifier(adapter->parent->wined3d, adapter->ordinal, 0, &adapter_id);
+    hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id);
     wined3d_mutex_unlock();
 
     if (FAILED(hr))
@@ -221,7 +222,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
         return DXGI_ERROR_UNSUPPORTED;
     }
 
-    if (!dxgi_check_feature_level_support(adapter->parent, adapter, &feature_level, 1))
+    if (!dxgi_check_feature_level_support(adapter->factory, adapter, &feature_level, 1))
         return DXGI_ERROR_UNSUPPORTED;
 
     if (umd_version)
@@ -231,7 +232,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter
         adapter_id.device_name_size = 0;
 
         wined3d_mutex_lock();
-        hr = wined3d_get_adapter_identifier(adapter->parent->wined3d, adapter->ordinal, 0, &adapter_id);
+        hr = wined3d_get_adapter_identifier(adapter->factory->wined3d, adapter->ordinal, 0, &adapter_id);
         wined3d_mutex_unlock();
         if (FAILED(hr))
             return hr;
@@ -265,11 +266,24 @@ struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface)
     return CONTAINING_RECORD(iface, struct dxgi_adapter, IDXGIAdapter1_iface);
 }
 
-void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal)
+static void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *factory, UINT ordinal)
 {
     adapter->IDXGIAdapter1_iface.lpVtbl = &dxgi_adapter_vtbl;
-    adapter->parent = parent;
     adapter->refcount = 1;
     wined3d_private_store_init(&adapter->private_store);
     adapter->ordinal = ordinal;
+    adapter->factory = factory;
+    IDXGIFactory1_AddRef(&adapter->factory->IDXGIFactory1_iface);
+}
+
+HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal, struct dxgi_adapter **adapter)
+{
+    if (!(*adapter = HeapAlloc(GetProcessHeap(), 0, sizeof(**adapter))))
+    {
+        *adapter = NULL;
+        return E_OUTOFMEMORY;
+    }
+
+    dxgi_adapter_init(*adapter, factory, ordinal);
+    return S_OK;
 }
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index 7c81900..5a4d43e 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -100,8 +100,6 @@ struct dxgi_factory
     LONG refcount;
     struct wined3d_private_store private_store;
     struct wined3d *wined3d;
-    UINT adapter_count;
-    IDXGIAdapter1 **adapters;
     BOOL extended;
     HWND device_window;
 };
@@ -141,13 +139,14 @@ HRESULT dxgi_output_create(struct dxgi_adapter *adapter, struct dxgi_output **ou
 struct dxgi_adapter
 {
     IDXGIAdapter1 IDXGIAdapter1_iface;
-    struct dxgi_factory *parent;
     LONG refcount;
     struct wined3d_private_store private_store;
     UINT ordinal;
+    struct dxgi_factory *factory;
 };
 
-void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *parent, UINT ordinal) DECLSPEC_HIDDEN;
+HRESULT dxgi_adapter_create(struct dxgi_factory *factory, UINT ordinal,
+        struct dxgi_adapter **adapter) 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 8dd6ead..2cc372f 100644
--- a/dlls/dxgi/factory.c
+++ b/dlls/dxgi/factory.c
@@ -70,15 +70,8 @@ static ULONG STDMETHODCALLTYPE dxgi_factory_Release(IDXGIFactory1 *iface)
 
     if (!refcount)
     {
-        UINT i;
-
         if (factory->device_window)
             DestroyWindow(factory->device_window);
-        for (i = 0; i < factory->adapter_count; ++i)
-        {
-            IDXGIAdapter1_Release(factory->adapters[i]);
-        }
-        HeapFree(GetProcessHeap(), 0, factory->adapters);
 
         wined3d_mutex_lock();
         wined3d_decref(factory->wined3d);
@@ -133,20 +126,29 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_EnumAdapters1(IDXGIFactory1 *iface
         UINT adapter_idx, IDXGIAdapter1 **adapter)
 {
     struct dxgi_factory *factory = impl_from_IDXGIFactory1(iface);
+    struct dxgi_adapter *adapter_object;
+    UINT adapter_count;
+    HRESULT hr;
 
     TRACE("iface %p, adapter_idx %u, adapter %p.\n", iface, adapter_idx, adapter);
 
     if (!adapter)
         return DXGI_ERROR_INVALID_CALL;
 
-    if (adapter_idx >= factory->adapter_count)
+    wined3d_mutex_lock();
+    adapter_count = wined3d_get_adapter_count(factory->wined3d);
+    wined3d_mutex_unlock();
+
+    if (adapter_idx >= adapter_count)
     {
         *adapter = NULL;
         return DXGI_ERROR_NOT_FOUND;
     }
 
-    *adapter = (IDXGIAdapter1 *)factory->adapters[adapter_idx];
-    IDXGIAdapter1_AddRef(*adapter);
+    if (FAILED(hr = dxgi_adapter_create(factory, adapter_idx, &adapter_object)))
+        return hr;
+
+    *adapter = &adapter_object->IDXGIAdapter1_iface;
 
     TRACE("Returning adapter %p.\n", *adapter);
 
@@ -304,64 +306,22 @@ struct dxgi_factory *unsafe_impl_from_IDXGIFactory1(IDXGIFactory1 *iface)
 
 static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended)
 {
-    HRESULT hr;
-    UINT i;
-
     factory->IDXGIFactory1_iface.lpVtbl = &dxgi_factory_vtbl;
     factory->refcount = 1;
     wined3d_private_store_init(&factory->private_store);
 
     wined3d_mutex_lock();
     factory->wined3d = wined3d_create(0);
+    wined3d_mutex_unlock();
     if (!factory->wined3d)
     {
-        wined3d_mutex_unlock();
         wined3d_private_store_cleanup(&factory->private_store);
         return DXGI_ERROR_UNSUPPORTED;
     }
 
-    factory->adapter_count = wined3d_get_adapter_count(factory->wined3d);
-    wined3d_mutex_unlock();
-    factory->adapters = HeapAlloc(GetProcessHeap(), 0, factory->adapter_count * sizeof(*factory->adapters));
-    if (!factory->adapters)
-    {
-        ERR("Failed to allocate DXGI adapter array memory.\n");
-        hr = E_OUTOFMEMORY;
-        goto fail;
-    }
-
-    for (i = 0; i < factory->adapter_count; ++i)
-    {
-        struct dxgi_adapter *adapter = HeapAlloc(GetProcessHeap(), 0, sizeof(*adapter));
-        if (!adapter)
-        {
-            UINT j;
-
-            ERR("Failed to allocate DXGI adapter memory.\n");
-
-            for (j = 0; j < i; ++j)
-            {
-                IDXGIAdapter1_Release(factory->adapters[j]);
-            }
-            hr = E_OUTOFMEMORY;
-            goto fail;
-        }
-
-        dxgi_adapter_init(adapter, factory, i);
-        factory->adapters[i] = &adapter->IDXGIAdapter1_iface;
-    }
-
     factory->extended = extended;
 
     return S_OK;
-
-fail:
-    HeapFree(GetProcessHeap(), 0, factory->adapters);
-    wined3d_mutex_lock();
-    wined3d_decref(factory->wined3d);
-    wined3d_mutex_unlock();
-    wined3d_private_store_cleanup(&factory->private_store);
-    return hr;
 }
 
 HRESULT dxgi_factory_create(REFIID riid, void **factory, BOOL extended)
diff --git a/dlls/dxgi/output.c b/dlls/dxgi/output.c
index a668b50..50aadd4 100644
--- a/dlls/dxgi/output.c
+++ b/dlls/dxgi/output.c
@@ -132,7 +132,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDesc(IDXGIOutput *iface, DXGI_OU
         return E_INVALIDARG;
 
     wined3d_mutex_lock();
-    hr = wined3d_get_output_desc(output->adapter->parent->wined3d,
+    hr = wined3d_get_output_desc(output->adapter->factory->wined3d,
             output->adapter->ordinal, &wined3d_desc);
     wined3d_mutex_unlock();
 
@@ -172,7 +172,7 @@ static HRESULT STDMETHODCALLTYPE dxgi_output_GetDisplayModeList(IDXGIOutput *ifa
         return S_OK;
     }
 
-    wined3d = This->adapter->parent->wined3d;
+    wined3d = This->adapter->factory->wined3d;
     wined3d_format = wined3dformat_from_dxgi_format(format);
 
     wined3d_mutex_lock();
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c
index 9cb66d7..1baea71 100644
--- a/dlls/dxgi/tests/device.c
+++ b/dlls/dxgi/tests/device.c
@@ -467,7 +467,7 @@ static void test_create_swapchain(void)
 
     expected_refcount = get_refcount((IUnknown *)adapter);
     refcount = get_refcount((IUnknown *)factory);
-    ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+    todo_wine ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
     refcount = get_refcount((IUnknown *)device);
     ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
@@ -499,7 +499,7 @@ static void test_create_swapchain(void)
     IDXGISwapChain_Release(swapchain);
 
     refcount = get_refcount((IUnknown *)factory);
-    ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
+    todo_wine ok(refcount == 2, "Got unexpected refcount %u.\n", refcount);
 
     for (i = 0; i < sizeof(refresh_list)/sizeof(refresh_list[0]); i++)
     {
@@ -554,7 +554,7 @@ static void test_create_swapchain(void)
     refcount = IDXGIDevice_Release(device);
     ok(!refcount, "Device has %u references left.\n", refcount);
     refcount = IDXGIAdapter_Release(adapter);
-    todo_wine ok(!refcount, "Adapter has %u references left.\n", refcount);
+    ok(!refcount, "Adapter has %u references left.\n", refcount);
     refcount = IDXGIFactory_Release(factory);
     ok(!refcount, "Factory has %u references left.\n", refcount);
     DestroyWindow(creation_desc.OutputWindow);
@@ -668,7 +668,7 @@ done:
     refcount = IDXGIDevice_Release(device);
     ok(!refcount, "Device has %u references left.\n", refcount);
     refcount = IDXGIAdapter_Release(adapter);
-    todo_wine ok(!refcount, "Adapter has %u references left.\n", refcount);
+    ok(!refcount, "Adapter has %u references left.\n", refcount);
     refcount = IDXGIFactory_Release(factory);
     ok(!refcount, "Factory has %u references left.\n", refcount);
     DestroyWindow(swapchain_desc.OutputWindow);
@@ -1448,15 +1448,15 @@ static void test_output_desc(void)
 
         hr = IDXGIFactory_EnumAdapters(factory, i, &adapter2);
         ok(SUCCEEDED(hr), "Failed to enumerate adapter %u, hr %#x.\n", i, hr);
-        todo_wine ok(adapter != adapter2, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter, adapter2);
+        ok(adapter != adapter2, "Expected to get new instance of IDXGIAdapter, %p == %p.\n", adapter, adapter2);
         refcount = get_refcount((IUnknown *)adapter);
-        todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
+        ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
         IDXGIAdapter_Release(adapter2);
 
         refcount = get_refcount((IUnknown *)factory);
-        todo_wine ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
+        ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
         refcount = get_refcount((IUnknown *)adapter);
-        todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
+        ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
 
         for (j = 0; ; ++j)
         {
@@ -1476,9 +1476,9 @@ static void test_output_desc(void)
             IDXGIOutput_Release(output2);
 
             refcount = get_refcount((IUnknown *)factory);
-            todo_wine ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
+            ok(refcount == 2, "Get unexpected refcount %u.\n", refcount);
             refcount = get_refcount((IUnknown *)adapter);
-            todo_wine ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
+            ok(refcount == 2, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
             refcount = get_refcount((IUnknown *)output);
             ok(refcount == 1, "Get unexpected refcount %u for output %u, adapter %u.\n", refcount, j, i);
 
@@ -1501,7 +1501,7 @@ static void test_output_desc(void)
 
             IDXGIOutput_Release(output);
             refcount = get_refcount((IUnknown *)adapter);
-            todo_wine ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
+            ok(refcount == 1, "Get unexpected refcount %u for adapter %u.\n", refcount, i);
         }
 
         IDXGIAdapter_Release(adapter);
-- 
2.4.10




More information about the wine-patches mailing list