Module: wine Branch: master Commit: 1860208f5fe5ddf3b30cf77667aa3b6d1985538a URL: http://source.winehq.org/git/wine.git/?a=commit;h=1860208f5fe5ddf3b30cf77667...
Author: Józef Kucia jkucia@codeweavers.com Date: Mon Feb 13 13:07:35 2017 +0100
d3d9: Do not decrease swapchain refcount when it is already 0.
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
---
dlls/d3d9/swapchain.c | 9 ++++++++- dlls/d3d9/tests/device.c | 40 ++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 19 deletions(-)
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c index 91ceaf0..8f3803a 100644 --- a/dlls/d3d9/swapchain.c +++ b/dlls/d3d9/swapchain.c @@ -90,8 +90,15 @@ static ULONG WINAPI d3d9_swapchain_AddRef(IDirect3DSwapChain9Ex *iface) static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); - ULONG refcount = InterlockedDecrement(&swapchain->refcount); + ULONG refcount;
+ if (!swapchain->refcount) + { + WARN("Swapchain does not have any references.\n"); + return 0; + } + + refcount = InterlockedDecrement(&swapchain->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount);
if (!refcount) diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c index 27f3a1d..5aba575 100644 --- a/dlls/d3d9/tests/device.c +++ b/dlls/d3d9/tests/device.c @@ -1437,15 +1437,15 @@ static void test_refcount(void) CHECK_CALL(hr, "GetSwapChain", device, ++refcount); if (pSwapChain) { - CHECK_REFCOUNT( pSwapChain, 1); + CHECK_REFCOUNT(pSwapChain, 1);
hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget); CHECK_CALL(hr, "GetRenderTarget", device, ++refcount); - CHECK_REFCOUNT( pSwapChain, 1); - if(pRenderTarget) + CHECK_REFCOUNT(pSwapChain, 1); + if (pRenderTarget) { - CHECK_SURFACE_CONTAINER( pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain); - CHECK_REFCOUNT( pRenderTarget, 1); + CHECK_SURFACE_CONTAINER(pRenderTarget, IID_IDirect3DSwapChain9, pSwapChain); + CHECK_REFCOUNT(pRenderTarget, 1);
CHECK_ADDREF_REFCOUNT(pRenderTarget, 2); CHECK_REFCOUNT(device, refcount); @@ -1454,9 +1454,9 @@ static void test_refcount(void)
hr = IDirect3DDevice9_GetRenderTarget(device, 0, &pRenderTarget); CHECK_CALL(hr, "GetRenderTarget", device, refcount); - CHECK_REFCOUNT( pRenderTarget, 2); - CHECK_RELEASE_REFCOUNT( pRenderTarget, 1); - CHECK_RELEASE_REFCOUNT( pRenderTarget, 0); + CHECK_REFCOUNT(pRenderTarget, 2); + CHECK_RELEASE_REFCOUNT(pRenderTarget, 1); + CHECK_RELEASE_REFCOUNT(pRenderTarget, 0); CHECK_REFCOUNT(device, --refcount);
/* The render target is released with the device, so AddRef with refcount=0 is fine here. */ @@ -1484,7 +1484,7 @@ static void test_refcount(void)
hr = IDirect3DDevice9_GetDepthStencilSurface(device, &pStencilSurface); CHECK_CALL(hr, "GetDepthStencilSurface", device, ++refcount); - CHECK_REFCOUNT( pSwapChain, 1); + CHECK_REFCOUNT(pSwapChain, 1); if (pStencilSurface) { CHECK_SURFACE_CONTAINER(pStencilSurface, IID_IDirect3DDevice9, device); @@ -1508,14 +1508,18 @@ static void test_refcount(void) pStencilSurface = NULL; }
- CHECK_RELEASE_REFCOUNT( pSwapChain, 0); + CHECK_RELEASE_REFCOUNT(pSwapChain, 0); CHECK_REFCOUNT(device, --refcount); + CHECK_RELEASE_REFCOUNT(pSwapChain, 0); + CHECK_RELEASE_REFCOUNT(pSwapChain, 0);
/* The implicit swapchwin is released with the device, so AddRef with refcount=0 is fine here. */ CHECK_ADDREF_REFCOUNT(pSwapChain, 1); CHECK_REFCOUNT(device, ++refcount); CHECK_RELEASE_REFCOUNT(pSwapChain, 0); CHECK_REFCOUNT(device, --refcount); + CHECK_RELEASE_REFCOUNT(pSwapChain, 0); + CHECK_RELEASE_REFCOUNT(pSwapChain, 0); pSwapChain = NULL; }
@@ -1524,7 +1528,7 @@ static void test_refcount(void) CHECK_CALL(hr, "CreateIndexBuffer", device, ++refcount ); if(pIndexBuffer) { - tmp = get_refcount( (IUnknown *)pIndexBuffer ); + tmp = get_refcount((IUnknown *)pIndexBuffer);
hr = IDirect3DDevice9_SetIndices(device, pIndexBuffer); CHECK_CALL( hr, "SetIndices", pIndexBuffer, tmp); @@ -1641,17 +1645,17 @@ static void test_refcount(void) d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; hr = IDirect3DDevice9_CreateAdditionalSwapChain(device, &d3dpp, &pSwapChain); CHECK_CALL(hr, "CreateAdditionalSwapChain", device, ++refcount); - if(pSwapChain) + if (pSwapChain) { /* check implicit back buffer */ hr = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, 0, 0, &pBackBuffer); CHECK_CALL(hr, "GetBackBuffer", device, ++refcount); - CHECK_REFCOUNT( pSwapChain, 1); - if(pBackBuffer) + CHECK_REFCOUNT(pSwapChain, 1); + if (pBackBuffer) { - CHECK_SURFACE_CONTAINER( pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain); - CHECK_REFCOUNT( pBackBuffer, 1); - CHECK_RELEASE_REFCOUNT( pBackBuffer, 0); + CHECK_SURFACE_CONTAINER(pBackBuffer, IID_IDirect3DSwapChain9, pSwapChain); + CHECK_REFCOUNT(pBackBuffer, 1); + CHECK_RELEASE_REFCOUNT(pBackBuffer, 0); CHECK_REFCOUNT(device, --refcount);
/* The back buffer is released with the swapchain, so AddRef with refcount=0 is fine here. */ @@ -1663,7 +1667,7 @@ static void test_refcount(void) CHECK_RELEASE_REFCOUNT(pBackBuffer, 0); pBackBuffer = NULL; } - CHECK_REFCOUNT( pSwapChain, 1); + CHECK_REFCOUNT(pSwapChain, 1); } hr = IDirect3DDevice9_CreateQuery(device, D3DQUERYTYPE_EVENT, &pQuery); CHECK_CALL(hr, "CreateQuery", device, ++refcount);