From: Józef Kucia Subject: [PATCH 07/11] dxgi: Do not store IDXGIOutputs in IDXGIAdapter. Message-Id: <1460456986-5082-7-git-send-email-jkucia@codeweavers.com> Date: Tue, 12 Apr 2016 12:29:42 +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 | 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