[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