wined3d: Don't free D3D swapchains until the wined3d swapchain is destroyed.
This will allow us the get rid of the swapchain refcounting hacks in d3d9 in particular. This is similar to the way we handle resources that are still in use by a stateblock, but aren't referenced anywhere by the application.
This commit is contained in:
parent
d19c3588bc
commit
dd2c7d0d8c
|
@ -54,6 +54,15 @@ static ULONG WINAPI IDirect3DSwapChain8Impl_AddRef(IDirect3DSwapChain8 *iface)
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u.\n", iface, ref);
|
TRACE("%p increasing refcount to %u.\n", iface, ref);
|
||||||
|
|
||||||
|
if (ref == 1)
|
||||||
|
{
|
||||||
|
if (This->parentDevice)
|
||||||
|
IDirect3DDevice8_AddRef(This->parentDevice);
|
||||||
|
wined3d_mutex_lock();
|
||||||
|
IWineD3DSwapChain_AddRef(This->wineD3DSwapChain);
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +73,16 @@ static ULONG WINAPI IDirect3DSwapChain8Impl_Release(IDirect3DSwapChain8 *iface)
|
||||||
|
|
||||||
TRACE("%p decreasing refcount to %u.\n", iface, ref);
|
TRACE("%p decreasing refcount to %u.\n", iface, ref);
|
||||||
|
|
||||||
if (ref == 0) {
|
if (!ref)
|
||||||
|
{
|
||||||
|
IDirect3DDevice8 *parentDevice = This->parentDevice;
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
|
IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
if (This->parentDevice) IUnknown_Release(This->parentDevice);
|
if (parentDevice)
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
IDirect3DDevice8_Release(parentDevice);
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
@ -125,6 +137,16 @@ static const IDirect3DSwapChain8Vtbl Direct3DSwapChain8_Vtbl =
|
||||||
IDirect3DSwapChain8Impl_GetBackBuffer
|
IDirect3DSwapChain8Impl_GetBackBuffer
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void STDMETHODCALLTYPE d3d8_swapchain_wined3d_object_released(void *parent)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
|
||||||
|
{
|
||||||
|
d3d8_swapchain_wined3d_object_released,
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT swapchain_init(IDirect3DSwapChain8Impl *swapchain, IDirect3DDevice8Impl *device,
|
HRESULT swapchain_init(IDirect3DSwapChain8Impl *swapchain, IDirect3DDevice8Impl *device,
|
||||||
D3DPRESENT_PARAMETERS *present_parameters)
|
D3DPRESENT_PARAMETERS *present_parameters)
|
||||||
{
|
{
|
||||||
|
@ -152,7 +174,8 @@ HRESULT swapchain_init(IDirect3DSwapChain8Impl *swapchain, IDirect3DDevice8Impl
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = IWineD3DDevice_CreateSwapChain(device->WineD3DDevice, &wined3d_parameters,
|
hr = IWineD3DDevice_CreateSwapChain(device->WineD3DDevice, &wined3d_parameters,
|
||||||
SURFACE_OPENGL, swapchain, &swapchain->wineD3DSwapChain);
|
SURFACE_OPENGL, swapchain, &d3d8_swapchain_wined3d_parent_ops,
|
||||||
|
&swapchain->wineD3DSwapChain);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
present_parameters->BackBufferWidth = wined3d_parameters.BackBufferWidth;
|
present_parameters->BackBufferWidth = wined3d_parameters.BackBufferWidth;
|
||||||
|
|
|
@ -50,7 +50,18 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_AddRef(LPDIRECT3DSWAPCHAIN9 iface) {
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u.\n", iface, ref);
|
TRACE("%p increasing refcount to %u.\n", iface, ref);
|
||||||
|
|
||||||
if(ref == 1 && This->parentDevice) IDirect3DDevice9Ex_AddRef(This->parentDevice);
|
if (ref == 1)
|
||||||
|
{
|
||||||
|
if (This->parentDevice)
|
||||||
|
IDirect3DDevice9Ex_AddRef(This->parentDevice);
|
||||||
|
|
||||||
|
if (!This->isImplicit)
|
||||||
|
{
|
||||||
|
wined3d_mutex_lock();
|
||||||
|
IWineD3DSwapChain_AddRef(This->wineD3DSwapChain);
|
||||||
|
wined3d_mutex_unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +79,6 @@ static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface)
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
|
IWineD3DSwapChain_Destroy(This->wineD3DSwapChain);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the device last, as it may cause the device to be destroyed. */
|
/* Release the device last, as it may cause the device to be destroyed. */
|
||||||
|
@ -217,6 +226,16 @@ static const IDirect3DSwapChain9Vtbl Direct3DSwapChain9_Vtbl =
|
||||||
IDirect3DSwapChain9Impl_GetPresentParameters
|
IDirect3DSwapChain9Impl_GetPresentParameters
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void STDMETHODCALLTYPE d3d9_swapchain_wined3d_object_released(void *parent)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
|
||||||
|
{
|
||||||
|
d3d9_swapchain_wined3d_object_released,
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT swapchain_init(IDirect3DSwapChain9Impl *swapchain, IDirect3DDevice9Impl *device,
|
HRESULT swapchain_init(IDirect3DSwapChain9Impl *swapchain, IDirect3DDevice9Impl *device,
|
||||||
D3DPRESENT_PARAMETERS *present_parameters)
|
D3DPRESENT_PARAMETERS *present_parameters)
|
||||||
{
|
{
|
||||||
|
@ -244,7 +263,8 @@ HRESULT swapchain_init(IDirect3DSwapChain9Impl *swapchain, IDirect3DDevice9Impl
|
||||||
|
|
||||||
wined3d_mutex_lock();
|
wined3d_mutex_lock();
|
||||||
hr = IWineD3DDevice_CreateSwapChain(device->WineD3DDevice, &wined3d_parameters,
|
hr = IWineD3DDevice_CreateSwapChain(device->WineD3DDevice, &wined3d_parameters,
|
||||||
SURFACE_OPENGL, swapchain, &swapchain->wineD3DSwapChain);
|
SURFACE_OPENGL, swapchain, &d3d9_swapchain_wined3d_parent_ops,
|
||||||
|
&swapchain->wineD3DSwapChain);
|
||||||
wined3d_mutex_unlock();
|
wined3d_mutex_unlock();
|
||||||
|
|
||||||
present_parameters->BackBufferWidth = wined3d_parameters.BackBufferWidth;
|
present_parameters->BackBufferWidth = wined3d_parameters.BackBufferWidth;
|
||||||
|
|
|
@ -5905,7 +5905,7 @@ static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDevicePar
|
||||||
TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
|
TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
|
||||||
|
|
||||||
hr = IWineD3DDevice_CreateSwapChain(This->wineD3DDevice, present_parameters,
|
hr = IWineD3DDevice_CreateSwapChain(This->wineD3DDevice, present_parameters,
|
||||||
This->ImplType, NULL, swapchain);
|
This->ImplType, NULL, &ddraw_null_wined3d_parent_ops, swapchain);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
FIXME("(%p) CreateSwapChain failed, returning %#x\n", iface, hr);
|
FIXME("(%p) CreateSwapChain failed, returning %#x\n", iface, hr);
|
||||||
|
|
|
@ -53,6 +53,9 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_AddRef(IDXGISwapChain *iface)
|
||||||
|
|
||||||
TRACE("%p increasing refcount to %u\n", This, refcount);
|
TRACE("%p increasing refcount to %u\n", This, refcount);
|
||||||
|
|
||||||
|
if (refcount == 1)
|
||||||
|
IWineD3DSwapChain_AddRef(This->wined3d_swapchain);
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +94,6 @@ static ULONG STDMETHODCALLTYPE dxgi_swapchain_Release(IDXGISwapChain *iface)
|
||||||
ERR("Uninit3D failed, hr %#x\n", hr);
|
ERR("Uninit3D failed, hr %#x\n", hr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return refcount;
|
return refcount;
|
||||||
|
@ -269,6 +270,16 @@ static const struct IDXGISwapChainVtbl dxgi_swapchain_vtbl =
|
||||||
dxgi_swapchain_GetLastPresentCount,
|
dxgi_swapchain_GetLastPresentCount,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void STDMETHODCALLTYPE dxgi_swapchain_wined3d_object_released(void *parent)
|
||||||
|
{
|
||||||
|
HeapFree(GetProcessHeap(), 0, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wined3d_parent_ops dxgi_swapchain_wined3d_parent_ops =
|
||||||
|
{
|
||||||
|
dxgi_swapchain_wined3d_object_released,
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
|
HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device *device,
|
||||||
WINED3DPRESENT_PARAMETERS *present_parameters)
|
WINED3DPRESENT_PARAMETERS *present_parameters)
|
||||||
{
|
{
|
||||||
|
@ -278,7 +289,8 @@ HRESULT dxgi_swapchain_init(struct dxgi_swapchain *swapchain, struct dxgi_device
|
||||||
swapchain->refcount = 1;
|
swapchain->refcount = 1;
|
||||||
|
|
||||||
hr = IWineD3DDevice_CreateSwapChain(device->wined3d_device, present_parameters,
|
hr = IWineD3DDevice_CreateSwapChain(device->wined3d_device, present_parameters,
|
||||||
SURFACE_OPENGL, swapchain, &swapchain->wined3d_swapchain);
|
SURFACE_OPENGL, swapchain, &dxgi_swapchain_wined3d_parent_ops,
|
||||||
|
&swapchain->wined3d_swapchain);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
|
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
|
||||||
|
|
|
@ -1278,7 +1278,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateQuery(IWineD3DDevice *iface,
|
||||||
/* Do not call while under the GL lock. */
|
/* Do not call while under the GL lock. */
|
||||||
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
|
static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
|
||||||
WINED3DPRESENT_PARAMETERS *present_parameters, WINED3DSURFTYPE surface_type,
|
WINED3DPRESENT_PARAMETERS *present_parameters, WINED3DSURFTYPE surface_type,
|
||||||
void *parent, IWineD3DSwapChain **swapchain)
|
void *parent, const struct wined3d_parent_ops *parent_ops, IWineD3DSwapChain **swapchain)
|
||||||
{
|
{
|
||||||
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
|
||||||
IWineD3DSwapChainImpl *object;
|
IWineD3DSwapChainImpl *object;
|
||||||
|
@ -1294,7 +1294,7 @@ static HRESULT WINAPI IWineD3DDeviceImpl_CreateSwapChain(IWineD3DDevice *iface,
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = swapchain_init(object, surface_type, This, present_parameters, parent);
|
hr = swapchain_init(object, surface_type, This, present_parameters, parent, parent_ops);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
|
WARN("Failed to initialize swapchain, hr %#x.\n", hr);
|
||||||
|
|
|
@ -80,6 +80,7 @@ static void WINAPI IWineD3DBaseSwapChainImpl_Destroy(IWineD3DSwapChain *iface)
|
||||||
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)swapchain->device, 0, &mode);
|
IWineD3DDevice_SetDisplayMode((IWineD3DDevice *)swapchain->device, 0, &mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swapchain->parent_ops->wined3d_object_destroyed(swapchain->parent);
|
||||||
HeapFree(GetProcessHeap(), 0, swapchain->context);
|
HeapFree(GetProcessHeap(), 0, swapchain->context);
|
||||||
HeapFree(GetProcessHeap(), 0, swapchain);
|
HeapFree(GetProcessHeap(), 0, swapchain);
|
||||||
}
|
}
|
||||||
|
@ -860,7 +861,8 @@ static const IWineD3DSwapChainVtbl IWineGDISwapChain_Vtbl =
|
||||||
|
|
||||||
/* Do not call while under the GL lock. */
|
/* Do not call while under the GL lock. */
|
||||||
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
|
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
|
||||||
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, void *parent)
|
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters,
|
||||||
|
void *parent, const struct wined3d_parent_ops *parent_ops)
|
||||||
{
|
{
|
||||||
const struct wined3d_adapter *adapter = device->adapter;
|
const struct wined3d_adapter *adapter = device->adapter;
|
||||||
const struct wined3d_format *format;
|
const struct wined3d_format *format;
|
||||||
|
@ -903,6 +905,7 @@ HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface
|
||||||
|
|
||||||
swapchain->device = device;
|
swapchain->device = device;
|
||||||
swapchain->parent = parent;
|
swapchain->parent = parent;
|
||||||
|
swapchain->parent_ops = parent_ops;
|
||||||
swapchain->ref = 1;
|
swapchain->ref = 1;
|
||||||
swapchain->win_handle = window;
|
swapchain->win_handle = window;
|
||||||
swapchain->device_window = window;
|
swapchain->device_window = window;
|
||||||
|
|
|
@ -2530,6 +2530,7 @@ struct IWineD3DSwapChainImpl
|
||||||
LONG ref; /* Note: Ref counting not required */
|
LONG ref; /* Note: Ref counting not required */
|
||||||
|
|
||||||
void *parent;
|
void *parent;
|
||||||
|
const struct wined3d_parent_ops *parent_ops;
|
||||||
IWineD3DDeviceImpl *device;
|
IWineD3DDeviceImpl *device;
|
||||||
|
|
||||||
/* IWineD3DSwapChain fields */
|
/* IWineD3DSwapChain fields */
|
||||||
|
@ -2556,7 +2557,8 @@ void x11_copy_to_screen(IWineD3DSwapChainImpl *This, const RECT *rc) DECLSPEC_HI
|
||||||
|
|
||||||
struct wined3d_context *swapchain_get_context(struct IWineD3DSwapChainImpl *swapchain) DECLSPEC_HIDDEN;
|
struct wined3d_context *swapchain_get_context(struct IWineD3DSwapChainImpl *swapchain) DECLSPEC_HIDDEN;
|
||||||
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
|
HRESULT swapchain_init(IWineD3DSwapChainImpl *swapchain, WINED3DSURFTYPE surface_type,
|
||||||
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters, void *parent) DECLSPEC_HIDDEN;
|
IWineD3DDeviceImpl *device, WINED3DPRESENT_PARAMETERS *present_parameters,
|
||||||
|
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
#define DEFAULT_REFRESH_RATE 0
|
#define DEFAULT_REFRESH_RATE 0
|
||||||
|
|
||||||
|
|
|
@ -2481,6 +2481,7 @@ interface IWineD3DDevice : IUnknown
|
||||||
[in] WINED3DPRESENT_PARAMETERS *present_parameters,
|
[in] WINED3DPRESENT_PARAMETERS *present_parameters,
|
||||||
[in] WINED3DSURFTYPE surface_type,
|
[in] WINED3DSURFTYPE surface_type,
|
||||||
[in] void *parent,
|
[in] void *parent,
|
||||||
|
[in] const struct wined3d_parent_ops *parent_ops,
|
||||||
[out] IWineD3DSwapChain **swapchain
|
[out] IWineD3DSwapChain **swapchain
|
||||||
);
|
);
|
||||||
HRESULT CreateVertexDeclaration(
|
HRESULT CreateVertexDeclaration(
|
||||||
|
|
Loading…
Reference in New Issue