static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface) { struct d3d9_vertexbuffer *buffer = impl_from_IDirect3DVertexBuffer9(iface); ULONG refcount = InterlockedDecrement(&buffer->resource.refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { struct wined3d_buffer *draw_buffer = buffer->draw_buffer; IDirect3DDevice9Ex *device = buffer->parent_device; wined3d_mutex_lock(); if (draw_buffer) wined3d_buffer_decref(draw_buffer); else wined3d_buffer_decref(buffer->wined3d_buffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(device); } return refcount; }
static ULONG WINAPI IDirect3DSurface9Impl_Release(IDirect3DSurface9 *iface) { IDirect3DSurface9Impl *This = impl_from_IDirect3DSurface9(iface); TRACE("iface %p.\n", iface); if (This->forwardReference) { /* Forward to the containerParent */ TRACE("(%p) : Forwarding to %p\n", This, This->forwardReference); return IUnknown_Release(This->forwardReference); } else { /* No container, handle our own refcounting */ ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; wined3d_mutex_lock(); wined3d_surface_decref(This->wined3d_surface); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parentDevice) IDirect3DDevice9Ex_Release(parentDevice); } return ref; } }
static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface) { struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface); ULONG refcount; TRACE("iface %p.\n", iface); if (surface->forwardReference) { TRACE("Forwarding to %p.\n", surface->forwardReference); return IUnknown_Release(surface->forwardReference); } refcount = InterlockedDecrement(&surface->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { IDirect3DDevice9Ex *parent_device = surface->parent_device; wined3d_mutex_lock(); wined3d_surface_decref(surface->wined3d_surface); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parent_device) IDirect3DDevice9Ex_Release(parent_device); } return refcount; }
static ULONG WINAPI d3d9_swapchain_Release(IDirect3DSwapChain9Ex *iface) { struct d3d9_swapchain *swapchain = impl_from_IDirect3DSwapChain9Ex(iface); 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) { IDirect3DDevice9Ex *parent_device = swapchain->parent_device; wined3d_mutex_lock(); wined3d_swapchain_decref(swapchain->wined3d_swapchain); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parent_device) IDirect3DDevice9Ex_Release(parent_device); } return refcount; }
static void uninit(struct ra_hwdec *hw) { struct priv_owner *p = hw->priv; hwdec_devices_remove(hw->devs, &p->hwctx); av_buffer_unref(&p->hwctx.av_device_ref); if (p->device) IDirect3DDevice9Ex_Release(p->device); }
static void test_qi_base_to_ex(void) { IDirect3D9 *d3d9 = pDirect3DCreate9(D3D_SDK_VERSION); IDirect3D9Ex *d3d9ex = (void *) 0xdeadbeef; IDirect3DDevice9 *device; IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef; HRESULT hr; HWND window = create_window(); D3DPRESENT_PARAMETERS present_parameters; if (!d3d9) { skip("Direct3D9 is not available\n"); return; } hr = IDirect3D9_QueryInterface(d3d9, &IID_IDirect3D9Ex, (void **) &d3d9ex); ok(hr == E_NOINTERFACE, "IDirect3D9::QueryInterface for IID_IDirect3D9Ex returned %08x, expected E_NOINTERFACE\n", hr); ok(d3d9ex == NULL, "QueryInterface returned interface %p, expected NULL\n", d3d9ex); if(d3d9ex) IDirect3D9Ex_Release(d3d9ex); memset(&present_parameters, 0, sizeof(present_parameters)); present_parameters.Windowed = TRUE; present_parameters.hDeviceWindow = window; present_parameters.SwapEffect = D3DSWAPEFFECT_COPY; present_parameters.BackBufferWidth = 640; present_parameters.BackBufferHeight = 480; present_parameters.EnableAutoDepthStencil = FALSE; present_parameters.AutoDepthStencilFormat = D3DFMT_D16; hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device); if(FAILED(hr)) { skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n"); goto out; } hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx); ok(hr == E_NOINTERFACE, "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected E_NOINTERFACE\n", hr); ok(deviceEx == NULL, "QueryInterface returned interface %p, expected NULL\n", deviceEx); if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx); IDirect3DDevice9_Release(device); out: IDirect3D9_Release(d3d9); DestroyWindow(window); }
static ULONG WINAPI IDirect3DVertexShader9Impl_Release(LPDIRECT3DVERTEXSHADER9 iface) { IDirect3DVertexShader9Impl *This = (IDirect3DVertexShader9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { EnterCriticalSection(&d3d9_cs); IWineD3DVertexShader_Release(This->wineD3DVertexShader); LeaveCriticalSection(&d3d9_cs); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static ULONG WINAPI IDirect3DTexture9Impl_Release(LPDIRECT3DTEXTURE9 iface) { IDirect3DTexture9Impl *This = (IDirect3DTexture9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("(%p) : ReleaseRef to %d\n", This, ref); if (ref == 0) { EnterCriticalSection(&d3d9_cs); IWineD3DTexture_Destroy(This->wineD3DTexture, D3D9CB_DestroySurface); LeaveCriticalSection(&d3d9_cs); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static ULONG WINAPI IDirect3DStateBlock9Impl_Release(LPDIRECT3DSTATEBLOCK9 iface) { IDirect3DStateBlock9Impl *This = (IDirect3DStateBlock9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { wined3d_mutex_lock(); wined3d_stateblock_decref(This->wined3d_stateblock); wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static ULONG WINAPI IDirect3DQuery9Impl_Release(IDirect3DQuery9 *iface) { IDirect3DQuery9Impl *This = impl_from_IDirect3DQuery9(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { wined3d_mutex_lock(); wined3d_query_decref(This->wineD3DQuery); wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(This->parentDevice); HeapFree(GetProcessHeap(), 0, This); } return ref; }
static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface) { IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; wined3d_mutex_lock(); wined3d_swapchain_decref(This->wined3d_swapchain); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parentDevice) IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static ULONG WINAPI d3d9_query_Release(IDirect3DQuery9 *iface) { struct d3d9_query *query = impl_from_IDirect3DQuery9(iface); ULONG refcount = InterlockedDecrement(&query->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { wined3d_mutex_lock(); wined3d_query_decref(query->wined3d_query); wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(query->parent_device); HeapFree(GetProcessHeap(), 0, query); } return refcount; }
static ULONG WINAPI IDirect3DIndexBuffer9Impl_Release(LPDIRECT3DINDEXBUFFER9 iface) { IDirect3DIndexBuffer9Impl *This = (IDirect3DIndexBuffer9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; wined3d_mutex_lock(); IWineD3DBuffer_Release(This->wineD3DIndexBuffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static ULONG WINAPI d3d9_stateblock_Release(IDirect3DStateBlock9 *iface) { struct d3d9_stateblock *stateblock = impl_from_IDirect3DStateBlock9(iface); ULONG refcount = InterlockedDecrement(&stateblock->refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { wined3d_mutex_lock(); wined3d_stateblock_decref(stateblock->wined3d_stateblock); wined3d_mutex_unlock(); IDirect3DDevice9Ex_Release(stateblock->parent_device); HeapFree(GetProcessHeap(), 0, stateblock); } return refcount; }
static ULONG WINAPI IDirect3DVolumeTexture9Impl_Release(IDirect3DVolumeTexture9 *iface) { IDirect3DVolumeTexture9Impl *This = impl_from_IDirect3DVolumeTexture9(iface); ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; wined3d_mutex_lock(); wined3d_texture_decref(This->wined3d_texture); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static ULONG WINAPI IDirect3DCubeTexture9Impl_Release(LPDIRECT3DCUBETEXTURE9 iface) { IDirect3DCubeTexture9Impl *This = (IDirect3DCubeTexture9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; TRACE("Releasing child %p\n", This->wineD3DCubeTexture); wined3d_mutex_lock(); IWineD3DCubeTexture_Release(This->wineD3DCubeTexture); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static ULONG WINAPI d3d9_texture_3d_Release(IDirect3DVolumeTexture9 *iface) { struct d3d9_texture *texture = impl_from_IDirect3DVolumeTexture9(iface); ULONG ref = InterlockedDecrement(&texture->refcount); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (!ref) { IDirect3DDevice9Ex *parent_device = texture->parent_device; wined3d_mutex_lock(); wined3d_texture_decref(texture->wined3d_texture); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(parent_device); } return ref; }
static ULONG WINAPI d3d9_vertexshader_Release(IDirect3DVertexShader9 *iface) { IDirect3DVertexShader9Impl *shader = impl_from_IDirect3DVertexShader9(iface); ULONG refcount = InterlockedDecrement(&shader->ref); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { IDirect3DDevice9Ex *device = shader->parentDevice; wined3d_mutex_lock(); wined3d_shader_decref(shader->wined3d_shader); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(device); } return refcount; }
static ULONG WINAPI d3d9_vertexbuffer_Release(IDirect3DVertexBuffer9 *iface) { IDirect3DVertexBuffer9Impl *buffer = (IDirect3DVertexBuffer9Impl *)iface; ULONG refcount = InterlockedDecrement(&buffer->ref); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { IDirect3DDevice9Ex *device = buffer->parentDevice; wined3d_mutex_lock(); IWineD3DBuffer_Release(buffer->wineD3DVertexBuffer); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ IDirect3DDevice9Ex_Release(device); } return refcount; }
static ULONG WINAPI d3d9_surface_Release(IDirect3DSurface9 *iface) { struct d3d9_surface *surface = impl_from_IDirect3DSurface9(iface); ULONG refcount; TRACE("iface %p.\n", iface); if (surface->texture) { TRACE("Forwarding to %p.\n", surface->texture); return IDirect3DBaseTexture9_Release(&surface->texture->IDirect3DBaseTexture9_iface); } if (!surface->resource.refcount) { ERR("Surface doesn't have any references.\n"); return 0; } refcount = InterlockedDecrement(&surface->resource.refcount); TRACE("%p decreasing refcount to %u.\n", iface, refcount); if (!refcount) { IDirect3DDevice9Ex *parent_device = surface->parent_device; wined3d_mutex_lock(); if (surface->wined3d_rtv) wined3d_rendertarget_view_decref(surface->wined3d_rtv); wined3d_surface_decref(surface->wined3d_surface); wined3d_mutex_unlock(); /* Release the device last, as it may cause the device to be destroyed. */ if (parent_device) IDirect3DDevice9Ex_Release(parent_device); } return refcount; }
static ULONG WINAPI IDirect3DSwapChain9Impl_Release(LPDIRECT3DSWAPCHAIN9 iface) { IDirect3DSwapChain9Impl *This = (IDirect3DSwapChain9Impl *)iface; ULONG ref = InterlockedDecrement(&This->ref); TRACE("%p decreasing refcount to %u.\n", iface, ref); if (ref == 0) { IDirect3DDevice9Ex *parentDevice = This->parentDevice; if (!This->isImplicit) { wined3d_mutex_lock(); IWineD3DSwapChain_Destroy(This->wineD3DSwapChain); wined3d_mutex_unlock(); HeapFree(GetProcessHeap(), 0, This); } /* Release the device last, as it may cause the device to be destroyed. */ if (parentDevice) IDirect3DDevice9Ex_Release(parentDevice); } return ref; }
static void test_qi_ex_to_base(void) { IDirect3D9 *d3d9 = (void *) 0xdeadbeef; IDirect3D9Ex *d3d9ex; IDirect3DDevice9 *device; IDirect3DDevice9Ex *deviceEx = (void *) 0xdeadbeef; HRESULT hr; HWND window = create_window(); D3DPRESENT_PARAMETERS present_parameters; ULONG ref; hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex); ok(hr == D3D_OK || hr == D3DERR_NOTAVAILABLE, "Direct3DCreate9Ex returned %08x\n", hr); if(FAILED(hr)) { skip("Direct3D9Ex is not available\n"); goto out; } hr = IDirect3D9Ex_QueryInterface(d3d9ex, &IID_IDirect3D9, (void **) &d3d9); ok(hr == D3D_OK, "IDirect3D9Ex::QueryInterface for IID_IDirect3D9 returned %08x, expected D3D_OK\n", hr); ok(d3d9 != NULL && d3d9 != (void *) 0xdeadbeef, "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", d3d9); ref = getref((IUnknown *) d3d9ex); ok(ref == 2, "IDirect3D9Ex refcount is %d, expected 2\n", ref); ref = getref((IUnknown *) d3d9); ok(ref == 2, "IDirect3D9 refcount is %d, expected 2\n", ref); memset(&present_parameters, 0, sizeof(present_parameters)); present_parameters.Windowed = TRUE; present_parameters.hDeviceWindow = window; present_parameters.SwapEffect = D3DSWAPEFFECT_COPY; present_parameters.BackBufferWidth = 640; present_parameters.BackBufferHeight = 480; present_parameters.EnableAutoDepthStencil = FALSE; present_parameters.AutoDepthStencilFormat = D3DFMT_D16; /* First, try to create a normal device with IDirect3D9Ex::CreateDevice and QI it for IDirect3DDevice9Ex */ hr = IDirect3D9Ex_CreateDevice(d3d9ex, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device); if(FAILED(hr)) { skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n"); goto out; } hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx); ok(hr == D3D_OK, "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n", hr); ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef, "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx); ref = getref((IUnknown *) device); ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref); ref = getref((IUnknown *) deviceEx); ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref); if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx); IDirect3DDevice9_Release(device); /* Next, try to create a normal device with IDirect3D9::CreateDevice(non-ex) and QI it */ hr = IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, present_parameters.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present_parameters, &device); if(FAILED(hr)) { skip("Failed to create a regular Direct3DDevice9, skipping QI tests\n"); goto out; } hr = IDirect3DDevice9_QueryInterface(device, &IID_IDirect3DDevice9Ex, (void **) &deviceEx); ok(hr == D3D_OK, "IDirect3D9Device::QueryInterface for IID_IDirect3DDevice9Ex returned %08x, expected D3D_OK\n", hr); ok(deviceEx != NULL && deviceEx != (void *) 0xdeadbeef, "QueryInterface returned interface %p, expected != NULL && != 0xdeadbeef\n", deviceEx); ref = getref((IUnknown *) device); ok(ref == 2, "IDirect3DDevice9 refcount is %d, expected 2\n", ref); ref = getref((IUnknown *) deviceEx); ok(ref == 2, "IDirect3DDevice9Ex refcount is %d, expected 2\n", ref); if(deviceEx) IDirect3DDevice9Ex_Release(deviceEx); IDirect3DDevice9_Release(device); IDirect3D9_Release(d3d9); IDirect3D9Ex_Release(d3d9ex); out: DestroyWindow(window); }