From: Józef Kucia Subject: [PATCH 09/11] dxgi: Do not store IDXGIAdapters in IDXGIFactory. Message-Id: <1460456986-5082-9-git-send-email-jkucia@codeweavers.com> Date: Tue, 12 Apr 2016 12:29:44 +0200 In-Reply-To: <1460456986-5082-1-git-send-email-jkucia@codeweavers.com> References: <1460456986-5082-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- 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