[PATCH v2 1/7] dxgi: Do not store IDXGIOutputs in IDXGIAdapter.
Józef Kucia
jkucia at codeweavers.com
Thu Apr 14 05:20:21 CDT 2016
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
Version 2: Do not set *output to NULL in dxgi_output_create().
---
dlls/dxgi/adapter.c | 28 +++++++++++-----------------
dlls/dxgi/dxgi_private.h | 5 ++---
dlls/dxgi/factory.c | 15 +--------------
dlls/dxgi/output.c | 27 +++++++++++++++++++--------
dlls/dxgi/tests/device.c | 18 +++++++++---------
5 files changed, 42 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..7c45cdd 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,20 @@ 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))))
+ 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