dxgi: Do not store IDXGIOutputs in IDXGIAdapter.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2016-04-14 12:20:21 +02:00 committed by Alexandre Julliard
parent ef34222131
commit b835a35881
5 changed files with 42 additions and 51 deletions

View File

@ -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;
}
TRACE("Returning output %p.\n", output);
*output = &output_object->IDXGIOutput_iface;
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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);